Repository: kiegroup/appformer Branch: main Commit: cb4b2efc1d6c Files: 7926 Total size: 34.7 MB Directory structure: gitextract_zcersj5y/ ├── .gitignore ├── LICENSE ├── README.md ├── appformer-client-api/ │ ├── README.md │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── appformer/ │ │ │ └── client/ │ │ │ ├── context/ │ │ │ │ ├── Channel.java │ │ │ │ ├── DefaultEditorContextProviderImpl.java │ │ │ │ ├── EditorContextProvider.java │ │ │ │ └── OperatingSystem.java │ │ │ ├── keyboardShortcuts/ │ │ │ │ └── KeyboardShortcutsApiOpts.java │ │ │ └── stateControl/ │ │ │ └── registry/ │ │ │ ├── DefaultRegistry.java │ │ │ ├── Registry.java │ │ │ ├── RegistryChangeListener.java │ │ │ └── impl/ │ │ │ └── DefaultRegistryImpl.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── ErraiApp.properties │ │ └── org/ │ │ └── appformer/ │ │ └── AppformerClientAPI.gwt.xml │ └── test/ │ └── java/ │ └── org/ │ └── appformer/ │ └── client/ │ └── stateControl/ │ └── registry/ │ └── impl/ │ └── DefaultRegistryImplTest.java ├── appformer-js/ │ ├── .gitignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── pom.xml │ ├── prettier.config.js │ ├── src/ │ │ ├── appformer/ │ │ │ ├── AppFormer.tsx │ │ │ ├── CompassLayoutPerspective.tsx │ │ │ ├── Component.ts │ │ │ ├── ComponentTypes.ts │ │ │ ├── Components.ts │ │ │ ├── DisplayInfo.ts │ │ │ ├── Panel.ts │ │ │ ├── Part.ts │ │ │ ├── Perspective.ts │ │ │ ├── Screen.ts │ │ │ └── index.ts │ │ ├── core/ │ │ │ ├── Component.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── java-wrappers/ │ │ │ ├── BigNumberWrapper.ts │ │ │ ├── FloatBasedJavaNumber.ts │ │ │ ├── IntegerBasedJavaNumber.ts │ │ │ ├── JavaArrayList.ts │ │ │ ├── JavaBigDecimal.ts │ │ │ ├── JavaBigInteger.ts │ │ │ ├── JavaBoolean.ts │ │ │ ├── JavaByte.ts │ │ │ ├── JavaCollection.ts │ │ │ ├── JavaDate.ts │ │ │ ├── JavaDouble.ts │ │ │ ├── JavaEnum.ts │ │ │ ├── JavaFloat.ts │ │ │ ├── JavaHashMap.ts │ │ │ ├── JavaHashSet.ts │ │ │ ├── JavaInteger.ts │ │ │ ├── JavaLinkedList.ts │ │ │ ├── JavaLong.ts │ │ │ ├── JavaNumber.ts │ │ │ ├── JavaOptional.ts │ │ │ ├── JavaShort.ts │ │ │ ├── JavaString.ts │ │ │ ├── JavaTreeMap.ts │ │ │ ├── JavaTreeSet.ts │ │ │ ├── JavaType.ts │ │ │ ├── JavaWrapper.ts │ │ │ ├── JavaWrapperUtils.ts │ │ │ ├── NumberWrapper.ts │ │ │ ├── __tests__/ │ │ │ │ ├── JavaArrayList.test.ts │ │ │ │ ├── JavaBigDecimal.test.ts │ │ │ │ ├── JavaBigInteger.test.ts │ │ │ │ ├── JavaBoolean.test.ts │ │ │ │ ├── JavaByte.test.ts │ │ │ │ ├── JavaDate.test.ts │ │ │ │ ├── JavaDouble.test.ts │ │ │ │ ├── JavaFloat.test.ts │ │ │ │ ├── JavaHashMap.test.ts │ │ │ │ ├── JavaHashSet.test.ts │ │ │ │ ├── JavaInteger.test.ts │ │ │ │ ├── JavaLong.test.ts │ │ │ │ ├── JavaOptional.test.ts │ │ │ │ ├── JavaShort.test.ts │ │ │ │ ├── JavaString.test.ts │ │ │ │ ├── JavaWrapper.test.ts │ │ │ │ └── JavaWrapperUtils.test.ts │ │ │ └── index.ts │ │ ├── marshalling/ │ │ │ ├── Marshaller.ts │ │ │ ├── MarshallerProvider.ts │ │ │ ├── Marshalling.ts │ │ │ ├── MarshallingContext.ts │ │ │ ├── Portable.ts │ │ │ ├── UnmarshallingContext.ts │ │ │ ├── __tests__/ │ │ │ │ ├── MarshallerProvider.test.ts │ │ │ │ ├── Marshalling.test.ts │ │ │ │ ├── MarshallingContext.test.ts │ │ │ │ └── UnmarshallingContext.test.ts │ │ │ ├── index.ts │ │ │ ├── marshallers/ │ │ │ │ ├── DefaultMarshaller.ts │ │ │ │ ├── JavaBigDecimalMarshaller.ts │ │ │ │ ├── JavaBigIntegerMarshaller.ts │ │ │ │ ├── JavaBooleanMarshaller.ts │ │ │ │ ├── JavaByteMarshaller.ts │ │ │ │ ├── JavaCollectionMarshaller.ts │ │ │ │ ├── JavaDateMarshaller.ts │ │ │ │ ├── JavaDoubleMarshaller.ts │ │ │ │ ├── JavaEnumMarshaller.ts │ │ │ │ ├── JavaFloatMarshaller.ts │ │ │ │ ├── JavaHashMapMarshaller.ts │ │ │ │ ├── JavaIntegerMarshaller.ts │ │ │ │ ├── JavaLongMarshaller.ts │ │ │ │ ├── JavaOptionalMarshaller.ts │ │ │ │ ├── JavaShortMarshaller.ts │ │ │ │ ├── JavaStringMarshaller.ts │ │ │ │ ├── NullableMarshaller.ts │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── DefaultMarshaller.test.ts │ │ │ │ │ ├── JavaBigDecimalMarshaller.test.ts │ │ │ │ │ ├── JavaBigIntegerMarshaller.test.ts │ │ │ │ │ ├── JavaBooleanMarshaller.test.ts │ │ │ │ │ ├── JavaByteMarshaller.test.ts │ │ │ │ │ ├── JavaCollectionSubTypesMarshaller.test.ts │ │ │ │ │ ├── JavaDateMarshaller.test.ts │ │ │ │ │ ├── JavaDoubleMarshaller.test.ts │ │ │ │ │ ├── JavaEnumMarshaller.test.ts │ │ │ │ │ ├── JavaFloatMarshaller.test.ts │ │ │ │ │ ├── JavaHashMapMarshaller.test.ts │ │ │ │ │ ├── JavaIntegerMarshaller.test.ts │ │ │ │ │ ├── JavaLongMarshaller.test.ts │ │ │ │ │ ├── JavaOptionalMarshaller.test.ts │ │ │ │ │ ├── JavaShortMarshaller.test.ts │ │ │ │ │ └── JavaStringMarshaller.test.ts │ │ │ │ └── util/ │ │ │ │ ├── GenericsTypeMarshallingUtils.ts │ │ │ │ └── __tests__/ │ │ │ │ └── GenericsTypeMarshallingUtils.test.ts │ │ │ └── model/ │ │ │ ├── EnumStringValueBasedErraiObject.ts │ │ │ ├── ErraiObject.ts │ │ │ ├── ErraiObjectConstants.ts │ │ │ ├── NumValBasedErraiObject.ts │ │ │ ├── ValueBasedErraiObject.ts │ │ │ └── __tests__/ │ │ │ ├── EnumStringValueBasedErraiObject.test.ts │ │ │ ├── NumValBasedErraiObject.test.ts │ │ │ └── ValueBasedErraiObject.test.ts │ │ └── util/ │ │ ├── DomUtils.ts │ │ ├── NumberUtils.ts │ │ ├── TypeUtils.ts │ │ ├── __tests__/ │ │ │ ├── NumberUtils.test.ts │ │ │ └── TypeUtils.test.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.webpack.json │ ├── tslint.json │ └── webpack.config.js ├── appformer-js-bridge/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── jsbridge/ │ │ │ └── client/ │ │ │ ├── AppFormerJsBridge.java │ │ │ ├── JsPlaceRequest.java │ │ │ ├── cdi/ │ │ │ │ ├── EditorActivityBeanDefinition.java │ │ │ │ └── SingletonBeanDefinition.java │ │ │ ├── editor/ │ │ │ │ ├── JsNativeEditor.java │ │ │ │ └── JsWorkbenchEditorActivity.java │ │ │ ├── loading/ │ │ │ │ ├── ActivityLazyLoaded.java │ │ │ │ ├── AppFormerComponentsRegistry.java │ │ │ │ ├── AppFormerJsActivityLoader.java │ │ │ │ ├── JsWorkbenchLazyPerspectiveActivity.java │ │ │ │ ├── LazyLoadingScreen.java │ │ │ │ └── lazy-loading.html │ │ │ ├── perspective/ │ │ │ │ ├── JsWorkbenchPanelConverter.java │ │ │ │ ├── JsWorkbenchPartConverter.java │ │ │ │ ├── JsWorkbenchPerspectiveActivity.java │ │ │ │ ├── JsWorkbenchTemplatedPerspectiveActivity.java │ │ │ │ └── jsnative/ │ │ │ │ ├── JsNativeContextDisplay.java │ │ │ │ ├── JsNativePanel.java │ │ │ │ ├── JsNativePart.java │ │ │ │ ├── JsNativePerspective.java │ │ │ │ └── JsNativeView.java │ │ │ └── screen/ │ │ │ ├── InvocationPostponer.java │ │ │ ├── JsNativeScreen.java │ │ │ └── JsWorkbenchScreenActivity.java │ │ └── resources/ │ │ └── org/ │ │ └── uberfire/ │ │ └── jsbridge/ │ │ └── AppFormerJsBridge.gwt.xml │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── jsbridge/ │ └── client/ │ ├── loading/ │ │ ├── AppFormerJsActivityLoaderTest.java │ │ ├── AppFormerJsLifecycleIT.java │ │ └── JsWorkbenchLazyPerspectiveActivityTest.java │ └── screen/ │ └── JsWorkbenchScreenActivityTest.java ├── appformer-js-monaco/ │ ├── .gitignore │ ├── package.json │ ├── pom.xml │ ├── prettier.config.js │ ├── src/ │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.webpack.json │ ├── tslint.json │ └── webpack.config.js ├── dashbuilder/ │ ├── README.md │ ├── dashbuilder-backend/ │ │ ├── dashbuilder-dataset-cdi/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ ├── Bootstrap.java │ │ │ │ │ ├── config/ │ │ │ │ │ │ ├── Config.java │ │ │ │ │ │ └── ConfigReader.java │ │ │ │ │ ├── dataprovider/ │ │ │ │ │ │ ├── BeanDataSetProviderCDI.java │ │ │ │ │ │ ├── CSVDataSetProviderCDI.java │ │ │ │ │ │ ├── DataSetProviderRegistryCDI.java │ │ │ │ │ │ ├── KafkaDataSetProviderCDI.java │ │ │ │ │ │ ├── PrometheusDataSetProviderCDI.java │ │ │ │ │ │ ├── SQLDataSetProviderCDI.java │ │ │ │ │ │ ├── SQLDataSourceLocatorCDI.java │ │ │ │ │ │ └── StaticDataSetProviderCDI.java │ │ │ │ │ ├── dataset/ │ │ │ │ │ │ ├── DataSetDefDeployerCDI.java │ │ │ │ │ │ ├── DataSetDefRegistryCDI.java │ │ │ │ │ │ └── DataSetManagerCDI.java │ │ │ │ │ ├── exception/ │ │ │ │ │ │ ├── ExceptionManager.java │ │ │ │ │ │ └── GenericPortableException.java │ │ │ │ │ └── scheduler/ │ │ │ │ │ └── SchedulerCDI.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ ├── BootstrapTest.java │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── config/ │ │ │ │ │ └── ConfigAnnotationTest.java │ │ │ │ ├── dataset/ │ │ │ │ │ ├── DataSetDefRegistryCDITest.java │ │ │ │ │ ├── DataSetProviderRegistryCDITest.java │ │ │ │ │ ├── DataSetSubsystemCDITest.java │ │ │ │ │ ├── SQLDataSourceLocatorCDITest.java │ │ │ │ │ └── SQLDataSourceLocatorMock.java │ │ │ │ ├── pojo/ │ │ │ │ │ ├── Bean.java │ │ │ │ │ └── BeanExt.java │ │ │ │ └── test/ │ │ │ │ ├── BaseCDITest.java │ │ │ │ ├── MavenProjectHelper.java │ │ │ │ └── ShrinkWrapHelper.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── beans.config │ │ │ ├── beans.xml │ │ │ ├── org.dashbuilder.pojo.Bean.config │ │ │ └── org.dashbuilder.pojo.BeanExt.config │ │ ├── dashbuilder-external-backend/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── external/ │ │ │ │ │ ├── ExternalComponentServlet.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── BackendComponentFunction.java │ │ │ │ │ ├── BackendComponentFunctionServiceImpl.java │ │ │ │ │ ├── ComponentAssetProviderImpl.java │ │ │ │ │ ├── ComponentLoaderImpl.java │ │ │ │ │ ├── ComponentServiceImpl.java │ │ │ │ │ └── function/ │ │ │ │ │ └── BackendDateFunction.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── external/ │ │ │ └── impl/ │ │ │ ├── ComponentAssetProviderImplTest.java │ │ │ ├── ComponentLoaderImplTest.java │ │ │ └── ComponentServiceImplTest.java │ │ ├── dashbuilder-kie-server-backend/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── kieserver/ │ │ │ │ │ └── backend/ │ │ │ │ │ ├── KieServerConnectionInfoProviderImpl.java │ │ │ │ │ ├── KieServerDataSetListener.java │ │ │ │ │ ├── RuntimeKieServerDataSetProvider.java │ │ │ │ │ ├── function/ │ │ │ │ │ │ └── ProcessSVGFunction.java │ │ │ │ │ └── rest/ │ │ │ │ │ ├── BasicAuthFilter.java │ │ │ │ │ ├── KieServerQueryClient.java │ │ │ │ │ ├── QueryDefinition.java │ │ │ │ │ ├── QueryFilterSpec.java │ │ │ │ │ ├── QueryParam.java │ │ │ │ │ └── TokenFilter.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── kieserver/ │ │ │ └── backend/ │ │ │ ├── KieServerConnectionInfoProviderImplTest.java │ │ │ └── RuntimeKieServerDataSetProviderTest.java │ │ ├── dashbuilder-navigation-backend/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── navigation/ │ │ │ │ │ ├── service/ │ │ │ │ │ │ ├── LayoutTemplateAnalyzer.java │ │ │ │ │ │ ├── NavigationServicesImpl.java │ │ │ │ │ │ └── PerspectivePluginServicesImpl.java │ │ │ │ │ └── storage/ │ │ │ │ │ └── NavTreeStorage.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── navigation/ │ │ │ └── service/ │ │ │ └── LayoutTemplateAnalyzerTest.java │ │ ├── dashbuilder-services/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ ├── dataset/ │ │ │ │ │ │ └── service/ │ │ │ │ │ │ ├── DataSetDefServicesImpl.java │ │ │ │ │ │ ├── DataSetDefVfsServicesImpl.java │ │ │ │ │ │ ├── DataSetExportServicesImpl.java │ │ │ │ │ │ ├── DataSetLookupServicesImpl.java │ │ │ │ │ │ └── SQLProviderServicesImpl.java │ │ │ │ │ ├── migration/ │ │ │ │ │ │ └── DashbuilderDataMigration.java │ │ │ │ │ ├── renderer/ │ │ │ │ │ │ └── service/ │ │ │ │ │ │ └── RendererSettingsServiceImpl.java │ │ │ │ │ └── transfer/ │ │ │ │ │ ├── DataTransferServicesImpl.java │ │ │ │ │ ├── ExportModelValidationServiceImpl.java │ │ │ │ │ ├── LayoutComponentHelper.java │ │ │ │ │ └── rest/ │ │ │ │ │ └── DataTransferResource.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── dataset/ │ │ │ │ │ └── service/ │ │ │ │ │ └── DataSetExportServicesTest.java │ │ │ │ ├── migration/ │ │ │ │ │ └── DashbuilderDataMigrationTest.java │ │ │ │ ├── renderer/ │ │ │ │ │ └── service/ │ │ │ │ │ └── RendererSettingsServiceTest.java │ │ │ │ └── transfer/ │ │ │ │ ├── DataTransferServicesTest.java │ │ │ │ ├── ExportModelValidationServiceImplTest.java │ │ │ │ ├── LayoutComponentHelperTest.java │ │ │ │ └── rest/ │ │ │ │ └── DataTransferResourceTest.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ └── pom.xml │ ├── dashbuilder-client/ │ │ ├── dashbuilder-cms-client/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── client/ │ │ │ │ │ └── cms/ │ │ │ │ │ ├── ContentManagerEntryPoint.java │ │ │ │ │ ├── layout/ │ │ │ │ │ │ └── editor/ │ │ │ │ │ │ ├── PerspectiveDragComponent.java │ │ │ │ │ │ ├── PerspectiveDragConfigModal.java │ │ │ │ │ │ ├── PerspectiveDragConfigModalView.css │ │ │ │ │ │ ├── PerspectiveDragConfigModalView.html │ │ │ │ │ │ └── PerspectiveDragConfigModalView.java │ │ │ │ │ ├── perspective/ │ │ │ │ │ │ ├── ContentManagerPerspective.java │ │ │ │ │ │ └── DataTransferPerspective.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ ├── ContentManagerConstants.java │ │ │ │ │ │ └── ContentManagerI18n.java │ │ │ │ │ ├── screen/ │ │ │ │ │ │ ├── explorer/ │ │ │ │ │ │ │ ├── NavigationExplorerScreen.java │ │ │ │ │ │ │ └── PerspectivesExplorerScreen.java │ │ │ │ │ │ ├── home/ │ │ │ │ │ │ │ ├── ContentManagerHomeScreen.java │ │ │ │ │ │ │ ├── ContentManagerHomeView.html │ │ │ │ │ │ │ └── ContentManagerHomeView.java │ │ │ │ │ │ ├── transfer/ │ │ │ │ │ │ │ ├── DataTransferPopUp.java │ │ │ │ │ │ │ ├── DataTransferPopUpView.html │ │ │ │ │ │ │ ├── DataTransferPopUpView.java │ │ │ │ │ │ │ ├── DataTransferScreen.java │ │ │ │ │ │ │ ├── DataTransferView.css │ │ │ │ │ │ │ ├── DataTransferView.html │ │ │ │ │ │ │ ├── DataTransferView.java │ │ │ │ │ │ │ └── export/ │ │ │ │ │ │ │ └── wizard/ │ │ │ │ │ │ │ ├── DataSetsWizardPage.java │ │ │ │ │ │ │ ├── ExportSummaryWizardPage.java │ │ │ │ │ │ │ ├── ExportSummaryWizardPageView.css │ │ │ │ │ │ │ ├── ExportSummaryWizardPageView.html │ │ │ │ │ │ │ ├── ExportSummaryWizardPageView.java │ │ │ │ │ │ │ ├── ExportWizard.java │ │ │ │ │ │ │ ├── PagesWizardPage.java │ │ │ │ │ │ │ └── widget/ │ │ │ │ │ │ │ ├── AssetsTableAbstractPresenter.java │ │ │ │ │ │ │ ├── AssetsTableView.css │ │ │ │ │ │ │ ├── AssetsTableView.html │ │ │ │ │ │ │ ├── AssetsTableView.java │ │ │ │ │ │ │ ├── DataSetsTable.java │ │ │ │ │ │ │ └── PagesTable.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ └── DomFactory.java │ │ │ │ │ └── widget/ │ │ │ │ │ ├── NewPerspectivePopUp.java │ │ │ │ │ ├── NewPerspectivePopUpView.css │ │ │ │ │ ├── NewPerspectivePopUpView.html │ │ │ │ │ ├── NewPerspectivePopUpView.java │ │ │ │ │ ├── PerspectiveWidget.java │ │ │ │ │ ├── PerspectiveWidgetView.html │ │ │ │ │ ├── PerspectiveWidgetView.java │ │ │ │ │ ├── PerspectivesExplorer.java │ │ │ │ │ ├── PerspectivesExplorerView.css │ │ │ │ │ ├── PerspectivesExplorerView.html │ │ │ │ │ └── PerspectivesExplorerView.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── ContentManagerClient.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── cms/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── ContentManagerConstants.properties │ │ │ │ ├── ContentManagerConstants_es.properties │ │ │ │ ├── ContentManagerConstants_fr.properties │ │ │ │ ├── ContentManagerConstants_it.properties │ │ │ │ └── ContentManagerConstants_ja.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── client/ │ │ │ └── cms/ │ │ │ ├── perspective/ │ │ │ │ └── ContentManagerPerspectiveTest.java │ │ │ ├── screen/ │ │ │ │ ├── explorer/ │ │ │ │ │ └── NavigationExplorerScreenTest.java │ │ │ │ └── transfer/ │ │ │ │ ├── DataTransferScreenTest.java │ │ │ │ └── export/ │ │ │ │ └── wizard/ │ │ │ │ ├── ExportSummaryWizardPageTest.java │ │ │ │ └── widget/ │ │ │ │ └── AssetsTableViewTest.java │ │ │ └── widget/ │ │ │ ├── NewPerspectivePopUpTest.java │ │ │ └── PerspectivesExplorerTest.java │ │ ├── dashbuilder-common-client/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── common/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── CollectionUtils.java │ │ │ │ │ ├── JsonSourceViewer.java │ │ │ │ │ ├── SpacerWidget.java │ │ │ │ │ ├── StringTemplateBuilder.java │ │ │ │ │ ├── StringUtils.java │ │ │ │ │ ├── backend/ │ │ │ │ │ │ └── PathUrlFactory.java │ │ │ │ │ ├── editor/ │ │ │ │ │ │ ├── HasConstrainedValue.java │ │ │ │ │ │ ├── HasEditMode.java │ │ │ │ │ │ ├── HasRestrictedValue.java │ │ │ │ │ │ ├── LeafAttributeEditor.java │ │ │ │ │ │ ├── ToggleSwitchEditor.java │ │ │ │ │ │ ├── ToggleSwitchEditorView.java │ │ │ │ │ │ ├── ToggleSwitchEditorView.ui.xml │ │ │ │ │ │ ├── ValueBoxEditor.java │ │ │ │ │ │ ├── ValueBoxEditorView.java │ │ │ │ │ │ ├── ValueBoxEditorView.ui.xml │ │ │ │ │ │ ├── file/ │ │ │ │ │ │ │ ├── FileUploadEditor.java │ │ │ │ │ │ │ ├── FileUploadEditorView.java │ │ │ │ │ │ │ └── FileUploadEditorView.ui.xml │ │ │ │ │ │ ├── list/ │ │ │ │ │ │ │ ├── DropDownEditor.java │ │ │ │ │ │ │ ├── DropDownEditorView.java │ │ │ │ │ │ │ ├── DropDownEditorView.ui.xml │ │ │ │ │ │ │ ├── DropDownImageListEditor.java │ │ │ │ │ │ │ ├── DropDownImageListEditorView.java │ │ │ │ │ │ │ ├── DropDownImageListEditorView.ui.xml │ │ │ │ │ │ │ ├── HorizImageListEditor.java │ │ │ │ │ │ │ ├── HorizImageListEditorView.java │ │ │ │ │ │ │ ├── HorizImageListEditorView.ui.xml │ │ │ │ │ │ │ ├── ImageListEditor.java │ │ │ │ │ │ │ └── ImageListEditorView.java │ │ │ │ │ │ └── map/ │ │ │ │ │ │ ├── MapEditor.java │ │ │ │ │ │ ├── MapEditorView.java │ │ │ │ │ │ └── MapEditorView.ui.xml │ │ │ │ │ ├── error/ │ │ │ │ │ │ └── ClientRuntimeError.java │ │ │ │ │ ├── event/ │ │ │ │ │ │ ├── ContextualEvent.java │ │ │ │ │ │ └── ValueChangeEvent.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ ├── bundles/ │ │ │ │ │ │ │ ├── DashbuilderCommonImages.java │ │ │ │ │ │ │ └── DashbuilderCommonResources.java │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ ├── DashbuilderCommonConstants.java │ │ │ │ │ │ └── DashbuilderCommonMessages.java │ │ │ │ │ └── widgets/ │ │ │ │ │ ├── AlertBox.java │ │ │ │ │ ├── AlertBoxView.html │ │ │ │ │ ├── AlertBoxView.java │ │ │ │ │ ├── AlertPanel.java │ │ │ │ │ ├── AlertPanelView.java │ │ │ │ │ ├── AlertPanelView.ui.xml │ │ │ │ │ ├── CharacterBox.java │ │ │ │ │ ├── CharacterBoxBase.java │ │ │ │ │ ├── FilterLabel.java │ │ │ │ │ ├── FilterLabelSet.java │ │ │ │ │ ├── FilterLabelSetView.html │ │ │ │ │ ├── FilterLabelSetView.java │ │ │ │ │ ├── FilterLabelView.html │ │ │ │ │ └── FilterLabelView.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── CommonClient.gwt.xml │ │ │ │ └── common/ │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── DashbuilderCommonConstants.properties │ │ │ │ ├── DashbuilderCommonConstants_de.properties │ │ │ │ ├── DashbuilderCommonConstants_es.properties │ │ │ │ ├── DashbuilderCommonConstants_fr.properties │ │ │ │ ├── DashbuilderCommonConstants_it.properties │ │ │ │ ├── DashbuilderCommonConstants_ja.properties │ │ │ │ ├── DashbuilderCommonConstants_pt_BR.properties │ │ │ │ ├── DashbuilderCommonConstants_zh_CN.properties │ │ │ │ ├── DashbuilderCommonMessages.properties │ │ │ │ ├── DashbuilderCommonMessages_es.properties │ │ │ │ ├── DashbuilderCommonMessages_fr.properties │ │ │ │ ├── DashbuilderCommonMessages_it.properties │ │ │ │ └── DashbuilderCommonMessages_ja.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── common/ │ │ │ └── client/ │ │ │ ├── StringTemplateBuilderTest.java │ │ │ ├── editor/ │ │ │ │ ├── AbstractEditorTest.java │ │ │ │ ├── ToggleSwitchEditorTest.java │ │ │ │ ├── ValueBoxEditorTest.java │ │ │ │ ├── file/ │ │ │ │ │ └── FileUploadEditorTest.java │ │ │ │ ├── list/ │ │ │ │ │ ├── DropDownEditorTest.java │ │ │ │ │ ├── DropDownImageListEditorTest.java │ │ │ │ │ ├── HorizImageListEditorTest.java │ │ │ │ │ └── ImageListEditorTest.java │ │ │ │ └── map/ │ │ │ │ └── MapEditorTest.java │ │ │ └── widgets/ │ │ │ └── FilterLabelSetTest.java │ │ ├── dashbuilder-dataset-client/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── dataset/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── ClientDataSetCore.java │ │ │ │ │ ├── ClientDataSetManager.java │ │ │ │ │ ├── DataSetClientServices.java │ │ │ │ │ ├── DataSetExportReadyCallback.java │ │ │ │ │ ├── DataSetMetadataCallback.java │ │ │ │ │ ├── DataSetReadyCallback.java │ │ │ │ │ ├── editor/ │ │ │ │ │ │ ├── BeanDataSetDefAttributesEditor.java │ │ │ │ │ │ ├── BeanDataSetDefEditor.java │ │ │ │ │ │ ├── CSVDataSetDefAttributesEditor.java │ │ │ │ │ │ ├── CSVDataSetDefEditor.java │ │ │ │ │ │ ├── ColumnListEditor.java │ │ │ │ │ │ ├── ColumnTypeEditor.java │ │ │ │ │ │ ├── DataColumnDefEditor.java │ │ │ │ │ │ ├── DataSetDefBackendCacheAttributesEditor.java │ │ │ │ │ │ ├── DataSetDefBasicAttributesEditor.java │ │ │ │ │ │ ├── DataSetDefClientCacheAttributesEditor.java │ │ │ │ │ │ ├── DataSetDefColumnsEditor.java │ │ │ │ │ │ ├── DataSetDefColumnsFilterEditor.java │ │ │ │ │ │ ├── DataSetDefEditor.java │ │ │ │ │ │ ├── DataSetDefFilterEditor.java │ │ │ │ │ │ ├── DataSetDefProviderTypeEditor.java │ │ │ │ │ │ ├── DataSetDefRefreshAttributesEditor.java │ │ │ │ │ │ ├── DataSetDefRefreshIntervalEditor.java │ │ │ │ │ │ ├── KafkaDataSetDefAttributesEditor.java │ │ │ │ │ │ ├── KafkaDataSetDefEditor.java │ │ │ │ │ │ ├── PrometheusDataSetDefAttributesEditor.java │ │ │ │ │ │ ├── PrometheusDataSetDefEditor.java │ │ │ │ │ │ ├── SQLDataSetDefAttributesEditor.java │ │ │ │ │ │ └── SQLDataSetDefEditor.java │ │ │ │ │ ├── engine/ │ │ │ │ │ │ ├── ClientChronometer.java │ │ │ │ │ │ ├── ClientDateFormatter.java │ │ │ │ │ │ ├── ClientDateFormatterImpl.java │ │ │ │ │ │ ├── ClientIntervalBuilderDynamicDate.java │ │ │ │ │ │ └── ClientIntervalBuilderLocator.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ ├── bundles/ │ │ │ │ │ │ │ ├── DataSetClientImages.java │ │ │ │ │ │ │ └── DataSetClientResources.java │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ ├── AggregateFunctionTypeConstants.java │ │ │ │ │ │ ├── CommonConstants.java │ │ │ │ │ │ ├── CoreFunctionTypeConstants.java │ │ │ │ │ │ ├── DateIntervalTypeConstants.java │ │ │ │ │ │ ├── DayOfWeekConstants.java │ │ │ │ │ │ ├── MonthConstants.java │ │ │ │ │ │ ├── QuarterConstants.java │ │ │ │ │ │ └── TimeModeConstants.java │ │ │ │ │ └── uuid/ │ │ │ │ │ └── ClientUUIDGenerator.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── DatasetClient.gwt.xml │ │ │ │ └── dataset/ │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── AggregateFunctionTypeConstants.properties │ │ │ │ ├── AggregateFunctionTypeConstants_de.properties │ │ │ │ ├── AggregateFunctionTypeConstants_es.properties │ │ │ │ ├── AggregateFunctionTypeConstants_fr.properties │ │ │ │ ├── AggregateFunctionTypeConstants_it.properties │ │ │ │ ├── AggregateFunctionTypeConstants_ja.properties │ │ │ │ ├── AggregateFunctionTypeConstants_pt_BR.properties │ │ │ │ ├── AggregateFunctionTypeConstants_zh_CN.properties │ │ │ │ ├── CommonConstants.properties │ │ │ │ ├── CommonConstants_de.properties │ │ │ │ ├── CommonConstants_es.properties │ │ │ │ ├── CommonConstants_fr.properties │ │ │ │ ├── CommonConstants_it.properties │ │ │ │ ├── CommonConstants_ja.properties │ │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ │ ├── CommonConstants_zh_CN.properties │ │ │ │ ├── CoreFunctionTypeConstants.properties │ │ │ │ ├── CoreFunctionTypeConstants_de.properties │ │ │ │ ├── CoreFunctionTypeConstants_es.properties │ │ │ │ ├── CoreFunctionTypeConstants_fr.properties │ │ │ │ ├── CoreFunctionTypeConstants_it.properties │ │ │ │ ├── CoreFunctionTypeConstants_ja.properties │ │ │ │ ├── CoreFunctionTypeConstants_pt_BR.properties │ │ │ │ ├── CoreFunctionTypeConstants_zh_CN.properties │ │ │ │ ├── DateIntervalTypeConstants.properties │ │ │ │ ├── DateIntervalTypeConstants_de.properties │ │ │ │ ├── DateIntervalTypeConstants_es.properties │ │ │ │ ├── DateIntervalTypeConstants_fr.properties │ │ │ │ ├── DateIntervalTypeConstants_it.properties │ │ │ │ ├── DateIntervalTypeConstants_ja.properties │ │ │ │ ├── DateIntervalTypeConstants_pt_BR.properties │ │ │ │ ├── DateIntervalTypeConstants_zh_CN.properties │ │ │ │ ├── DayOfWeekConstants.properties │ │ │ │ ├── DayOfWeekConstants_de.properties │ │ │ │ ├── DayOfWeekConstants_es.properties │ │ │ │ ├── DayOfWeekConstants_fr.properties │ │ │ │ ├── DayOfWeekConstants_it.properties │ │ │ │ ├── DayOfWeekConstants_ja.properties │ │ │ │ ├── DayOfWeekConstants_pt_BR.properties │ │ │ │ ├── DayOfWeekConstants_zh_CN.properties │ │ │ │ ├── MonthConstants.properties │ │ │ │ ├── MonthConstants_de.properties │ │ │ │ ├── MonthConstants_es.properties │ │ │ │ ├── MonthConstants_fr.properties │ │ │ │ ├── MonthConstants_it.properties │ │ │ │ ├── MonthConstants_ja.properties │ │ │ │ ├── MonthConstants_pt_BR.properties │ │ │ │ ├── MonthConstants_zh_CN.properties │ │ │ │ ├── QuarterConstants.properties │ │ │ │ ├── QuarterConstants_de.properties │ │ │ │ ├── QuarterConstants_es.properties │ │ │ │ ├── QuarterConstants_fr.properties │ │ │ │ ├── QuarterConstants_it.properties │ │ │ │ ├── QuarterConstants_ja.properties │ │ │ │ ├── QuarterConstants_pt_BR.properties │ │ │ │ ├── QuarterConstants_zh_CN.properties │ │ │ │ ├── TimeModeConstants.properties │ │ │ │ ├── TimeModeConstants_de.properties │ │ │ │ ├── TimeModeConstants_es.properties │ │ │ │ ├── TimeModeConstants_fr.properties │ │ │ │ ├── TimeModeConstants_it.properties │ │ │ │ ├── TimeModeConstants_ja.properties │ │ │ │ ├── TimeModeConstants_pt_BR.properties │ │ │ │ └── TimeModeConstants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── dataset/ │ │ │ └── client/ │ │ │ ├── AbstractDataSetTest.java │ │ │ ├── ChronometerMock.java │ │ │ ├── ClientDataSetManagerTest.java │ │ │ ├── ClientDateFormatterMock.java │ │ │ └── DataSetClientServicesTest.java │ │ ├── dashbuilder-dataset-editor/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── dataset/ │ │ │ │ │ └── editor/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── perspectives/ │ │ │ │ │ │ └── DataSetAuthoringPerspective.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ └── DataSetAuthoringConstants.java │ │ │ │ │ └── screens/ │ │ │ │ │ ├── DataSetAuthoringHomePresenter.java │ │ │ │ │ ├── DataSetAuthoringHomeView.java │ │ │ │ │ ├── DataSetAuthoringHomeView.ui.xml │ │ │ │ │ ├── DataSetDefEditorPresenter.java │ │ │ │ │ ├── DataSetDefExplorerScreen.java │ │ │ │ │ ├── DataSetDefScreenView.java │ │ │ │ │ ├── DataSetDefScreenViewImpl.java │ │ │ │ │ ├── DataSetDefType.java │ │ │ │ │ └── DataSetDefWizardScreen.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── DataSetEditor.gwt.xml │ │ │ │ └── dataset/ │ │ │ │ └── editor/ │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── DataSetAuthoringConstants.properties │ │ │ │ ├── DataSetAuthoringConstants_de.properties │ │ │ │ ├── DataSetAuthoringConstants_es.properties │ │ │ │ ├── DataSetAuthoringConstants_fr.properties │ │ │ │ ├── DataSetAuthoringConstants_it.properties │ │ │ │ ├── DataSetAuthoringConstants_ja.properties │ │ │ │ ├── DataSetAuthoringConstants_pt_BR.properties │ │ │ │ └── DataSetAuthoringConstants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── dataset/ │ │ │ └── editor/ │ │ │ └── client/ │ │ │ └── screens/ │ │ │ ├── DataSetAuthoringHomePresenterTest.java │ │ │ ├── DataSetDefEditorPresenterTest.java │ │ │ ├── DataSetDefExplorerScreenTest.java │ │ │ ├── DataSetDefTypeTest.java │ │ │ └── DataSetDefWizardScreenTest.java │ │ ├── dashbuilder-displayer-client/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── displayer/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── AbstractDisplayer.java │ │ │ │ │ ├── AbstractDisplayerListener.java │ │ │ │ │ ├── AbstractErraiDisplayer.java │ │ │ │ │ ├── AbstractErraiDisplayerView.java │ │ │ │ │ ├── AbstractGwtDisplayer.java │ │ │ │ │ ├── AbstractGwtDisplayerView.java │ │ │ │ │ ├── AbstractRendererLibrary.java │ │ │ │ │ ├── ClientSettings.java │ │ │ │ │ ├── DataSetEditHandler.java │ │ │ │ │ ├── DataSetHandler.java │ │ │ │ │ ├── DataSetHandlerImpl.java │ │ │ │ │ ├── Displayer.java │ │ │ │ │ ├── DisplayerClientEntryPoint.java │ │ │ │ │ ├── DisplayerCoordinator.java │ │ │ │ │ ├── DisplayerGwtExprEval.java │ │ │ │ │ ├── DisplayerGwtFormatter.java │ │ │ │ │ ├── DisplayerListener.java │ │ │ │ │ ├── DisplayerLocator.java │ │ │ │ │ ├── RendererLibrary.java │ │ │ │ │ ├── RendererManager.java │ │ │ │ │ ├── component/ │ │ │ │ │ │ ├── ExternalComponentDispatcher.java │ │ │ │ │ │ ├── ExternalComponentListener.java │ │ │ │ │ │ ├── ExternalComponentMessageHelperProducer.java │ │ │ │ │ │ └── function/ │ │ │ │ │ │ ├── BackendFunctionLoader.java │ │ │ │ │ │ ├── ComponentFunctionLocator.java │ │ │ │ │ │ ├── GWTVersion.java │ │ │ │ │ │ └── ListFunctions.java │ │ │ │ │ ├── events/ │ │ │ │ │ │ ├── ColumnDetailsChangedEvent.java │ │ │ │ │ │ ├── ColumnFilterChangedEvent.java │ │ │ │ │ │ ├── ColumnFilterDeletedEvent.java │ │ │ │ │ │ ├── DataSetFilterChangedEvent.java │ │ │ │ │ │ ├── DataSetGroupDateChanged.java │ │ │ │ │ │ ├── DataSetLookupChangedEvent.java │ │ │ │ │ │ ├── DisplayerEditorClosedEvent.java │ │ │ │ │ │ ├── DisplayerEditorSavedEvent.java │ │ │ │ │ │ ├── DisplayerSettingsChangedEvent.java │ │ │ │ │ │ ├── DisplayerSubtypeSelectedEvent.java │ │ │ │ │ │ ├── DisplayerTypeSelectedEvent.java │ │ │ │ │ │ ├── GroupFunctionChangedEvent.java │ │ │ │ │ │ └── GroupFunctionDeletedEvent.java │ │ │ │ │ ├── export/ │ │ │ │ │ │ ├── ExportCallback.java │ │ │ │ │ │ └── ExportFormat.java │ │ │ │ │ ├── formatter/ │ │ │ │ │ │ ├── AbstractValueFormatter.java │ │ │ │ │ │ ├── ValueFormatter.java │ │ │ │ │ │ └── ValueFormatterRegistry.java │ │ │ │ │ ├── prototypes/ │ │ │ │ │ │ ├── DataSetPrototypes.java │ │ │ │ │ │ └── DisplayerPrototypes.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ ├── i18n/ │ │ │ │ │ │ │ ├── CommonConstants.java │ │ │ │ │ │ │ ├── DisplayerConstants.java │ │ │ │ │ │ │ ├── DisplayerHtmlConstants.java │ │ │ │ │ │ │ ├── DisplayerTypeConstants.java │ │ │ │ │ │ │ ├── MapColorSchemeConstants.java │ │ │ │ │ │ │ ├── PositionConstants.java │ │ │ │ │ │ │ ├── SourceCodeEditorConstants.java │ │ │ │ │ │ │ └── SourceCodeValidatorConstants.java │ │ │ │ │ │ └── images/ │ │ │ │ │ │ └── DisplayerImagesResources.java │ │ │ │ │ └── widgets/ │ │ │ │ │ ├── DataSetLookupEditor.java │ │ │ │ │ ├── DataSetLookupEditorView.java │ │ │ │ │ ├── DataSetLookupEditorView.ui.xml │ │ │ │ │ ├── DisplayerEditor.java │ │ │ │ │ ├── DisplayerEditorPopup.java │ │ │ │ │ ├── DisplayerEditorPopup.ui.xml │ │ │ │ │ ├── DisplayerEditorStatus.java │ │ │ │ │ ├── DisplayerEditorView.java │ │ │ │ │ ├── DisplayerEditorView.ui.xml │ │ │ │ │ ├── DisplayerError.java │ │ │ │ │ ├── DisplayerError.ui.xml │ │ │ │ │ ├── DisplayerErrorWidget.css │ │ │ │ │ ├── DisplayerErrorWidget.html │ │ │ │ │ ├── DisplayerErrorWidget.java │ │ │ │ │ ├── DisplayerHtmlEditor.java │ │ │ │ │ ├── DisplayerHtmlEditorView.html │ │ │ │ │ ├── DisplayerHtmlEditorView.java │ │ │ │ │ ├── DisplayerSettingsEditor.java │ │ │ │ │ ├── DisplayerSettingsEditorView.java │ │ │ │ │ ├── DisplayerSettingsEditorView.ui.xml │ │ │ │ │ ├── DisplayerSettingsJSONSourceViewer.java │ │ │ │ │ ├── DisplayerSettingsJSONSourceViewer.ui.xml │ │ │ │ │ ├── DisplayerSubtypeSelector.java │ │ │ │ │ ├── DisplayerSubtypeSelectorView.java │ │ │ │ │ ├── DisplayerTypeSelector.java │ │ │ │ │ ├── DisplayerTypeSelectorView.java │ │ │ │ │ ├── DisplayerTypeSelectorView.ui.xml │ │ │ │ │ ├── DisplayerViewer.java │ │ │ │ │ ├── ExternalComponentEditor.java │ │ │ │ │ ├── ExternalComponentEditorPopUp.java │ │ │ │ │ ├── ExternalComponentEditorView.css │ │ │ │ │ ├── ExternalComponentEditorView.html │ │ │ │ │ ├── ExternalComponentEditorView.java │ │ │ │ │ ├── ExternalComponentPresenter.java │ │ │ │ │ ├── ExternalComponentPropertiesEditor.java │ │ │ │ │ ├── ExternalComponentPropertiesEditorView.css │ │ │ │ │ ├── ExternalComponentPropertiesEditorView.html │ │ │ │ │ ├── ExternalComponentPropertiesEditorView.java │ │ │ │ │ ├── ExternalComponentView.css │ │ │ │ │ ├── ExternalComponentView.html │ │ │ │ │ ├── ExternalComponentView.java │ │ │ │ │ ├── RendererSelector.java │ │ │ │ │ ├── RendererSelectorListBoxView.java │ │ │ │ │ ├── RendererSelectorListBoxView.ui.xml │ │ │ │ │ ├── RendererSelectorRadioListView.java │ │ │ │ │ ├── RendererSelectorRadioListView.ui.xml │ │ │ │ │ ├── RendererSelectorTabListView.java │ │ │ │ │ ├── RendererSelectorTabListView.ui.xml │ │ │ │ │ ├── filter/ │ │ │ │ │ │ ├── ColumnFilterEditor.java │ │ │ │ │ │ ├── ColumnFilterEditorView.java │ │ │ │ │ │ ├── ColumnFilterEditorView.ui.xml │ │ │ │ │ │ ├── DataSetFilterEditor.java │ │ │ │ │ │ ├── DataSetFilterEditorView.java │ │ │ │ │ │ ├── DataSetFilterEditorView.ui.xml │ │ │ │ │ │ ├── DateParameterEditor.java │ │ │ │ │ │ ├── DateParameterEditorView.java │ │ │ │ │ │ ├── DateParameterEditorView.ui.xml │ │ │ │ │ │ ├── FunctionParameterEditor.java │ │ │ │ │ │ ├── LikeToFunctionEditor.java │ │ │ │ │ │ ├── LikeToFunctionEditorView.java │ │ │ │ │ │ ├── LikeToFunctionEditorView.ui.xml │ │ │ │ │ │ ├── MultipleNumberParameterEditor.java │ │ │ │ │ │ ├── MultipleNumberParameterEditorView.java │ │ │ │ │ │ ├── MultipleNumberParameterEditorView.ui.xml │ │ │ │ │ │ ├── MultipleTextParameterEditor.java │ │ │ │ │ │ ├── MultipleTextParameterEditorView.java │ │ │ │ │ │ ├── MultipleTextParameterEditorView.ui.xml │ │ │ │ │ │ ├── NumberParameterEditor.java │ │ │ │ │ │ ├── NumberParameterEditorView.java │ │ │ │ │ │ ├── NumberParameterEditorView.ui.xml │ │ │ │ │ │ ├── TextParameterEditor.java │ │ │ │ │ │ ├── TextParameterEditorView.java │ │ │ │ │ │ ├── TextParameterEditorView.ui.xml │ │ │ │ │ │ ├── TimeAmountEditor.java │ │ │ │ │ │ ├── TimeAmountEditorView.java │ │ │ │ │ │ ├── TimeAmountEditorView.ui.xml │ │ │ │ │ │ ├── TimeFrameEditor.java │ │ │ │ │ │ ├── TimeFrameEditorView.java │ │ │ │ │ │ ├── TimeFrameEditorView.ui.xml │ │ │ │ │ │ ├── TimeInstantEditor.java │ │ │ │ │ │ ├── TimeInstantEditorView.java │ │ │ │ │ │ └── TimeInstantEditorView.ui.xml │ │ │ │ │ ├── group/ │ │ │ │ │ │ ├── ColumnDetailsEditor.java │ │ │ │ │ │ ├── ColumnDetailsEditorView.java │ │ │ │ │ │ ├── ColumnDetailsEditorView.ui.xml │ │ │ │ │ │ ├── ColumnFunctionEditor.java │ │ │ │ │ │ ├── ColumnFunctionEditorView.java │ │ │ │ │ │ ├── ColumnFunctionEditorView.ui.xml │ │ │ │ │ │ ├── DataSetGroupDateEditor.java │ │ │ │ │ │ ├── DataSetGroupDateEditorView.java │ │ │ │ │ │ └── DataSetGroupDateEditorView.ui.xml │ │ │ │ │ └── sourcecode/ │ │ │ │ │ ├── DefaultHtmlValidator.java │ │ │ │ │ ├── DefaultJsEvaluator.java │ │ │ │ │ ├── DefaultJsValidator.java │ │ │ │ │ ├── HasHtmlTemplate.java │ │ │ │ │ ├── HasJsTemplate.java │ │ │ │ │ ├── HtmlValidator.java │ │ │ │ │ ├── JsEvaluator.java │ │ │ │ │ ├── JsValidator.java │ │ │ │ │ ├── SourceCodeEditor.java │ │ │ │ │ ├── SourceCodeEditorView.css │ │ │ │ │ ├── SourceCodeEditorView.html │ │ │ │ │ ├── SourceCodeEditorView.java │ │ │ │ │ └── SourceCodeType.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── DisplayerClient.gwt.xml │ │ │ │ └── displayer/ │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── CommonConstants.properties │ │ │ │ ├── CommonConstants_de.properties │ │ │ │ ├── CommonConstants_es.properties │ │ │ │ ├── CommonConstants_fr.properties │ │ │ │ ├── CommonConstants_it.properties │ │ │ │ ├── CommonConstants_ja.properties │ │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ │ ├── CommonConstants_zh_CN.properties │ │ │ │ ├── DisplayerConstants.properties │ │ │ │ ├── DisplayerConstants_de.properties │ │ │ │ ├── DisplayerConstants_es.properties │ │ │ │ ├── DisplayerConstants_fr.properties │ │ │ │ ├── DisplayerConstants_it.properties │ │ │ │ ├── DisplayerConstants_ja.properties │ │ │ │ ├── DisplayerConstants_pt_BR.properties │ │ │ │ ├── DisplayerConstants_zh_CN.properties │ │ │ │ ├── DisplayerHtmlConstants.properties │ │ │ │ ├── DisplayerHtmlConstants_es.properties │ │ │ │ ├── DisplayerHtmlConstants_fr.properties │ │ │ │ ├── DisplayerHtmlConstants_ja.properties │ │ │ │ ├── DisplayerTypeConstants.properties │ │ │ │ ├── DisplayerTypeConstants_de.properties │ │ │ │ ├── DisplayerTypeConstants_es.properties │ │ │ │ ├── DisplayerTypeConstants_fr.properties │ │ │ │ ├── DisplayerTypeConstants_it.properties │ │ │ │ ├── DisplayerTypeConstants_ja.properties │ │ │ │ ├── DisplayerTypeConstants_pt_BR.properties │ │ │ │ ├── DisplayerTypeConstants_zh_CN.properties │ │ │ │ ├── MapColorSchemeConstants.properties │ │ │ │ ├── MapColorSchemeConstants_es.properties │ │ │ │ ├── MapColorSchemeConstants_fr.properties │ │ │ │ ├── MapColorSchemeConstants_it.properties │ │ │ │ ├── MapColorSchemeConstants_ja.properties │ │ │ │ ├── PositionConstants.properties │ │ │ │ ├── PositionConstants_de.properties │ │ │ │ ├── PositionConstants_es.properties │ │ │ │ ├── PositionConstants_fr.properties │ │ │ │ ├── PositionConstants_it.properties │ │ │ │ ├── PositionConstants_ja.properties │ │ │ │ ├── PositionConstants_pt_BR.properties │ │ │ │ ├── PositionConstants_zh_CN.properties │ │ │ │ ├── SourceCodeEditorConstants.properties │ │ │ │ ├── SourceCodeEditorConstants_es.properties │ │ │ │ ├── SourceCodeEditorConstants_fr.properties │ │ │ │ ├── SourceCodeEditorConstants_it.properties │ │ │ │ ├── SourceCodeEditorConstants_ja.properties │ │ │ │ ├── SourceCodeValidatorConstants.properties │ │ │ │ ├── SourceCodeValidatorConstants_es.properties │ │ │ │ ├── SourceCodeValidatorConstants_fr.properties │ │ │ │ ├── SourceCodeValidatorConstants_it.properties │ │ │ │ └── SourceCodeValidatorConstants_ja.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── displayer/ │ │ │ └── client/ │ │ │ ├── AbstractDisplayerTest.java │ │ │ ├── DisplayerCoordinatorTest.java │ │ │ ├── DisplayerEvaluatorMock.java │ │ │ ├── DisplayerExportTest.java │ │ │ ├── DisplayerFilterTest.java │ │ │ ├── DisplayerFormatterMock.java │ │ │ ├── DisplayerLifecycleTest.java │ │ │ ├── DisplayerMock.java │ │ │ ├── DisplayerRefreshTest.java │ │ │ ├── RendererManagerTest.java │ │ │ ├── component/ │ │ │ │ ├── ExternalComponentDispatcherTest.java │ │ │ │ └── function/ │ │ │ │ └── ComponentFunctionLocatorTest.java │ │ │ └── widgets/ │ │ │ ├── DataSetLookupEditorTest.java │ │ │ ├── DisplayerEditorTest.java │ │ │ ├── DisplayerHtmlEditorTest.java │ │ │ ├── DisplayerSettingsEditorTest.java │ │ │ ├── DisplayerSubtypeSelectorTest.java │ │ │ ├── DisplayerTypeSelectorTest.java │ │ │ ├── ExternalComponentPresenterTest.java │ │ │ ├── ExternalComponentPropertiesEditorTest.java │ │ │ ├── RendererSelectorTest.java │ │ │ ├── filter/ │ │ │ │ ├── ColumnFilterEditorTest.java │ │ │ │ ├── DataSetFilterEditorTest.java │ │ │ │ ├── LikeToFunctionEditorTest.java │ │ │ │ ├── MultipleNumberParameterEditorTest.java │ │ │ │ ├── MultipleTextParameterEditorTest.java │ │ │ │ ├── NumberParameterEditorTest.java │ │ │ │ ├── TextParameterEditorTest.java │ │ │ │ ├── TimeAmountEditorTest.java │ │ │ │ ├── TimeFrameEditorTest.java │ │ │ │ └── TimeInstantEditorTest.java │ │ │ ├── group/ │ │ │ │ ├── ColumnFunctionEditorTest.java │ │ │ │ └── DataSetGroupDateEditorTest.java │ │ │ └── sourcecode/ │ │ │ ├── JsValidatorTest.java │ │ │ └── SourceCodeEditorTest.java │ │ ├── dashbuilder-displayer-editor/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── client/ │ │ │ │ │ └── editor/ │ │ │ │ │ ├── AreaChartDragComponent.java │ │ │ │ │ ├── BarChartDragComponent.java │ │ │ │ │ ├── BubbleChartDragComponent.java │ │ │ │ │ ├── DisplayerDragComponent.java │ │ │ │ │ ├── DisplayerEditorEntryPoint.java │ │ │ │ │ ├── LineChartDragComponent.java │ │ │ │ │ ├── MapChartDragComponent.java │ │ │ │ │ ├── MeterChartDragComponent.java │ │ │ │ │ ├── MetricDragComponent.java │ │ │ │ │ ├── PerspectiveEditorReportingGroupProvider.java │ │ │ │ │ ├── PieChartDragComponent.java │ │ │ │ │ ├── SelectorDragComponent.java │ │ │ │ │ ├── TableDragComponent.java │ │ │ │ │ ├── external/ │ │ │ │ │ │ ├── ComponentGroupProducer.java │ │ │ │ │ │ ├── ExternalComponentDragDef.java │ │ │ │ │ │ ├── ExternalDisplayerDragComponent.java │ │ │ │ │ │ └── ExternalDragComponent.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ └── Constants.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── DisplayerEditor.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── editor/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── Constants.properties │ │ │ │ ├── Constants_de.properties │ │ │ │ ├── Constants_es.properties │ │ │ │ ├── Constants_fr.properties │ │ │ │ ├── Constants_it.properties │ │ │ │ ├── Constants_ja.properties │ │ │ │ ├── Constants_pt_BR.properties │ │ │ │ └── Constants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── client/ │ │ │ └── editor/ │ │ │ ├── DisplayerDragComponentTest.java │ │ │ ├── PerspectiveEditorReportingGroupProviderTest.java │ │ │ └── external/ │ │ │ └── ExternalComponentGroupProviderTest.java │ │ ├── dashbuilder-displayer-screen/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── displayer/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── DisplayerScreenPresenter.java │ │ │ │ │ ├── PerspectiveCoordinator.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ └── Constants.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── DisplayerScreen.gwt.xml │ │ │ │ └── displayer/ │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── Constants.properties │ │ │ │ ├── Constants_de.properties │ │ │ │ ├── Constants_es.properties │ │ │ │ ├── Constants_fr.properties │ │ │ │ ├── Constants_it.properties │ │ │ │ ├── Constants_ja.properties │ │ │ │ ├── Constants_pt_BR.properties │ │ │ │ └── Constants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── displayer/ │ │ │ └── client/ │ │ │ └── PerspectiveCoordinatorTest.java │ │ ├── dashbuilder-kie-server-client/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── client/ │ │ │ │ └── kieserver/ │ │ │ │ ├── dataset/ │ │ │ │ │ └── editor/ │ │ │ │ │ ├── RemoteDataSetDefAttributesEditor.java │ │ │ │ │ ├── RemoteDataSetDefEditor.java │ │ │ │ │ ├── RemoteDataSetEditorDriverFactory.java │ │ │ │ │ ├── driver/ │ │ │ │ │ │ ├── RemoteDataSetDefAttributesDriver.java │ │ │ │ │ │ └── RemoteDataSetDefDriver.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── RemoteDataSetDefAttributesEditorImpl.java │ │ │ │ │ │ ├── RemoteDataSetDefAttributesEditorView.java │ │ │ │ │ │ ├── RemoteDataSetDefAttributesEditorView.ui.xml │ │ │ │ │ │ ├── RemoteDataSetEditor.java │ │ │ │ │ │ └── RemoteDataSetEditorPlugin.java │ │ │ │ │ ├── validator/ │ │ │ │ │ │ └── RemoteDataSetDefValidator.java │ │ │ │ │ └── workflow/ │ │ │ │ │ ├── RemoteDataSetBasicAttributesWorkflow.java │ │ │ │ │ └── RemoteDataSetEditWorkflow.java │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ └── KieServerClientConstants.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ ├── DashbuilderKieServerClient.gwt.xml │ │ │ └── client/ │ │ │ └── kieserver/ │ │ │ └── resources/ │ │ │ └── i18n/ │ │ │ ├── KieServerClientConstants.properties │ │ │ ├── KieServerClientConstants_es.properties │ │ │ ├── KieServerClientConstants_fr.properties │ │ │ ├── KieServerClientConstants_it.properties │ │ │ └── KieServerClientConstants_ja.properties │ │ ├── dashbuilder-navigation-client/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── client/ │ │ │ │ │ └── navigation/ │ │ │ │ │ ├── NavBarHelper.java │ │ │ │ │ ├── NavigationManager.java │ │ │ │ │ ├── event/ │ │ │ │ │ │ ├── NavItemEditCancelledEvent.java │ │ │ │ │ │ ├── NavItemEditStartedEvent.java │ │ │ │ │ │ ├── NavItemGotoEvent.java │ │ │ │ │ │ └── NavTreeLoadedEvent.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ └── NavigationManagerImpl.java │ │ │ │ │ ├── layout/ │ │ │ │ │ │ └── editor/ │ │ │ │ │ │ ├── AbstractNavDragComponent.java │ │ │ │ │ │ ├── NavCarouselDragComponent.java │ │ │ │ │ │ ├── NavDragComponent.java │ │ │ │ │ │ ├── NavMenuBarDragComponent.java │ │ │ │ │ │ ├── NavTabListDragComponent.java │ │ │ │ │ │ ├── NavTilesDragComponent.java │ │ │ │ │ │ └── NavTreeDragComponent.java │ │ │ │ │ ├── plugin/ │ │ │ │ │ │ ├── PerspectivePluginEntryPoint.java │ │ │ │ │ │ ├── PerspectivePluginManager.java │ │ │ │ │ │ └── PerspectivePluginManagerImpl.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ └── NavigationConstants.java │ │ │ │ │ └── widget/ │ │ │ │ │ ├── BaseNavWidget.java │ │ │ │ │ ├── BaseNavWidgetView.java │ │ │ │ │ ├── HasDefaultNavItem.java │ │ │ │ │ ├── HasTargetDiv.java │ │ │ │ │ ├── NavCarouselWidget.java │ │ │ │ │ ├── NavCarouselWidgetView.html │ │ │ │ │ ├── NavCarouselWidgetView.java │ │ │ │ │ ├── NavComponentConfigModal.java │ │ │ │ │ ├── NavComponentConfigModalView.css │ │ │ │ │ ├── NavComponentConfigModalView.html │ │ │ │ │ ├── NavComponentConfigModalView.java │ │ │ │ │ ├── NavDropDownWidget.java │ │ │ │ │ ├── NavDropDownWidgetView.html │ │ │ │ │ ├── NavDropDownWidgetView.java │ │ │ │ │ ├── NavItemTileWidget.java │ │ │ │ │ ├── NavItemTileWidgetView.css │ │ │ │ │ ├── NavItemTileWidgetView.html │ │ │ │ │ ├── NavItemTileWidgetView.java │ │ │ │ │ ├── NavMenuBarWidget.java │ │ │ │ │ ├── NavMenuBarWidgetView.html │ │ │ │ │ ├── NavMenuBarWidgetView.java │ │ │ │ │ ├── NavTabListWidget.java │ │ │ │ │ ├── NavTabListWidgetView.html │ │ │ │ │ ├── NavTabListWidgetView.java │ │ │ │ │ ├── NavTilesWidget.java │ │ │ │ │ ├── NavTilesWidgetView.html │ │ │ │ │ ├── NavTilesWidgetView.java │ │ │ │ │ ├── NavTreeWidget.java │ │ │ │ │ ├── NavTreeWidgetView.css │ │ │ │ │ ├── NavTreeWidgetView.html │ │ │ │ │ ├── NavTreeWidgetView.java │ │ │ │ │ ├── NavWidget.java │ │ │ │ │ ├── NavWidgetView.java │ │ │ │ │ ├── TargetDivNavWidget.java │ │ │ │ │ ├── TargetDivNavWidgetView.java │ │ │ │ │ └── editor/ │ │ │ │ │ ├── NavItemDefaultEditor.java │ │ │ │ │ ├── NavItemDefaultEditorView.css │ │ │ │ │ ├── NavItemDefaultEditorView.html │ │ │ │ │ ├── NavItemDefaultEditorView.java │ │ │ │ │ ├── NavItemEditor.java │ │ │ │ │ ├── NavItemEditorSettings.java │ │ │ │ │ ├── NavItemEditorView.java │ │ │ │ │ ├── NavRootNodeEditor.java │ │ │ │ │ ├── NavRootNodeEditorView.css │ │ │ │ │ ├── NavRootNodeEditorView.html │ │ │ │ │ ├── NavRootNodeEditorView.java │ │ │ │ │ ├── NavTreeEditor.java │ │ │ │ │ ├── NavTreeEditorView.css │ │ │ │ │ ├── NavTreeEditorView.html │ │ │ │ │ ├── NavTreeEditorView.java │ │ │ │ │ ├── TargetPerspectiveEditor.java │ │ │ │ │ ├── TargetPerspectiveEditorView.css │ │ │ │ │ ├── TargetPerspectiveEditorView.html │ │ │ │ │ └── TargetPerspectiveEditorView.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── NavigationClient.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── navigation/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── NavigationConstants.properties │ │ │ │ ├── NavigationConstants_de.properties │ │ │ │ ├── NavigationConstants_es.properties │ │ │ │ ├── NavigationConstants_fr.properties │ │ │ │ ├── NavigationConstants_it.properties │ │ │ │ ├── NavigationConstants_ja.properties │ │ │ │ ├── NavigationConstants_pt_BR.properties │ │ │ │ └── NavigationConstants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── client/ │ │ │ └── navigation/ │ │ │ ├── NavComponentConfigModalTest.java │ │ │ ├── plugin/ │ │ │ │ └── PerspectivePluginManagerImplTest.java │ │ │ └── widget/ │ │ │ ├── NavMenuBarWidgetTest.java │ │ │ ├── NavTabListWidgetTest.java │ │ │ ├── NavTilesWidgetTest.java │ │ │ └── editor/ │ │ │ ├── NavItemEditorTest.java │ │ │ ├── NavTreeEditorTest.java │ │ │ └── TargetPerspectiveEditorTest.java │ │ ├── dashbuilder-renderers/ │ │ │ ├── dashbuilder-renderer-c3/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ │ └── renderer/ │ │ │ │ │ │ └── c3/ │ │ │ │ │ │ ├── client/ │ │ │ │ │ │ │ ├── C3AbstractDisplayer.java │ │ │ │ │ │ │ ├── C3AbstractDisplayerView.java │ │ │ │ │ │ │ ├── C3Displayer.java │ │ │ │ │ │ │ ├── C3DisplayerView.java │ │ │ │ │ │ │ ├── C3Renderer.java │ │ │ │ │ │ │ ├── C3XYDisplayer.java │ │ │ │ │ │ │ ├── charts/ │ │ │ │ │ │ │ │ ├── CommonC3DisplayerConstants.java │ │ │ │ │ │ │ │ ├── area/ │ │ │ │ │ │ │ │ │ ├── C3AreaChartDisplayer.java │ │ │ │ │ │ │ │ │ └── C3AreaChartView.java │ │ │ │ │ │ │ │ ├── bar/ │ │ │ │ │ │ │ │ │ ├── C3BarChartDisplayer.java │ │ │ │ │ │ │ │ │ └── C3BarChartView.java │ │ │ │ │ │ │ │ ├── bubble/ │ │ │ │ │ │ │ │ │ ├── BubbleData.java │ │ │ │ │ │ │ │ │ ├── C3BubbleChartDisplayer.java │ │ │ │ │ │ │ │ │ └── C3BubbleChartView.java │ │ │ │ │ │ │ │ ├── line/ │ │ │ │ │ │ │ │ │ ├── C3LineChartDisplayer.java │ │ │ │ │ │ │ │ │ └── C3LineChartView.java │ │ │ │ │ │ │ │ ├── map/ │ │ │ │ │ │ │ │ │ ├── D3MapConf.java │ │ │ │ │ │ │ │ │ ├── D3MapDisplayer.java │ │ │ │ │ │ │ │ │ ├── D3MapDisplayerView.java │ │ │ │ │ │ │ │ │ ├── geojson/ │ │ │ │ │ │ │ │ │ │ ├── CountriesGeoJsonService.java │ │ │ │ │ │ │ │ │ │ ├── GeoJsonLoader.java │ │ │ │ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ │ │ │ │ ├── CountriesGeoJsonServiceImpl.java │ │ │ │ │ │ │ │ │ │ └── GWTGeoJsonLoader.java │ │ │ │ │ │ │ │ │ └── widgets/ │ │ │ │ │ │ │ │ │ ├── D3Map.css │ │ │ │ │ │ │ │ │ ├── D3Map.html │ │ │ │ │ │ │ │ │ ├── D3Map.java │ │ │ │ │ │ │ │ │ ├── MapTooltip.css │ │ │ │ │ │ │ │ │ ├── MapTooltip.html │ │ │ │ │ │ │ │ │ └── MapTooltip.java │ │ │ │ │ │ │ │ ├── meter/ │ │ │ │ │ │ │ │ │ ├── C3MeterChartDisplayer.java │ │ │ │ │ │ │ │ │ └── C3MeterView.java │ │ │ │ │ │ │ │ └── pie/ │ │ │ │ │ │ │ │ ├── C3PieChartDisplayer.java │ │ │ │ │ │ │ │ └── C3PieChartView.java │ │ │ │ │ │ │ ├── exports/ │ │ │ │ │ │ │ │ ├── NativeLibraryResources.java │ │ │ │ │ │ │ │ └── ResourcesInjector.java │ │ │ │ │ │ │ ├── jsbinding/ │ │ │ │ │ │ │ │ ├── C3.java │ │ │ │ │ │ │ │ ├── C3AxisInfo.java │ │ │ │ │ │ │ │ ├── C3AxisLabel.java │ │ │ │ │ │ │ │ ├── C3AxisX.java │ │ │ │ │ │ │ │ ├── C3AxisY.java │ │ │ │ │ │ │ │ ├── C3Chart.java │ │ │ │ │ │ │ │ ├── C3ChartConf.java │ │ │ │ │ │ │ │ ├── C3ChartData.java │ │ │ │ │ │ │ │ ├── C3ChartSize.java │ │ │ │ │ │ │ │ ├── C3Color.java │ │ │ │ │ │ │ │ ├── C3DataInfo.java │ │ │ │ │ │ │ │ ├── C3Donut.java │ │ │ │ │ │ │ │ ├── C3Format.java │ │ │ │ │ │ │ │ ├── C3Gauge.java │ │ │ │ │ │ │ │ ├── C3Grid.java │ │ │ │ │ │ │ │ ├── C3GridConf.java │ │ │ │ │ │ │ │ ├── C3JsTypesFactory.java │ │ │ │ │ │ │ │ ├── C3Legend.java │ │ │ │ │ │ │ │ ├── C3Padding.java │ │ │ │ │ │ │ │ ├── C3Point.java │ │ │ │ │ │ │ │ ├── C3Selection.java │ │ │ │ │ │ │ │ ├── C3Threshold.java │ │ │ │ │ │ │ │ ├── C3Tick.java │ │ │ │ │ │ │ │ ├── C3Tooltip.java │ │ │ │ │ │ │ │ ├── C3Transition.java │ │ │ │ │ │ │ │ ├── d3/ │ │ │ │ │ │ │ │ │ ├── D3PathGenerator.java │ │ │ │ │ │ │ │ │ └── D3Projection.java │ │ │ │ │ │ │ │ └── geojson/ │ │ │ │ │ │ │ │ ├── Feature.java │ │ │ │ │ │ │ │ ├── FeatureCollection.java │ │ │ │ │ │ │ │ ├── Geometry.java │ │ │ │ │ │ │ │ └── GeometryType.java │ │ │ │ │ │ │ └── resources/ │ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ │ └── C3DisplayerConstants.java │ │ │ │ │ │ └── mutationobserver/ │ │ │ │ │ │ └── MutationObserverFactory.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── renderer/ │ │ │ │ │ ├── C3Renderer.gwt.xml │ │ │ │ │ └── c3/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── exports/ │ │ │ │ │ │ └── json/ │ │ │ │ │ │ └── countries.geo.json │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── C3DisplayerConstants.properties │ │ │ │ │ ├── C3DisplayerConstants_de.properties │ │ │ │ │ ├── C3DisplayerConstants_es.properties │ │ │ │ │ ├── C3DisplayerConstants_fr.properties │ │ │ │ │ ├── C3DisplayerConstants_it.properties │ │ │ │ │ ├── C3DisplayerConstants_ja.properties │ │ │ │ │ ├── C3DisplayerConstants_pt_BR.properties │ │ │ │ │ └── C3DisplayerConstants_zh_CN.properties │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── renderer/ │ │ │ │ └── c3/ │ │ │ │ └── client/ │ │ │ │ ├── C3BaseTest.java │ │ │ │ ├── C3DisplayerTest.java │ │ │ │ ├── C3RendererTest.java │ │ │ │ ├── C3ResizableChartTest.java │ │ │ │ └── charts/ │ │ │ │ ├── area/ │ │ │ │ │ └── C3AreaChartDisplayerTest.java │ │ │ │ ├── map/ │ │ │ │ │ ├── D3MapDisplayerTest.java │ │ │ │ │ └── geojson/ │ │ │ │ │ └── impl/ │ │ │ │ │ └── CountriesGeoJsonServiceImplTest.java │ │ │ │ └── meter/ │ │ │ │ └── C3MeterDisplayerTest.java │ │ │ ├── dashbuilder-renderer-chartjs/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── renderer/ │ │ │ │ │ └── chartjs/ │ │ │ │ │ ├── ChartJsBarChartDisplayer.java │ │ │ │ │ ├── ChartJsBarChartDisplayerView.java │ │ │ │ │ ├── ChartJsDisplayer.java │ │ │ │ │ ├── ChartJsDisplayerView.java │ │ │ │ │ ├── ChartJsRenderer.java │ │ │ │ │ ├── lib/ │ │ │ │ │ │ ├── BarChart.java │ │ │ │ │ │ ├── Chart.java │ │ │ │ │ │ ├── ChartJs.java │ │ │ │ │ │ ├── ChartWithAnimation.java │ │ │ │ │ │ ├── ChartWithScale.java │ │ │ │ │ │ ├── ChartWithTooltip.java │ │ │ │ │ │ ├── DoughnutChart.java │ │ │ │ │ │ ├── LineChart.java │ │ │ │ │ │ ├── PieChart.java │ │ │ │ │ │ ├── PolarAreaChart.java │ │ │ │ │ │ ├── RadarChart.java │ │ │ │ │ │ ├── data/ │ │ │ │ │ │ │ ├── AreaChartData.java │ │ │ │ │ │ │ ├── AreaChartDataProvider.java │ │ │ │ │ │ │ ├── AreaSeries.java │ │ │ │ │ │ │ ├── ChartDataProvider.java │ │ │ │ │ │ │ ├── Data.java │ │ │ │ │ │ │ ├── Dataset.java │ │ │ │ │ │ │ ├── LineChartData.java │ │ │ │ │ │ │ ├── PieChartDataProvider.java │ │ │ │ │ │ │ ├── RadarChartData.java │ │ │ │ │ │ │ ├── Series.java │ │ │ │ │ │ │ └── SeriesBuilder.java │ │ │ │ │ │ ├── event/ │ │ │ │ │ │ │ ├── AnimationCompleteEvent.java │ │ │ │ │ │ │ ├── AnimationCompleteHandler.java │ │ │ │ │ │ │ ├── DataSelectionEvent.java │ │ │ │ │ │ │ ├── DataSelectionHandler.java │ │ │ │ │ │ │ ├── HasAnimationCompleteHandlers.java │ │ │ │ │ │ │ └── HasDataSelectionEventHandlers.java │ │ │ │ │ │ ├── options/ │ │ │ │ │ │ │ ├── AnimationCallback.java │ │ │ │ │ │ │ ├── ChartOption.java │ │ │ │ │ │ │ ├── HasAnimation.java │ │ │ │ │ │ │ ├── HasScale.java │ │ │ │ │ │ │ ├── HasTooltip.java │ │ │ │ │ │ │ ├── IsResponsive.java │ │ │ │ │ │ │ ├── LegendOption.java │ │ │ │ │ │ │ └── Type.java │ │ │ │ │ │ └── resources/ │ │ │ │ │ │ ├── ChartStyle.java │ │ │ │ │ │ ├── Resources.java │ │ │ │ │ │ └── js/ │ │ │ │ │ │ └── chart.css │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ └── ChartJsDisplayerConstants.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── renderer/ │ │ │ │ ├── ChartJsRenderer.gwt.xml │ │ │ │ └── chartjs/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── ChartJsDisplayerConstants.properties │ │ │ │ ├── ChartJsDisplayerConstants_de.properties │ │ │ │ ├── ChartJsDisplayerConstants_es.properties │ │ │ │ ├── ChartJsDisplayerConstants_fr.properties │ │ │ │ ├── ChartJsDisplayerConstants_it.properties │ │ │ │ ├── ChartJsDisplayerConstants_ja.properties │ │ │ │ ├── ChartJsDisplayerConstants_pt_BR.properties │ │ │ │ └── ChartJsDisplayerConstants_zh_CN.properties │ │ │ ├── dashbuilder-renderer-default/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ │ └── renderer/ │ │ │ │ │ │ └── client/ │ │ │ │ │ │ ├── DefaultRenderer.java │ │ │ │ │ │ ├── external/ │ │ │ │ │ │ │ ├── ExternalComponentDisplayer.java │ │ │ │ │ │ │ ├── ExternalComponentDisplayerView.html │ │ │ │ │ │ │ └── ExternalComponentDisplayerView.java │ │ │ │ │ │ ├── metric/ │ │ │ │ │ │ │ ├── MetricDisplayer.java │ │ │ │ │ │ │ └── MetricView.java │ │ │ │ │ │ ├── resources/ │ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ │ ├── CommonConstants.java │ │ │ │ │ │ │ ├── MetricConstants.java │ │ │ │ │ │ │ ├── SelectorConstants.java │ │ │ │ │ │ │ ├── SliderConstants.java │ │ │ │ │ │ │ └── TableConstants.java │ │ │ │ │ │ ├── selector/ │ │ │ │ │ │ │ ├── AbstractSelectorItemPresenter.java │ │ │ │ │ │ │ ├── SelectorDisplayer.java │ │ │ │ │ │ │ ├── SelectorDisplayerView.java │ │ │ │ │ │ │ ├── SelectorDropDownDisplayer.java │ │ │ │ │ │ │ ├── SelectorDropDownDisplayerView.css │ │ │ │ │ │ │ ├── SelectorDropDownDisplayerView.html │ │ │ │ │ │ │ ├── SelectorDropDownDisplayerView.java │ │ │ │ │ │ │ ├── SelectorDropDownItem.java │ │ │ │ │ │ │ ├── SelectorDropDownItemView.css │ │ │ │ │ │ │ ├── SelectorDropDownItemView.html │ │ │ │ │ │ │ ├── SelectorDropDownItemView.java │ │ │ │ │ │ │ ├── SelectorItemPresenter.java │ │ │ │ │ │ │ ├── SelectorItemView.java │ │ │ │ │ │ │ ├── SelectorLabelItem.java │ │ │ │ │ │ │ ├── SelectorLabelItemView.html │ │ │ │ │ │ │ ├── SelectorLabelItemView.java │ │ │ │ │ │ │ ├── SelectorLabelSetDisplayer.java │ │ │ │ │ │ │ ├── SelectorLabelSetDisplayerView.html │ │ │ │ │ │ │ ├── SelectorLabelSetDisplayerView.java │ │ │ │ │ │ │ ├── SelectorSliderDisplayer.java │ │ │ │ │ │ │ └── SelectorSliderDisplayerView.java │ │ │ │ │ │ └── table/ │ │ │ │ │ │ ├── TableDisplayer.java │ │ │ │ │ │ └── TableDisplayerView.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── renderer/ │ │ │ │ │ ├── DefaultRenderer.gwt.xml │ │ │ │ │ └── client/ │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── CommonConstants.properties │ │ │ │ │ ├── CommonConstants_de.properties │ │ │ │ │ ├── CommonConstants_es.properties │ │ │ │ │ ├── CommonConstants_fr.properties │ │ │ │ │ ├── CommonConstants_it.properties │ │ │ │ │ ├── CommonConstants_ja.properties │ │ │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ │ │ ├── CommonConstants_zh_CN.properties │ │ │ │ │ ├── MetricConstants.properties │ │ │ │ │ ├── MetricConstants_de.properties │ │ │ │ │ ├── MetricConstants_es.properties │ │ │ │ │ ├── MetricConstants_fr.properties │ │ │ │ │ ├── MetricConstants_it.properties │ │ │ │ │ ├── MetricConstants_ja.properties │ │ │ │ │ ├── MetricConstants_pt_BR.properties │ │ │ │ │ ├── MetricConstants_zh_CN.properties │ │ │ │ │ ├── SelectorConstants.properties │ │ │ │ │ ├── SelectorConstants_de.properties │ │ │ │ │ ├── SelectorConstants_es.properties │ │ │ │ │ ├── SelectorConstants_fr.properties │ │ │ │ │ ├── SelectorConstants_it.properties │ │ │ │ │ ├── SelectorConstants_ja.properties │ │ │ │ │ ├── SelectorConstants_pt_BR.properties │ │ │ │ │ ├── SelectorConstants_zh_CN.properties │ │ │ │ │ ├── SliderConstants.properties │ │ │ │ │ ├── SliderConstants_es.properties │ │ │ │ │ ├── SliderConstants_fr.properties │ │ │ │ │ ├── SliderConstants_it.properties │ │ │ │ │ ├── SliderConstants_ja.properties │ │ │ │ │ ├── TableConstants.properties │ │ │ │ │ ├── TableConstants_de.properties │ │ │ │ │ ├── TableConstants_es.properties │ │ │ │ │ ├── TableConstants_fr.properties │ │ │ │ │ ├── TableConstants_it.properties │ │ │ │ │ ├── TableConstants_ja.properties │ │ │ │ │ ├── TableConstants_pt_BR.properties │ │ │ │ │ └── TableConstants_zh_CN.properties │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── renderer/ │ │ │ │ └── client/ │ │ │ │ ├── external/ │ │ │ │ │ └── ExternalComponentDisplayerTest.java │ │ │ │ ├── metric/ │ │ │ │ │ └── MetricDisplayerTest.java │ │ │ │ ├── selector/ │ │ │ │ │ ├── SelectorCoordinatorTest.java │ │ │ │ │ ├── SelectorDisplayerTest.java │ │ │ │ │ ├── SelectorDropDownDisplayerTest.java │ │ │ │ │ ├── SelectorLabelSetDisplayerTest.java │ │ │ │ │ └── SelectorSliderDisplayerTest.java │ │ │ │ └── table/ │ │ │ │ ├── TableDisplayerTest.java │ │ │ │ └── TableDisplayerViewTest.java │ │ │ ├── dashbuilder-renderer-google/ │ │ │ │ ├── README.md │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ │ └── renderer/ │ │ │ │ │ │ └── google/ │ │ │ │ │ │ └── client/ │ │ │ │ │ │ ├── GoogleAreaChartDisplayer.java │ │ │ │ │ │ ├── GoogleAreaChartDisplayerView.java │ │ │ │ │ │ ├── GoogleBarChartDisplayer.java │ │ │ │ │ │ ├── GoogleBarChartDisplayerView.java │ │ │ │ │ │ ├── GoogleBubbleChartDisplayer.java │ │ │ │ │ │ ├── GoogleBubbleChartDisplayerView.java │ │ │ │ │ │ ├── GoogleCategoriesDisplayer.java │ │ │ │ │ │ ├── GoogleCategoriesDisplayerView.java │ │ │ │ │ │ ├── GoogleChartDisplayer.java │ │ │ │ │ │ ├── GoogleChartDisplayerView.java │ │ │ │ │ │ ├── GoogleDisplayer.java │ │ │ │ │ │ ├── GoogleDisplayerView.java │ │ │ │ │ │ ├── GoogleLegendWrapper.java │ │ │ │ │ │ ├── GoogleLineChartDisplayer.java │ │ │ │ │ │ ├── GoogleLineChartDisplayerView.java │ │ │ │ │ │ ├── GoogleMapDisplayer.java │ │ │ │ │ │ ├── GoogleMapDisplayerView.java │ │ │ │ │ │ ├── GoogleMeterChartDisplayer.java │ │ │ │ │ │ ├── GoogleMeterChartDisplayerView.java │ │ │ │ │ │ ├── GooglePieChartDisplayer.java │ │ │ │ │ │ ├── GooglePieChartDisplayerView.java │ │ │ │ │ │ ├── GoogleRenderer.java │ │ │ │ │ │ ├── GoogleTableDisplayer.java │ │ │ │ │ │ ├── GoogleTableDisplayerView.java │ │ │ │ │ │ ├── PieChartOptionsWrapper.java │ │ │ │ │ │ └── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ └── GoogleDisplayerConstants.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── renderer/ │ │ │ │ │ ├── GChartsRenderer.gwt.xml │ │ │ │ │ └── google/ │ │ │ │ │ └── client/ │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── GoogleDisplayerConstants.properties │ │ │ │ │ ├── GoogleDisplayerConstants_de.properties │ │ │ │ │ ├── GoogleDisplayerConstants_es.properties │ │ │ │ │ ├── GoogleDisplayerConstants_fr.properties │ │ │ │ │ ├── GoogleDisplayerConstants_it.properties │ │ │ │ │ ├── GoogleDisplayerConstants_ja.properties │ │ │ │ │ ├── GoogleDisplayerConstants_pt_BR.properties │ │ │ │ │ └── GoogleDisplayerConstants_zh_CN.properties │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── renderer/ │ │ │ │ └── google/ │ │ │ │ └── client/ │ │ │ │ ├── GoogleDisplayerDataTest.java │ │ │ │ ├── GoogleDisplayerDrawTest.java │ │ │ │ ├── GoogleDisplayerFilterTest.java │ │ │ │ ├── GoogleDisplayerTest.java │ │ │ │ └── GoogleTableDisplayerTest.java │ │ │ └── pom.xml │ │ ├── dashbuilder-widgets/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── client/ │ │ │ │ │ └── widgets/ │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── ClientRuntimeErrorPopupPresenter.java │ │ │ │ │ │ ├── DataSetEditorPlugin.java │ │ │ │ │ │ ├── LoadingBox.java │ │ │ │ │ │ └── LoadingBoxView.java │ │ │ │ │ ├── dataset/ │ │ │ │ │ │ ├── editor/ │ │ │ │ │ │ │ ├── DataSetDefColumnsFilterEditor.java │ │ │ │ │ │ │ ├── DataSetDefColumnsFilterEditorView.java │ │ │ │ │ │ │ ├── DataSetDefColumnsFilterEditorView.ui.xml │ │ │ │ │ │ │ ├── DataSetDefFilterEditor.java │ │ │ │ │ │ │ ├── DataSetDefFilterEditorView.java │ │ │ │ │ │ │ ├── DataSetDefFilterEditorView.ui.xml │ │ │ │ │ │ │ ├── DataSetDefPreviewTable.java │ │ │ │ │ │ │ ├── DataSetDefPreviewTableView.java │ │ │ │ │ │ │ ├── DataSetDefPreviewTableView.ui.xml │ │ │ │ │ │ │ ├── DataSetDefProviderTypeEditor.java │ │ │ │ │ │ │ ├── DataSetDefProviderTypeEditorView.java │ │ │ │ │ │ │ ├── DataSetDefProviderTypeEditorView.ui.xml │ │ │ │ │ │ │ ├── DataSetEditor.java │ │ │ │ │ │ │ ├── DataSetEditorView.java │ │ │ │ │ │ │ ├── DataSetEditorView.ui.xml │ │ │ │ │ │ │ ├── attributes/ │ │ │ │ │ │ │ │ ├── DataSetDefBackendCacheAttributesEditor.java │ │ │ │ │ │ │ │ ├── DataSetDefBasicAttributesEditor.java │ │ │ │ │ │ │ │ ├── DataSetDefBasicAttributesEditorView.java │ │ │ │ │ │ │ │ ├── DataSetDefBasicAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ ├── DataSetDefCacheAttributesEditorView.java │ │ │ │ │ │ │ │ ├── DataSetDefCacheAttributesEditorViewImpl.java │ │ │ │ │ │ │ │ ├── DataSetDefCacheAttributesEditorViewImpl.ui.xml │ │ │ │ │ │ │ │ ├── DataSetDefClientCacheAttributesEditor.java │ │ │ │ │ │ │ │ ├── DataSetDefRefreshAttributesEditor.java │ │ │ │ │ │ │ │ ├── DataSetDefRefreshAttributesEditorView.java │ │ │ │ │ │ │ │ ├── DataSetDefRefreshAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ ├── DataSetDefRefreshIntervalEditor.java │ │ │ │ │ │ │ │ ├── DataSetDefRefreshIntervalEditorView.java │ │ │ │ │ │ │ │ └── DataSetDefRefreshIntervalEditorView.ui.xml │ │ │ │ │ │ │ ├── bean/ │ │ │ │ │ │ │ │ ├── BeanDataSetDefAttributesEditor.java │ │ │ │ │ │ │ │ ├── BeanDataSetDefAttributesEditorView.java │ │ │ │ │ │ │ │ ├── BeanDataSetDefAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ └── BeanDataSetEditor.java │ │ │ │ │ │ │ ├── column/ │ │ │ │ │ │ │ │ ├── ColumnListEditor.java │ │ │ │ │ │ │ │ ├── ColumnListEditorView.java │ │ │ │ │ │ │ │ ├── ColumnListEditorView.ui.xml │ │ │ │ │ │ │ │ ├── ColumnTypeEditor.java │ │ │ │ │ │ │ │ ├── DataColumnDefEditor.java │ │ │ │ │ │ │ │ ├── DataColumnDefEditorView.java │ │ │ │ │ │ │ │ ├── DataColumnDefEditorView.ui.xml │ │ │ │ │ │ │ │ └── DataSetDefColumnsEditor.java │ │ │ │ │ │ │ ├── csv/ │ │ │ │ │ │ │ │ ├── CSVDataSetDefAttributesEditor.java │ │ │ │ │ │ │ │ ├── CSVDataSetDefAttributesEditorView.java │ │ │ │ │ │ │ │ ├── CSVDataSetDefAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ └── CSVDataSetEditor.java │ │ │ │ │ │ │ ├── driver/ │ │ │ │ │ │ │ │ ├── BeanDataSetDefAttributesDriver.java │ │ │ │ │ │ │ │ ├── BeanDataSetDefDriver.java │ │ │ │ │ │ │ │ ├── CSVDataSetDefAttributesDriver.java │ │ │ │ │ │ │ │ ├── CSVDataSetDefDriver.java │ │ │ │ │ │ │ │ ├── DataColumnDefDriver.java │ │ │ │ │ │ │ │ ├── DataSetDefBasicAttributesDriver.java │ │ │ │ │ │ │ │ ├── DataSetDefProviderTypeDriver.java │ │ │ │ │ │ │ │ ├── DataSetEditorDriverFactory.java │ │ │ │ │ │ │ │ ├── KafkaDataSetDefAttributesDriver.java │ │ │ │ │ │ │ │ ├── KafkaDataSetDefDriver.java │ │ │ │ │ │ │ │ ├── PrometheusDataSetDefAttributesDriver.java │ │ │ │ │ │ │ │ ├── PrometheusDataSetDefDriver.java │ │ │ │ │ │ │ │ ├── SQLDataSetDefAttributesDriver.java │ │ │ │ │ │ │ │ └── SQLDataSetDefDriver.java │ │ │ │ │ │ │ ├── kafka/ │ │ │ │ │ │ │ │ ├── KafkaDataSetDefAttributesEditor.java │ │ │ │ │ │ │ │ ├── KafkaDataSetDefAttributesEditorView.java │ │ │ │ │ │ │ │ ├── KafkaDataSetDefAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ ├── KafkaDataSetEditor.java │ │ │ │ │ │ │ │ └── MetricsTargetEditorAdapter.java │ │ │ │ │ │ │ ├── prometheus/ │ │ │ │ │ │ │ │ ├── PrometheusDataSetDefAttributesEditor.java │ │ │ │ │ │ │ │ ├── PrometheusDataSetDefAttributesEditorView.java │ │ │ │ │ │ │ │ ├── PrometheusDataSetDefAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ └── PrometheusDataSetEditor.java │ │ │ │ │ │ │ ├── sql/ │ │ │ │ │ │ │ │ ├── SQLDataSetDefAttributesEditor.java │ │ │ │ │ │ │ │ ├── SQLDataSetDefAttributesEditorView.java │ │ │ │ │ │ │ │ ├── SQLDataSetDefAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ └── SQLDataSetEditor.java │ │ │ │ │ │ │ └── workflow/ │ │ │ │ │ │ │ ├── DataSetEditorWorkflow.java │ │ │ │ │ │ │ ├── DataSetEditorWorkflowFactory.java │ │ │ │ │ │ │ ├── DataSetEditorWorkflowView.java │ │ │ │ │ │ │ ├── DataSetEditorWorkflowView.ui.xml │ │ │ │ │ │ │ ├── create/ │ │ │ │ │ │ │ │ ├── BeanDataSetBasicAttributesWorkflow.java │ │ │ │ │ │ │ │ ├── CSVDataSetBasicAttributesWorkflow.java │ │ │ │ │ │ │ │ ├── DataSetBasicAttributesWorkflow.java │ │ │ │ │ │ │ │ ├── DataSetProviderTypeWorkflow.java │ │ │ │ │ │ │ │ ├── KafkaDataSetBasicAttributesWorkflow.java │ │ │ │ │ │ │ │ ├── PrometheusDataSetBasicAttributesWorkflow.java │ │ │ │ │ │ │ │ └── SQLDataSetBasicAttributesWorkflow.java │ │ │ │ │ │ │ └── edit/ │ │ │ │ │ │ │ ├── BeanDataSetEditWorkflow.java │ │ │ │ │ │ │ ├── CSVDataSetEditWorkflow.java │ │ │ │ │ │ │ ├── DataSetEditWorkflow.java │ │ │ │ │ │ │ ├── KafkaDataSetEditWorkflow.java │ │ │ │ │ │ │ ├── PrometheusDataSetEditWorkflow.java │ │ │ │ │ │ │ └── SQLDataSetEditWorkflow.java │ │ │ │ │ │ ├── event/ │ │ │ │ │ │ │ ├── CancelRequestEvent.java │ │ │ │ │ │ │ ├── ColumnsChangedEvent.java │ │ │ │ │ │ │ ├── DataSetDefCreationRequestEvent.java │ │ │ │ │ │ │ ├── EditDataSetEvent.java │ │ │ │ │ │ │ ├── ErrorEvent.java │ │ │ │ │ │ │ ├── FilterChangedEvent.java │ │ │ │ │ │ │ ├── SaveRequestEvent.java │ │ │ │ │ │ │ ├── TabChangedEvent.java │ │ │ │ │ │ │ └── TestDataSetRequestEvent.java │ │ │ │ │ │ └── explorer/ │ │ │ │ │ │ ├── DataSetExplorer.java │ │ │ │ │ │ ├── DataSetExplorerView.java │ │ │ │ │ │ ├── DataSetExplorerView.ui.xml │ │ │ │ │ │ ├── DataSetPanel.java │ │ │ │ │ │ ├── DataSetPanelView.java │ │ │ │ │ │ ├── DataSetPanelView.ui.xml │ │ │ │ │ │ ├── DataSetSummary.java │ │ │ │ │ │ ├── DataSetSummaryView.java │ │ │ │ │ │ └── DataSetSummaryView.ui.xml │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── DataSetEditorConstants.java │ │ │ │ │ └── DataSetExplorerConstants.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── CommonWidgets.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── widgets/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── DataSetEditorConstants.properties │ │ │ │ ├── DataSetEditorConstants_de.properties │ │ │ │ ├── DataSetEditorConstants_es.properties │ │ │ │ ├── DataSetEditorConstants_fr.properties │ │ │ │ ├── DataSetEditorConstants_it.properties │ │ │ │ ├── DataSetEditorConstants_ja.properties │ │ │ │ ├── DataSetEditorConstants_pt_BR.properties │ │ │ │ ├── DataSetEditorConstants_zh_CN.properties │ │ │ │ ├── DataSetExplorerConstants.properties │ │ │ │ ├── DataSetExplorerConstants_de.properties │ │ │ │ ├── DataSetExplorerConstants_es.properties │ │ │ │ ├── DataSetExplorerConstants_fr.properties │ │ │ │ ├── DataSetExplorerConstants_it.properties │ │ │ │ ├── DataSetExplorerConstants_ja.properties │ │ │ │ ├── DataSetExplorerConstants_pt_BR.properties │ │ │ │ └── DataSetExplorerConstants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── client/ │ │ │ └── widgets/ │ │ │ ├── common/ │ │ │ │ ├── ClientRuntimeErrorPopupPresenterTest.java │ │ │ │ ├── CustomDataSetProviderType.java │ │ │ │ └── LoadingBoxTest.java │ │ │ └── dataset/ │ │ │ ├── editor/ │ │ │ │ ├── DataSetDefColumnsFilterEditorTest.java │ │ │ │ ├── DataSetDefFilterEditorTest.java │ │ │ │ ├── DataSetDefPreviewTableTest.java │ │ │ │ ├── DataSetDefProviderTypeEditorTest.java │ │ │ │ ├── DataSetEditorTest.java │ │ │ │ ├── attributes/ │ │ │ │ │ ├── DataSetDefBackendCacheAttributesEditorTest.java │ │ │ │ │ ├── DataSetDefBasicAttributesEditorTest.java │ │ │ │ │ ├── DataSetDefClientCacheAttributesEditorTest.java │ │ │ │ │ ├── DataSetDefRefreshAttributesEditorTest.java │ │ │ │ │ └── DataSetDefRefreshIntervalEditorTest.java │ │ │ │ ├── bean/ │ │ │ │ │ ├── BeanDataSetDefAttributesEditorTest.java │ │ │ │ │ └── BeanDataSetEditorTest.java │ │ │ │ ├── column/ │ │ │ │ │ ├── ColumnListEditorTest.java │ │ │ │ │ ├── ColumnTypeEditorTest.java │ │ │ │ │ ├── DataColumnDefEditorTest.java │ │ │ │ │ └── DataSetDefColumnsEditorTest.java │ │ │ │ ├── csv/ │ │ │ │ │ ├── CSVDataSetDefAttributesEditorTest.java │ │ │ │ │ └── CSVDataSetEditorTest.java │ │ │ │ ├── sql/ │ │ │ │ │ ├── SQLDataSetDefAttributesEditorTest.java │ │ │ │ │ └── SQLDataSetEditorTest.java │ │ │ │ └── workflow/ │ │ │ │ ├── AbstractDataSetWorkflowTest.java │ │ │ │ ├── DataSetEditorWorkflowTest.java │ │ │ │ ├── create/ │ │ │ │ │ ├── BeanDataSetBasicAttributesWorkflowTest.java │ │ │ │ │ ├── CSVDataSetBasicAttributesWorkflowTest.java │ │ │ │ │ ├── DataSetBasicAttributesWorkflowTest.java │ │ │ │ │ ├── DataSetProviderTypeWorkflowTest.java │ │ │ │ │ └── SQLDataSetBasicAttributesWorkflowTest.java │ │ │ │ └── edit/ │ │ │ │ ├── BeanDataSetEditWorkflowTest.java │ │ │ │ ├── CSVDataSetEditWorkflowTest.java │ │ │ │ ├── DataSetEditWorkflowTest.java │ │ │ │ └── SQLDataSetEditWorkflowTest.java │ │ │ └── explorer/ │ │ │ ├── DataSetExplorerTest.java │ │ │ ├── DataSetPanelTest.java │ │ │ └── DataSetSummaryTest.java │ │ └── pom.xml │ ├── dashbuilder-distros/ │ │ ├── README.md │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── assembly/ │ │ │ └── assembly-wildfly-10.xml │ │ └── wildfly10/ │ │ ├── README.md │ │ └── WEB-INF/ │ │ ├── beans.xml │ │ └── jboss-web.xml │ ├── dashbuilder-packaging/ │ │ ├── dashbuilder-all/ │ │ │ └── pom.xml │ │ ├── dashbuilder-client-all/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── DashbuilderClientAll.gwt.xml │ │ ├── dashbuilder-server-all/ │ │ │ └── pom.xml │ │ └── pom.xml │ ├── dashbuilder-runtime/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── backend/ │ │ │ │ │ ├── DataSetContentListener.java │ │ │ │ │ ├── ExternalComponentsContentListener.java │ │ │ │ │ ├── RuntimeModelListener.java │ │ │ │ │ ├── RuntimeModelLoader.java │ │ │ │ │ ├── RuntimeModelWatcherServiceManager.java │ │ │ │ │ ├── RuntimeOptions.java │ │ │ │ │ ├── ServerSideProducers.java │ │ │ │ │ ├── gzip/ │ │ │ │ │ │ ├── GzipFilter.java │ │ │ │ │ │ ├── GzipHttpServerResponseWrapper.java │ │ │ │ │ │ └── GzipOutputStream.java │ │ │ │ │ ├── health/ │ │ │ │ │ │ └── HealthService.java │ │ │ │ │ ├── helper/ │ │ │ │ │ │ └── PartitionHelper.java │ │ │ │ │ ├── navigation/ │ │ │ │ │ │ └── RuntimeNavigationBuilder.java │ │ │ │ │ ├── remote/ │ │ │ │ │ │ └── services/ │ │ │ │ │ │ ├── RuntimeModelServiceImpl.java │ │ │ │ │ │ ├── dataset/ │ │ │ │ │ │ │ └── RuntimeDataSetLookupServices.java │ │ │ │ │ │ └── dummy/ │ │ │ │ │ │ ├── DummyBackendExperimentalFeatureDefRegistry.java │ │ │ │ │ │ ├── DummyBackendExperimentalFeaturesRegistryService.java │ │ │ │ │ │ ├── DummyPerspectiveServices.java │ │ │ │ │ │ ├── DummyPluginServices.java │ │ │ │ │ │ ├── DummyRendererSettingsService.java │ │ │ │ │ │ └── DummyRuntimePluginService.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ ├── FileUploadModel.java │ │ │ │ │ │ ├── RuntimeJaxApp.java │ │ │ │ │ │ ├── UploadResourceImpl.java │ │ │ │ │ │ └── api/ │ │ │ │ │ │ └── DashbuilderRuntimeResource.java │ │ │ │ │ ├── security/ │ │ │ │ │ │ ├── BasicAuthSecurityFilter.java │ │ │ │ │ │ └── LoginRedirectServlet.java │ │ │ │ │ └── services/ │ │ │ │ │ ├── RuntimeInfoService.java │ │ │ │ │ ├── dataset/ │ │ │ │ │ │ ├── DataSetServicesProducer.java │ │ │ │ │ │ ├── RuntimeCSVFileStorage.java │ │ │ │ │ │ └── provider/ │ │ │ │ │ │ ├── RuntimeBeanDataSetProvider.java │ │ │ │ │ │ ├── RuntimeDataSetProviderRegistry.java │ │ │ │ │ │ └── RuntimeSQLDataSourceLocator.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── ExternalImportServiceImpl.java │ │ │ │ │ ├── ImportValidationServiceImpl.java │ │ │ │ │ ├── RuntimeInfoServiceImpl.java │ │ │ │ │ ├── RuntimeModelParserImpl.java │ │ │ │ │ └── RuntimeModelRegistryImpl.java │ │ │ │ ├── client/ │ │ │ │ │ ├── RuntimeClientLoader.java │ │ │ │ │ ├── RuntimeCommunication.java │ │ │ │ │ ├── RuntimeEntryPoint.java │ │ │ │ │ ├── error/ │ │ │ │ │ │ └── DefaultRuntimeErrorCallback.java │ │ │ │ │ ├── navbar/ │ │ │ │ │ │ ├── AppNavBar.html │ │ │ │ │ │ ├── AppNavBar.java │ │ │ │ │ │ ├── DashboardListMenuBuilder.java │ │ │ │ │ │ ├── GoToDashboardMenuBuilder.java │ │ │ │ │ │ ├── LogoutMenuBuilder.java │ │ │ │ │ │ ├── MenuBuilderHelper.java │ │ │ │ │ │ ├── NavBarHelper.java │ │ │ │ │ │ └── RuntimeNavBrand.java │ │ │ │ │ ├── perspective/ │ │ │ │ │ │ ├── DashboardsListPerspective.java │ │ │ │ │ │ ├── EmptyPerspective.java │ │ │ │ │ │ ├── NotFoundPerspective.java │ │ │ │ │ │ ├── RouterPerspective.java │ │ │ │ │ │ ├── RuntimePerspective.java │ │ │ │ │ │ └── generator/ │ │ │ │ │ │ ├── RuntimePerspectiveEditorActivity.java │ │ │ │ │ │ └── RuntimePerspectiveGenerator.java │ │ │ │ │ ├── plugins/ │ │ │ │ │ │ └── RuntimePerspectivePluginManager.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ └── AppConstants.java │ │ │ │ │ ├── screens/ │ │ │ │ │ │ ├── DashboardsListScreen.java │ │ │ │ │ │ ├── EmptyScreen.java │ │ │ │ │ │ ├── NotFoundScreen.java │ │ │ │ │ │ ├── RouterScreen.java │ │ │ │ │ │ ├── RuntimeScreen.java │ │ │ │ │ │ └── view/ │ │ │ │ │ │ ├── DashboardsListScreenView.css │ │ │ │ │ │ ├── DashboardsListScreenView.html │ │ │ │ │ │ ├── DashboardsListScreenView.java │ │ │ │ │ │ ├── EmptyScreenView.css │ │ │ │ │ │ ├── EmptyScreenView.html │ │ │ │ │ │ ├── EmptyScreenView.java │ │ │ │ │ │ ├── NotFoundScreenView.html │ │ │ │ │ │ ├── NotFoundScreenView.java │ │ │ │ │ │ ├── RouterScreenView.html │ │ │ │ │ │ ├── RouterScreenView.java │ │ │ │ │ │ ├── RuntimeScreenView.html │ │ │ │ │ │ ├── RuntimeScreenView.java │ │ │ │ │ │ └── RuntimeScreenView.less │ │ │ │ │ └── widgets/ │ │ │ │ │ ├── DashboardCard.java │ │ │ │ │ ├── UploadWidget.java │ │ │ │ │ └── view/ │ │ │ │ │ ├── DashboardCardView.html │ │ │ │ │ ├── DashboardCardView.java │ │ │ │ │ ├── UploadWidgetView.html │ │ │ │ │ └── UploadWidgetView.java │ │ │ │ └── shared/ │ │ │ │ ├── event/ │ │ │ │ │ ├── NewDataSetContentEvent.java │ │ │ │ │ ├── RemovedRuntimeModelEvent.java │ │ │ │ │ └── UpdatedRuntimeModelEvent.java │ │ │ │ ├── model/ │ │ │ │ │ ├── DashboardInfo.java │ │ │ │ │ ├── DashbuilderRuntimeInfo.java │ │ │ │ │ ├── DashbuilderRuntimeMode.java │ │ │ │ │ ├── DataSetContent.java │ │ │ │ │ ├── DataSetContentType.java │ │ │ │ │ ├── ImportDefinitions.java │ │ │ │ │ ├── RuntimeModel.java │ │ │ │ │ └── RuntimeServiceResponse.java │ │ │ │ ├── service/ │ │ │ │ │ ├── ImportValidationService.java │ │ │ │ │ ├── RuntimeModelParser.java │ │ │ │ │ ├── RuntimeModelRegistry.java │ │ │ │ │ └── RuntimeModelService.java │ │ │ │ └── services/ │ │ │ │ └── ExternalImportService.java │ │ │ ├── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── ErraiApp.properties │ │ │ │ ├── application-roles.properties │ │ │ │ ├── application-users.properties │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── DashbuilderRuntime.gwt.xml │ │ │ │ ├── FastCompiledDashbuilderRuntime.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── AppConstants.properties │ │ │ │ ├── AppConstants_es.properties │ │ │ │ ├── AppConstants_fr.properties │ │ │ │ ├── AppConstants_it.properties │ │ │ │ └── AppConstants_ja.properties │ │ │ └── webapp/ │ │ │ ├── WEB-INF/ │ │ │ │ ├── .gitignore │ │ │ │ ├── beans.xml │ │ │ │ ├── jboss-deployment-structure.xml │ │ │ │ ├── jboss-web.xml │ │ │ │ └── web.xml │ │ │ ├── banner/ │ │ │ │ └── banner.html │ │ │ ├── dashbuilder.html │ │ │ ├── login.html │ │ │ ├── logout.jsp │ │ │ └── not_authorized.jsp │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ ├── backend/ │ │ │ │ ├── DataSetContentListenerTest.java │ │ │ │ ├── RuntimeModelLoaderTest.java │ │ │ │ ├── helper/ │ │ │ │ │ └── PartitionHelperTest.java │ │ │ │ ├── navigation/ │ │ │ │ │ └── RuntimeNavigationBuilderTest.java │ │ │ │ └── services/ │ │ │ │ └── impl/ │ │ │ │ ├── ImportValidationServiceImplTest.java │ │ │ │ ├── RuntimeInfoServiceImplTest.java │ │ │ │ ├── RuntimeModelParserImplTest.java │ │ │ │ └── RuntimeModelRegistryImplTest.java │ │ │ ├── client/ │ │ │ │ ├── ClientRuntimeModelLoaderTest.java │ │ │ │ ├── error/ │ │ │ │ │ └── DefaultRuntimeErrorCallbackTest.java │ │ │ │ └── screens/ │ │ │ │ ├── RouterScreenTest.java │ │ │ │ └── RuntimeScreenTest.java │ │ │ └── shared/ │ │ │ └── service/ │ │ │ └── RuntimeModelRegistryTest.java │ │ └── resources/ │ │ ├── ds.csv │ │ └── ds.dset │ ├── dashbuilder-shared/ │ │ ├── dashbuilder-displayer-api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ ├── displayer/ │ │ │ │ │ │ ├── AreaChartSettingsBuilder.java │ │ │ │ │ │ ├── BarChartSettingsBuilder.java │ │ │ │ │ │ ├── BubbleChartSettingsBuilder.java │ │ │ │ │ │ ├── ChartSettingsBuilder.java │ │ │ │ │ │ ├── ColumnSettings.java │ │ │ │ │ │ ├── DisplayerAttributeDef.java │ │ │ │ │ │ ├── DisplayerAttributeGroupDef.java │ │ │ │ │ │ ├── DisplayerConstraints.java │ │ │ │ │ │ ├── DisplayerSettings.java │ │ │ │ │ │ ├── DisplayerSettingsBuilder.java │ │ │ │ │ │ ├── DisplayerSettingsFactory.java │ │ │ │ │ │ ├── DisplayerSubType.java │ │ │ │ │ │ ├── DisplayerType.java │ │ │ │ │ │ ├── ExternalDisplayerSettingsBuilder.java │ │ │ │ │ │ ├── LineChartSettingsBuilder.java │ │ │ │ │ │ ├── MapChartSettingsBuilder.java │ │ │ │ │ │ ├── MapColorScheme.java │ │ │ │ │ │ ├── MeterChartSettingsBuilder.java │ │ │ │ │ │ ├── MetricSettingsBuilder.java │ │ │ │ │ │ ├── PieChartSettingsBuilder.java │ │ │ │ │ │ ├── Position.java │ │ │ │ │ │ ├── SelectorDisplayerSettingsBuilder.java │ │ │ │ │ │ ├── TableDisplayerSettingsBuilder.java │ │ │ │ │ │ ├── XAxisChartSettingsBuilder.java │ │ │ │ │ │ ├── external/ │ │ │ │ │ │ │ ├── ExternalColumn.java │ │ │ │ │ │ │ ├── ExternalColumnSettings.java │ │ │ │ │ │ │ ├── ExternalComponentFunction.java │ │ │ │ │ │ │ ├── ExternalComponentMessage.java │ │ │ │ │ │ │ ├── ExternalComponentMessageHelper.java │ │ │ │ │ │ │ ├── ExternalComponentMessageType.java │ │ │ │ │ │ │ ├── ExternalDataSet.java │ │ │ │ │ │ │ ├── ExternalFilterRequest.java │ │ │ │ │ │ │ ├── FunctionCallRequest.java │ │ │ │ │ │ │ ├── FunctionResponse.java │ │ │ │ │ │ │ └── FunctionResultType.java │ │ │ │ │ │ ├── impl/ │ │ │ │ │ │ │ ├── AbstractChartSettingsBuilder.java │ │ │ │ │ │ │ ├── AbstractDisplayerSettingsBuilder.java │ │ │ │ │ │ │ ├── AbstractSelectorSettingsBuilder.java │ │ │ │ │ │ │ ├── AbstractXAxisChartSettingsBuilder.java │ │ │ │ │ │ │ ├── AreaChartSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── BarChartSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── BubbleChartSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── ExternalDisplayerSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── LineChartSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── MapChartSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── MeterChartSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── MetricSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── PieChartSettingsBuilderImpl.java │ │ │ │ │ │ │ ├── SelectorDisplayerSettingsBuilderImpl.java │ │ │ │ │ │ │ └── TableDisplayerSettingsBuilderImpl.java │ │ │ │ │ │ └── json/ │ │ │ │ │ │ └── DisplayerSettingsJSONMarshaller.java │ │ │ │ │ └── renderer/ │ │ │ │ │ └── RendererSettings.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── ErraiApp.properties │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── DisplayerAPI.gwt.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── displayer/ │ │ │ ├── external/ │ │ │ │ └── ExternalComponentMessageHelperTest.java │ │ │ └── json/ │ │ │ └── DisplayerSettingsJsonTest.java │ │ ├── dashbuilder-dsl/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── dsl/ │ │ │ │ ├── factory/ │ │ │ │ │ ├── component/ │ │ │ │ │ │ ├── AbstractComponentBuilder.java │ │ │ │ │ │ ├── AllProcessesHeatmapBuilder.java │ │ │ │ │ │ ├── ComponentFactory.java │ │ │ │ │ │ ├── DisplayerBuilder.java │ │ │ │ │ │ ├── ExternalComponentBuilder.java │ │ │ │ │ │ ├── ExternalDisplayerBuilder.java │ │ │ │ │ │ ├── HtmlComponentBuilder.java │ │ │ │ │ │ ├── LogoBuilder.java │ │ │ │ │ │ └── ProcessHeatmapBuilder.java │ │ │ │ │ ├── dashboard/ │ │ │ │ │ │ ├── DashboardBuilder.java │ │ │ │ │ │ └── DashboardFactory.java │ │ │ │ │ ├── navigation/ │ │ │ │ │ │ ├── NavigationBuilder.java │ │ │ │ │ │ ├── NavigationFactory.java │ │ │ │ │ │ ├── NavigationGroupBuilder.java │ │ │ │ │ │ └── NavigationItemBuilder.java │ │ │ │ │ └── page/ │ │ │ │ │ ├── AbstractLayoutBuilder.java │ │ │ │ │ ├── ColumnBuilder.java │ │ │ │ │ ├── PageBuilder.java │ │ │ │ │ ├── PageFactory.java │ │ │ │ │ └── RowBuilder.java │ │ │ │ ├── helper/ │ │ │ │ │ └── ComponentsHelper.java │ │ │ │ ├── model/ │ │ │ │ │ ├── Column.java │ │ │ │ │ ├── Component.java │ │ │ │ │ ├── Dashboard.java │ │ │ │ │ ├── Navigation.java │ │ │ │ │ ├── NavigationGroup.java │ │ │ │ │ ├── NavigationItem.java │ │ │ │ │ ├── Page.java │ │ │ │ │ └── Row.java │ │ │ │ ├── serialization/ │ │ │ │ │ ├── DashboardExporter.java │ │ │ │ │ ├── DashboardSerializer.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── DashboardZipSerializer.java │ │ │ │ │ └── InternalDataSetProviderRegistry.java │ │ │ │ └── validation/ │ │ │ │ ├── DashboardValidator.java │ │ │ │ ├── DashboardValidatorImpl.java │ │ │ │ └── ValidationResult.java │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── dsl/ │ │ │ │ ├── factory/ │ │ │ │ │ ├── component/ │ │ │ │ │ │ ├── ComponentFactoryTest.java │ │ │ │ │ │ └── DisplayerBuilderTest.java │ │ │ │ │ └── page/ │ │ │ │ │ ├── ComponentBuilderTest.java │ │ │ │ │ ├── PageBuilderTest.java │ │ │ │ │ └── RowBuilderTest.java │ │ │ │ ├── serialization/ │ │ │ │ │ ├── DashboardExporterTest.java │ │ │ │ │ └── impl/ │ │ │ │ │ └── DashboardZipSerializerTest.java │ │ │ │ └── validation/ │ │ │ │ └── DashboardValidatorImplTest.java │ │ │ └── resources/ │ │ │ ├── components/ │ │ │ │ └── comp1/ │ │ │ │ ├── index.html │ │ │ │ ├── index.js │ │ │ │ └── manifest.json │ │ │ └── data/ │ │ │ └── un_world_pop_medium_variant.csv │ │ ├── dashbuilder-js/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── packages/ │ │ │ │ ├── component-api/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── ComponentApi.ts │ │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ │ └── api.test.ts │ │ │ │ │ │ ├── controller/ │ │ │ │ │ │ │ ├── BrowserComponentBus.ts │ │ │ │ │ │ │ ├── ComponentBus.ts │ │ │ │ │ │ │ ├── ComponentController.ts │ │ │ │ │ │ │ ├── DashbuilderComponentController.ts │ │ │ │ │ │ │ ├── DashbuilderComponentDispatcher.ts │ │ │ │ │ │ │ ├── InternalComponentListener.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── dataset/ │ │ │ │ │ │ │ ├── Column.ts │ │ │ │ │ │ │ ├── ColumnSettings.ts │ │ │ │ │ │ │ ├── ColumnType.ts │ │ │ │ │ │ │ ├── DataSet.ts │ │ │ │ │ │ │ ├── FilterRequest.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── function/ │ │ │ │ │ │ │ ├── FunctionCallRequest.ts │ │ │ │ │ │ │ ├── FunctionResponse.ts │ │ │ │ │ │ │ ├── FunctionResultType.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── message/ │ │ │ │ │ │ ├── ComponentMessage.ts │ │ │ │ │ │ ├── MessageProperty.ts │ │ │ │ │ │ ├── MessageType.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ ├── component-dev/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── ComponentDevPane.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ ├── heatmap-base/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── SvgHeatmap.tsx │ │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ │ └── svgHeatmap.test.disabled │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ ├── heatmap-component/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── SVGHeatmapComponent.tsx │ │ │ │ │ │ ├── index-dev.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── static/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── manifest.dev.json │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ ├── logo-component/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── Logo.tsx │ │ │ │ │ │ ├── LogoComponent.tsx │ │ │ │ │ │ ├── index-dev.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── static/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── manifest.dev.json │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ ├── process-heatmap-component/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── ProcessHeatmapComponent.tsx │ │ │ │ │ │ ├── index-dev.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── static/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── manifest.dev.json │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ ├── processes-heatmaps-component/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── ProcessSelector.tsx │ │ │ │ │ │ ├── ProcessesHeatmapsComponent.tsx │ │ │ │ │ │ ├── index-dev.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── static/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── manifest.dev.json │ │ │ │ │ │ ├── manifest.json │ │ │ │ │ │ └── style.css │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ ├── runtime-client/ │ │ │ │ │ ├── jest.config.js │ │ │ │ │ ├── package.json │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── DashbuilderService.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── tsconfig.json │ │ │ │ │ └── webpack.config.js │ │ │ │ └── time-series-component/ │ │ │ │ ├── .gitignore │ │ │ │ ├── jest.config.js │ │ │ │ ├── package.json │ │ │ │ ├── src/ │ │ │ │ │ ├── Chart.tsx │ │ │ │ │ ├── Data.tsx │ │ │ │ │ ├── LineChart.tsx │ │ │ │ │ ├── SampleData.tsx │ │ │ │ │ ├── index-dev.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── tests/ │ │ │ │ │ ├── Chart.test.tsx │ │ │ │ │ ├── LineChart.test.tsx │ │ │ │ │ └── __snapshots__/ │ │ │ │ │ ├── Chart.test.tsx.snap │ │ │ │ │ └── LineChart.test.tsx.snap │ │ │ │ ├── static/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── manifest.dev.json │ │ │ │ │ └── manifest.json │ │ │ │ ├── tsconfig.json │ │ │ │ └── webpack.config.js │ │ │ ├── pom.xml │ │ │ ├── prettier.config.js │ │ │ ├── src/ │ │ │ │ ├── main/ │ │ │ │ │ └── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── components/ │ │ │ │ │ └── internal/ │ │ │ │ │ └── ProvidedComponentInfo.java │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── components/ │ │ │ │ │ └── internal/ │ │ │ │ │ └── InternalComponentsInfoTest.java │ │ │ │ └── resources/ │ │ │ │ └── dashbuilder-components.properties │ │ │ ├── tsconfig.json │ │ │ ├── tslint.json │ │ │ └── webpack.common.config.js │ │ ├── dashbuilder-kie-server-api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── kieserver/ │ │ │ │ ├── ConsoleDataSetLookup.java │ │ │ │ ├── KieServerConnectionInfo.java │ │ │ │ ├── KieServerConnectionInfoProvider.java │ │ │ │ ├── RemoteDataSetDef.java │ │ │ │ ├── RemoteDataSetDefValidation.java │ │ │ │ ├── RemoteDefJSONMarshaller.java │ │ │ │ └── RuntimeKieServerDataSetProviderType.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── DashbuilderKieServerAPI.gwt.xml │ │ ├── dashbuilder-navigation-api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── navigation/ │ │ │ │ │ ├── NavDivider.java │ │ │ │ │ ├── NavFactory.java │ │ │ │ │ ├── NavGroup.java │ │ │ │ │ ├── NavItem.java │ │ │ │ │ ├── NavItemContext.java │ │ │ │ │ ├── NavItemVisitor.java │ │ │ │ │ ├── NavTree.java │ │ │ │ │ ├── event/ │ │ │ │ │ │ ├── NavTreeChangedEvent.java │ │ │ │ │ │ └── PerspectivePluginsChangedEvent.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── NavDividerImpl.java │ │ │ │ │ │ ├── NavFactoryImpl.java │ │ │ │ │ │ ├── NavGroupImpl.java │ │ │ │ │ │ ├── NavItemContextImpl.java │ │ │ │ │ │ ├── NavItemImpl.java │ │ │ │ │ │ ├── NavTreeBuilder.java │ │ │ │ │ │ └── NavTreeImpl.java │ │ │ │ │ ├── json/ │ │ │ │ │ │ └── NavTreeJSONMarshaller.java │ │ │ │ │ ├── layout/ │ │ │ │ │ │ ├── LayoutNavigationRef.java │ │ │ │ │ │ ├── LayoutNavigationRefType.java │ │ │ │ │ │ ├── LayoutRecursionIssue.java │ │ │ │ │ │ ├── LayoutRecursionIssueI18n.java │ │ │ │ │ │ ├── LayoutTemplateContext.java │ │ │ │ │ │ ├── LayoutTemplateInfo.java │ │ │ │ │ │ ├── NavDragComponentSettings.java │ │ │ │ │ │ └── NavDragComponentType.java │ │ │ │ │ ├── service/ │ │ │ │ │ │ ├── NavigationServices.java │ │ │ │ │ │ └── PerspectivePluginServices.java │ │ │ │ │ └── workbench/ │ │ │ │ │ ├── NavSecurityController.java │ │ │ │ │ └── NavWorkbenchCtx.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── ErraiApp.properties │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── NavigationAPI.gwt.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── navigation/ │ │ │ ├── NavItemContextInclusionTest.java │ │ │ ├── NavItemContextTest.java │ │ │ ├── NavSecurityTest.java │ │ │ ├── NavTreeJsonTest.java │ │ │ └── NavTreeTest.java │ │ ├── dashbuilder-services-api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── dataset/ │ │ │ │ │ └── service/ │ │ │ │ │ ├── DataSetDefServices.java │ │ │ │ │ ├── DataSetDefVfsServices.java │ │ │ │ │ ├── DataSetExportServices.java │ │ │ │ │ ├── DataSetLookupServices.java │ │ │ │ │ └── SQLProviderServices.java │ │ │ │ ├── external/ │ │ │ │ │ ├── model/ │ │ │ │ │ │ ├── ComponentParameter.java │ │ │ │ │ │ └── ExternalComponent.java │ │ │ │ │ └── service/ │ │ │ │ │ ├── BackendComponentFunctionService.java │ │ │ │ │ ├── ComponentAssetProvider.java │ │ │ │ │ ├── ComponentLoader.java │ │ │ │ │ └── ComponentService.java │ │ │ │ ├── perspectives/ │ │ │ │ │ └── PerspectiveIds.java │ │ │ │ ├── renderer/ │ │ │ │ │ └── service/ │ │ │ │ │ └── RendererSettingsService.java │ │ │ │ └── transfer/ │ │ │ │ ├── DataTransferExportModel.java │ │ │ │ ├── DataTransferServices.java │ │ │ │ ├── ExportInfo.java │ │ │ │ └── ExportModelValidationService.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── ServicesAPI.gwt.xml │ │ ├── dashbuilder-validations/ │ │ │ ├── README.md │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ └── validations/ │ │ │ │ │ ├── DataSetDefValidator.java │ │ │ │ │ ├── DataSetValidatorProvider.java │ │ │ │ │ └── dataset/ │ │ │ │ │ ├── AbstractDataSetDefValidator.java │ │ │ │ │ ├── BeanDataSetDefValidator.java │ │ │ │ │ ├── CSVDataSetDefValidator.java │ │ │ │ │ ├── KafkaDataSetDefValidator.java │ │ │ │ │ ├── PrometheusDataSetDefValidator.java │ │ │ │ │ └── SQLDataSetDefValidator.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ └── CommonValidations.gwt.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── validations/ │ │ │ └── dataset/ │ │ │ ├── AbstractValidationTest.java │ │ │ ├── BeanDataSetDefValidatorTest.java │ │ │ ├── CSVDataSetDefValidatorTest.java │ │ │ ├── KafkaDataSetDefValidatorTest.java │ │ │ ├── PrometheusDataSetDefValidatorTest.java │ │ │ └── SQLDataSetDefValidatorTest.java │ │ └── pom.xml │ ├── dashbuilder-webapp/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── dashbuilder/ │ │ │ │ ├── backend/ │ │ │ │ │ ├── ApplicationScopedProducer.java │ │ │ │ │ ├── ClusterMetricsGenerator.java │ │ │ │ │ ├── RepositoryServiceImpl.java │ │ │ │ │ ├── RuntimeJaxApp.java │ │ │ │ │ ├── SalesDataSetGenerator.java │ │ │ │ │ └── command/ │ │ │ │ │ ├── CommandEvent.java │ │ │ │ │ └── CommandServer.java │ │ │ │ ├── client/ │ │ │ │ │ ├── ShowcaseEntryPoint.java │ │ │ │ │ ├── dashboard/ │ │ │ │ │ │ ├── DashboardManager.java │ │ │ │ │ │ └── DashboardPerspectiveActivity.java │ │ │ │ │ ├── expenses/ │ │ │ │ │ │ ├── ExpenseConstants.java │ │ │ │ │ │ ├── ExpensesDashboard.java │ │ │ │ │ │ └── ExpensesDashboard.ui.xml │ │ │ │ │ ├── gallery/ │ │ │ │ │ │ ├── GalleryPlaceRequest.java │ │ │ │ │ │ ├── GalleryTree.java │ │ │ │ │ │ ├── GalleryTreeNode.java │ │ │ │ │ │ ├── GalleryTreeNodeList.java │ │ │ │ │ │ ├── GalleryTreePresenter.java │ │ │ │ │ │ ├── GalleryTreeViewImpl.java │ │ │ │ │ │ ├── GalleryWidget.java │ │ │ │ │ │ └── GalleryWidgetPresenter.java │ │ │ │ │ ├── metrics/ │ │ │ │ │ │ ├── ClusterMetricsDashboard.java │ │ │ │ │ │ └── ClusterMetricsDashboard.ui.xml │ │ │ │ │ ├── navbar/ │ │ │ │ │ │ ├── AppHeader.html │ │ │ │ │ │ ├── AppHeader.java │ │ │ │ │ │ └── DashbuilderNavBrand.java │ │ │ │ │ ├── navigation/ │ │ │ │ │ │ └── NavTreeDefinitions.java │ │ │ │ │ ├── perspectives/ │ │ │ │ │ │ ├── DisplayerGalleryPerspective.java │ │ │ │ │ │ ├── HomePerspective.java │ │ │ │ │ │ ├── SalesDashboardPerspective.java │ │ │ │ │ │ └── SalesReportsPerspective.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ ├── AppImages.java │ │ │ │ │ │ ├── AppResource.java │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ └── AppConstants.java │ │ │ │ │ ├── sales/ │ │ │ │ │ │ ├── SalesOppsDisplayers.java │ │ │ │ │ │ └── widgets/ │ │ │ │ │ │ ├── SalesDistributionByCountry.java │ │ │ │ │ │ ├── SalesDistributionByCountry.ui.xml │ │ │ │ │ │ ├── SalesExpectedByDate.java │ │ │ │ │ │ ├── SalesExpectedByDate.ui.xml │ │ │ │ │ │ ├── SalesGoals.java │ │ │ │ │ │ ├── SalesGoals.ui.xml │ │ │ │ │ │ ├── SalesTableReports.java │ │ │ │ │ │ └── SalesTableReports.ui.xml │ │ │ │ │ ├── screens/ │ │ │ │ │ │ ├── GalleryHomeScreen.html │ │ │ │ │ │ ├── GalleryHomeScreen.java │ │ │ │ │ │ ├── HomeScreen.java │ │ │ │ │ │ ├── StaticChartScreen.java │ │ │ │ │ │ └── view/ │ │ │ │ │ │ ├── HomeScreenView.html │ │ │ │ │ │ ├── HomeScreenView.java │ │ │ │ │ │ └── HomeScreenView.less │ │ │ │ │ └── security/ │ │ │ │ │ └── PermissionTreeSetup.java │ │ │ │ └── shared/ │ │ │ │ ├── dashboard/ │ │ │ │ │ └── events/ │ │ │ │ │ └── DashboardDeletedEvent.java │ │ │ │ └── sales/ │ │ │ │ └── SalesConstants.java │ │ │ ├── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── services/ │ │ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ │ │ ├── app.html.template │ │ │ │ ├── application-roles.properties │ │ │ │ ├── application-users.properties │ │ │ │ ├── logback.xml │ │ │ │ ├── org/ │ │ │ │ │ └── dashbuilder/ │ │ │ │ │ ├── DashbuilderShowcase.gwt.xml │ │ │ │ │ ├── FastCompiledDashbuilderShowcase.gwt.xml │ │ │ │ │ ├── client/ │ │ │ │ │ │ └── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ ├── AppConstants.properties │ │ │ │ │ │ ├── AppConstants_de.properties │ │ │ │ │ │ ├── AppConstants_es.properties │ │ │ │ │ │ ├── AppConstants_fr.properties │ │ │ │ │ │ ├── AppConstants_it.properties │ │ │ │ │ │ ├── AppConstants_ja.properties │ │ │ │ │ │ ├── AppConstants_pt_BR.properties │ │ │ │ │ │ ├── AppConstants_zh_CN.properties │ │ │ │ │ │ ├── LoginConstants.properties │ │ │ │ │ │ ├── LoginConstants_de.properties │ │ │ │ │ │ ├── LoginConstants_es.properties │ │ │ │ │ │ ├── LoginConstants_fr.properties │ │ │ │ │ │ ├── LoginConstants_it.properties │ │ │ │ │ │ ├── LoginConstants_ja.properties │ │ │ │ │ │ ├── LoginConstants_pt_BR.properties │ │ │ │ │ │ └── LoginConstants_zh_CN.properties │ │ │ │ │ └── public/ │ │ │ │ │ └── css/ │ │ │ │ │ ├── uberfire-loading.css │ │ │ │ │ └── uberfire-showcase.css │ │ │ │ ├── security-management.properties │ │ │ │ └── security-policy.properties │ │ │ └── webapp/ │ │ │ ├── WEB-INF/ │ │ │ │ ├── beans.xml │ │ │ │ ├── datasets/ │ │ │ │ │ ├── README.md │ │ │ │ │ ├── clusterMetrics.dset │ │ │ │ │ ├── expenseReports.csv │ │ │ │ │ ├── expenseReports.dset │ │ │ │ │ ├── salesOpportunities.dset │ │ │ │ │ ├── worldPopulation.csv │ │ │ │ │ └── worldPopulation.dset │ │ │ │ ├── jboss-deployment-structure.xml │ │ │ │ ├── jboss-web.xml │ │ │ │ └── web.xml │ │ │ ├── banner/ │ │ │ │ └── banner.html │ │ │ ├── dashbuilder.html │ │ │ ├── index.jsp │ │ │ ├── login.jsp │ │ │ ├── logout.jsp │ │ │ └── not_authorized.jsp │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── dashbuilder/ │ │ │ └── security/ │ │ │ └── SecurityPolicyTest.java │ │ └── resources/ │ │ └── datasources/ │ │ └── h2-test-ds.xml │ ├── pom.xml │ └── scripts/ │ └── release/ │ ├── dashbuilder-createAndDeploy.sh │ ├── dashbuilder-pushTag.sh │ ├── dashbuilder-updateVersion.sh │ └── update-version.sh ├── drools_jbpm_eclipse_formatter_config.xml ├── pom.xml ├── uberfire-api/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ ├── annotations/ │ │ │ │ ├── Customizable.java │ │ │ │ └── FallbackImplementation.java │ │ │ ├── backend/ │ │ │ │ └── vfs/ │ │ │ │ ├── FileSystem.java │ │ │ │ ├── IsVersioned.java │ │ │ │ ├── ObservablePath.java │ │ │ │ ├── Path.java │ │ │ │ ├── PathFactory.java │ │ │ │ ├── PathSupport.java │ │ │ │ └── impl/ │ │ │ │ ├── ForceUnlockEvent.java │ │ │ │ ├── LockInfo.java │ │ │ │ ├── LockResult.java │ │ │ │ └── ObservablePathImpl.java │ │ │ ├── debug/ │ │ │ │ └── Debug.java │ │ │ ├── lifecycle/ │ │ │ │ ├── GetContent.java │ │ │ │ ├── GetPreview.java │ │ │ │ ├── IsDirty.java │ │ │ │ ├── OnClose.java │ │ │ │ ├── OnContextAttach.java │ │ │ │ ├── OnFocus.java │ │ │ │ ├── OnLostFocus.java │ │ │ │ ├── OnMayClose.java │ │ │ │ ├── OnOpen.java │ │ │ │ ├── OnSave.java │ │ │ │ ├── OnShutdown.java │ │ │ │ ├── OnStartup.java │ │ │ │ ├── SetContent.java │ │ │ │ └── Validate.java │ │ │ ├── mvp/ │ │ │ │ ├── BiParameterizedCommand.java │ │ │ │ ├── Command.java │ │ │ │ ├── Commands.java │ │ │ │ ├── ParameterizedCommand.java │ │ │ │ ├── PlaceRequest.java │ │ │ │ └── impl/ │ │ │ │ ├── ConditionalPlaceRequest.java │ │ │ │ ├── DefaultPlaceRequest.java │ │ │ │ ├── ExternalPathPlaceRequest.java │ │ │ │ ├── ForcedPlaceRequest.java │ │ │ │ └── PathPlaceRequest.java │ │ │ ├── paging/ │ │ │ │ ├── AbstractPageRow.java │ │ │ │ ├── AbstractPathPageRow.java │ │ │ │ ├── PageRequest.java │ │ │ │ └── PageResponse.java │ │ │ ├── plugin/ │ │ │ │ └── PluginUtil.java │ │ │ ├── rpc/ │ │ │ │ ├── SessionInfo.java │ │ │ │ └── impl/ │ │ │ │ ├── SessionInfoImpl.java │ │ │ │ └── SessionInfoMarshalller.java │ │ │ ├── security/ │ │ │ │ ├── Contributor.java │ │ │ │ ├── ContributorResource.java │ │ │ │ ├── ContributorType.java │ │ │ │ ├── Resource.java │ │ │ │ ├── ResourceAction.java │ │ │ │ ├── ResourceRef.java │ │ │ │ ├── ResourceType.java │ │ │ │ ├── WorkbenchUserManager.java │ │ │ │ └── authz/ │ │ │ │ ├── ResourceActionRef.java │ │ │ │ ├── RuntimeContentResource.java │ │ │ │ ├── RuntimeFeatureResource.java │ │ │ │ ├── RuntimeResource.java │ │ │ │ └── VotingStrategy.java │ │ │ ├── spaces/ │ │ │ │ ├── Space.java │ │ │ │ └── SpacesAPI.java │ │ │ ├── util/ │ │ │ │ └── URIUtil.java │ │ │ ├── workbench/ │ │ │ │ ├── annotations/ │ │ │ │ │ └── VisibleAsset.java │ │ │ │ ├── category/ │ │ │ │ │ ├── Category.java │ │ │ │ │ ├── Others.java │ │ │ │ │ └── Undefined.java │ │ │ │ ├── diff/ │ │ │ │ │ └── DiffMode.java │ │ │ │ ├── events/ │ │ │ │ │ ├── NotificationEvent.java │ │ │ │ │ ├── PluginAddedEvent.java │ │ │ │ │ ├── PluginEvent.java │ │ │ │ │ ├── PluginReloadedEvent.java │ │ │ │ │ ├── PluginUpdatedEvent.java │ │ │ │ │ ├── ResourceAdded.java │ │ │ │ │ ├── ResourceAddedEvent.java │ │ │ │ │ ├── ResourceBatchChangesEvent.java │ │ │ │ │ ├── ResourceChange.java │ │ │ │ │ ├── ResourceChangeType.java │ │ │ │ │ ├── ResourceCopied.java │ │ │ │ │ ├── ResourceCopiedEvent.java │ │ │ │ │ ├── ResourceDeleted.java │ │ │ │ │ ├── ResourceDeletedEvent.java │ │ │ │ │ ├── ResourceEvent.java │ │ │ │ │ ├── ResourceOpenedEvent.java │ │ │ │ │ ├── ResourceRenamed.java │ │ │ │ │ ├── ResourceRenamedEvent.java │ │ │ │ │ ├── ResourceUpdated.java │ │ │ │ │ ├── ResourceUpdatedEvent.java │ │ │ │ │ ├── UberFireEvent.java │ │ │ │ │ └── UberfireJSAPIReadyEvent.java │ │ │ │ ├── model/ │ │ │ │ │ ├── ActivityResourceType.java │ │ │ │ │ ├── AppFormerActivities.java │ │ │ │ │ ├── AppFormerActivitiesProducer.java │ │ │ │ │ ├── CompassPosition.java │ │ │ │ │ ├── ContextDefinition.java │ │ │ │ │ ├── ContextDisplayMode.java │ │ │ │ │ ├── CustomPanelDefinition.java │ │ │ │ │ ├── DefaultAppFormerActivities.java │ │ │ │ │ ├── NamedPosition.java │ │ │ │ │ ├── Notification.java │ │ │ │ │ ├── PanelDefinition.java │ │ │ │ │ ├── PartDefinition.java │ │ │ │ │ ├── PerspectiveDefinition.java │ │ │ │ │ ├── Position.java │ │ │ │ │ ├── SplashScreenFilter.java │ │ │ │ │ ├── bridge/ │ │ │ │ │ │ ├── Notification.java │ │ │ │ │ │ ├── NotificationSeverity.java │ │ │ │ │ │ └── NotificationType.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── ContextDefinitionImpl.java │ │ │ │ │ │ ├── CustomPanelDefinitionImpl.java │ │ │ │ │ │ ├── PanelDefinitionImpl.java │ │ │ │ │ │ ├── PartDefinitionImpl.java │ │ │ │ │ │ ├── PerspectiveDefinitionImpl.java │ │ │ │ │ │ └── SplashScreenFilterImpl.java │ │ │ │ │ ├── menu/ │ │ │ │ │ │ ├── EnabledStateChangeListener.java │ │ │ │ │ │ ├── HasEnabledStateChangeListeners.java │ │ │ │ │ │ ├── MenuCustom.java │ │ │ │ │ │ ├── MenuFactory.java │ │ │ │ │ │ ├── MenuGroup.java │ │ │ │ │ │ ├── MenuItem.java │ │ │ │ │ │ ├── MenuItemCommand.java │ │ │ │ │ │ ├── MenuItemPerspective.java │ │ │ │ │ │ ├── MenuItemPlain.java │ │ │ │ │ │ ├── MenuPosition.java │ │ │ │ │ │ ├── MenuVisitor.java │ │ │ │ │ │ ├── Menus.java │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── BaseMenuCustom.java │ │ │ │ │ │ ├── BaseMenuVisitor.java │ │ │ │ │ │ ├── DefaultMenuGroup.java │ │ │ │ │ │ ├── DefaultMenus.java │ │ │ │ │ │ └── MenuBuilderImpl.java │ │ │ │ │ └── toolbar/ │ │ │ │ │ ├── IconType.java │ │ │ │ │ ├── ToolBar.java │ │ │ │ │ ├── ToolBarIcon.java │ │ │ │ │ ├── ToolBarItem.java │ │ │ │ │ ├── ToolBarTypeIcon.java │ │ │ │ │ ├── ToolBarUrlIcon.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── DefaultToolBar.java │ │ │ │ │ └── DefaultToolBarItem.java │ │ │ │ └── type/ │ │ │ │ ├── AnyResourceTypeDefinition.java │ │ │ │ ├── DotResourceTypeDefinition.java │ │ │ │ ├── FileNameUtil.java │ │ │ │ ├── ResourceTypeDefinition.java │ │ │ │ └── TextResourceTypeDefinition.java │ │ │ └── workspace/ │ │ │ └── WorkspaceContext.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ ├── UberfireAPI.gwt.xml │ │ └── jre/ │ │ └── org/ │ │ └── uberfire/ │ │ └── util/ │ │ └── URIUtil.java │ └── test/ │ └── java/ │ ├── NaughtyClassInDefaultPackage.java │ └── org/ │ └── uberfire/ │ ├── backend/ │ │ └── vfs/ │ │ ├── PathFactoryTest.java │ │ └── impl/ │ │ └── ObservablePathImplTest.java │ ├── debug/ │ │ └── DebugTest.java │ ├── mvp/ │ │ └── impl/ │ │ ├── ConditionalPlaceRequestTest.java │ │ └── PathPlaceRequestTest.java │ ├── security/ │ │ └── ResourceRefTest.java │ ├── spaces/ │ │ └── SpacesAPITest.java │ └── workbench/ │ ├── category/ │ │ └── CategoryTest.java │ ├── model/ │ │ ├── TestWorkbenchModel.java │ │ ├── impl/ │ │ │ ├── PanelDefinitionImplTest.java │ │ │ └── PartDefinitionImplTest.java │ │ └── menu/ │ │ ├── TestMenuSyntax.java │ │ └── impl/ │ │ └── TestBehavior.java │ └── type/ │ └── FileNameUtilTest.java ├── uberfire-backend/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-backend-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ ├── backend/ │ │ │ │ │ ├── authz/ │ │ │ │ │ │ ├── AuthorizationPolicyStorage.java │ │ │ │ │ │ ├── AuthorizationService.java │ │ │ │ │ │ └── FileSystemResourceType.java │ │ │ │ │ ├── cdi/ │ │ │ │ │ │ └── workspace/ │ │ │ │ │ │ └── Workspace.java │ │ │ │ │ ├── events/ │ │ │ │ │ │ ├── AuthorizationPolicyDeployedEvent.java │ │ │ │ │ │ └── AuthorizationPolicySavedEvent.java │ │ │ │ │ ├── fs/ │ │ │ │ │ │ └── FileSystemService.java │ │ │ │ │ ├── plugin/ │ │ │ │ │ │ ├── PluginProcessor.java │ │ │ │ │ │ ├── RuntimePlugin.java │ │ │ │ │ │ ├── RuntimePluginProcessor.java │ │ │ │ │ │ └── RuntimePluginService.java │ │ │ │ │ └── vfs/ │ │ │ │ │ ├── BasicFileAttributes.java │ │ │ │ │ ├── DirectoryStream.java │ │ │ │ │ ├── FileSystemFactory.java │ │ │ │ │ ├── VFSLockService.java │ │ │ │ │ ├── VFSService.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── DirectoryStreamImpl.java │ │ │ │ │ └── VFSCacheInterceptor.java │ │ │ │ └── workbench/ │ │ │ │ └── services/ │ │ │ │ └── WorkbenchServices.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── UberfireBackend.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── backend/ │ │ └── vfs/ │ │ └── PathTest.java │ ├── uberfire-backend-cdi/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── backend/ │ │ │ │ └── server/ │ │ │ │ └── cdi/ │ │ │ │ ├── AlternativeStarterBean.java │ │ │ │ ├── SystemConfigProducer.java │ │ │ │ ├── model/ │ │ │ │ │ └── WorkspaceImpl.java │ │ │ │ └── workspace/ │ │ │ │ ├── WorkspaceExecutorService.java │ │ │ │ ├── WorkspaceExecutorServiceProducer.java │ │ │ │ ├── WorkspaceManager.java │ │ │ │ ├── WorkspaceManagerPreferences.java │ │ │ │ ├── WorkspaceNameResolver.java │ │ │ │ ├── WorkspaceScopeContext.java │ │ │ │ ├── WorkspaceScoped.java │ │ │ │ └── WorkspaceScopedExtension.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ ├── beans.xml │ │ │ └── services/ │ │ │ └── javax.enterprise.inject.spi.Extension │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── backend/ │ │ │ └── server/ │ │ │ └── cdi/ │ │ │ ├── SessionBasedBean.java │ │ │ ├── SystemConfigProducerTest.java │ │ │ ├── WorkspaceBuilderService.java │ │ │ ├── WorkspaceBuilderServiceImpl.java │ │ │ ├── WorkspaceBuilderServiceTest.java │ │ │ └── workspace/ │ │ │ ├── WorkspaceManagerTest.java │ │ │ └── WorkspaceNameResolverTest.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ └── logback.xml │ └── uberfire-backend-server/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── backend/ │ │ │ └── server/ │ │ │ ├── IOWatchServiceAllImpl.java │ │ │ ├── IOWatchServiceNonDotImpl.java │ │ │ ├── LockCleanupSessionListener.java │ │ │ ├── LockClientNotifier.java │ │ │ ├── UserServicesBackendImpl.java │ │ │ ├── UserServicesImpl.java │ │ │ ├── VFSLockServiceImpl.java │ │ │ ├── VFSServicesServerImpl.java │ │ │ ├── WebAppListener.java │ │ │ ├── WebAppSettings.java │ │ │ ├── WorkbenchServicesImpl.java │ │ │ ├── authz/ │ │ │ │ ├── AuthorizationPolicyDeployer.java │ │ │ │ ├── AuthorizationPolicyMarshaller.java │ │ │ │ ├── AuthorizationPolicyVfsStorage.java │ │ │ │ ├── AuthorizationServiceImpl.java │ │ │ │ └── NonEscapedProperties.java │ │ │ ├── fs/ │ │ │ │ └── FileSystemServiceImpl.java │ │ │ ├── io/ │ │ │ │ ├── ConfigIOServiceProducer.java │ │ │ │ ├── DisposableShutdownService.java │ │ │ │ ├── object/ │ │ │ │ │ ├── ObjectStorage.java │ │ │ │ │ └── ObjectStorageImpl.java │ │ │ │ └── watch/ │ │ │ │ ├── AbstractIOWatchService.java │ │ │ │ ├── AsyncWatchService.java │ │ │ │ ├── IOWatchServiceExecutor.java │ │ │ │ └── IOWatchServiceExecutorImpl.java │ │ │ ├── plugins/ │ │ │ │ ├── PluginService.java │ │ │ │ ├── PluginStartup.java │ │ │ │ ├── PluginUtils.java │ │ │ │ ├── RuntimePluginServiceImpl.java │ │ │ │ ├── engine/ │ │ │ │ │ ├── PluginJarProcessor.java │ │ │ │ │ ├── PluginManager.java │ │ │ │ │ └── PluginWatcher.java │ │ │ │ └── processors/ │ │ │ │ ├── AbstractRuntimePluginProcessor.java │ │ │ │ ├── GWTScriptPluginProcessor.java │ │ │ │ ├── HTMLPluginProcessor.java │ │ │ │ ├── PerspectiveLayoutPluginProcessor.java │ │ │ │ └── UFJSPluginProcessor.java │ │ │ ├── security/ │ │ │ │ ├── ElytronAuthenticationService.java │ │ │ │ ├── FileSystemResourceAdaptor.java │ │ │ │ ├── IOSecurityAuth.java │ │ │ │ ├── IOSecurityAuthz.java │ │ │ │ ├── IOServiceSecuritySetup.java │ │ │ │ ├── JAASAuthenticationService.java │ │ │ │ ├── RoleLoader.java │ │ │ │ ├── RoleRegistry.java │ │ │ │ ├── adapter/ │ │ │ │ │ ├── GroupAdapterAuthorizationSource.java │ │ │ │ │ ├── JettyGroupsAdapter.java │ │ │ │ │ ├── WebSphereGroupsAdapter.java │ │ │ │ │ └── WeblogicGroupsAdapter.java │ │ │ │ └── elytron/ │ │ │ │ ├── DefaultElytronIdentityHelper.java │ │ │ │ ├── ElytronIdentityHelper.java │ │ │ │ └── ElytronIdentityHelperProducer.java │ │ │ ├── servlet/ │ │ │ │ └── ReleaseUserLocksServlet.java │ │ │ ├── spaces/ │ │ │ │ └── SpacesAPIImpl.java │ │ │ └── util/ │ │ │ ├── Filter.java │ │ │ ├── Guava14Workaround.java │ │ │ ├── Paths.java │ │ │ ├── TextUtil.java │ │ │ └── gzip/ │ │ │ ├── GzipFilter.java │ │ │ ├── GzipHttpServletResponseWrapper.java │ │ │ └── GzipResponseServletOutputStream.java │ │ └── resources/ │ │ └── META-INF/ │ │ ├── beans.xml │ │ └── services/ │ │ └── org.uberfire.security.authz.adapter.GroupsAdapter │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ ├── backend/ │ │ │ └── server/ │ │ │ ├── IOWatchServiceNonDotImplTest.java │ │ │ ├── LockCleanupSessionListenerTest.java │ │ │ ├── VFSLockServiceTest.java │ │ │ ├── VFSServicesServerImplTest.java │ │ │ ├── WebAppSettingsTest.java │ │ │ ├── authz/ │ │ │ │ ├── AuthorizationServiceTest.java │ │ │ │ ├── AuthzPolicyDeployerTest.java │ │ │ │ └── AuthzPolicyMarshallerTest.java │ │ │ ├── io/ │ │ │ │ ├── JGitFileSystemLazyCacheTest.java │ │ │ │ ├── object/ │ │ │ │ │ └── ObjectStorageTest.java │ │ │ │ └── watch/ │ │ │ │ ├── AbstractIOWatchServiceTest.java │ │ │ │ └── IOWatchServiceExecutorImplTest.java │ │ │ ├── plugins/ │ │ │ │ ├── PluginServiceTest.java │ │ │ │ ├── engine/ │ │ │ │ │ ├── AbstractPluginsTest.java │ │ │ │ │ ├── PluginJarProcessorTest.java │ │ │ │ │ ├── PluginManagerTest.java │ │ │ │ │ └── PluginWatcherTest.java │ │ │ │ └── processors/ │ │ │ │ ├── GWTScriptPluginProcessorTest.java │ │ │ │ ├── HTMLPluginProcessorTest.java │ │ │ │ └── UFJSPluginProcessorTest.java │ │ │ ├── security/ │ │ │ │ ├── ElytronAuthenticationServiceTest.java │ │ │ │ ├── FileSystemResourceAdaptorTest.java │ │ │ │ ├── IOServiceSecuritySetupTest.java │ │ │ │ ├── JAASAuthenticationServiceTest.java │ │ │ │ ├── MockAuthenticationService.java │ │ │ │ ├── MockSecuredFilesystemProvider.java │ │ │ │ ├── RoleLoaderTest.java │ │ │ │ ├── adapter/ │ │ │ │ │ └── GroupAdapterAuthorizationSourceTest.java │ │ │ │ └── elytron/ │ │ │ │ ├── DefaultElytronIdentityHelperTest.java │ │ │ │ └── ElytronIdentityHelperProducerTest.java │ │ │ ├── servlet/ │ │ │ │ └── ReleaseUserLocksServletTest.java │ │ │ ├── spaces/ │ │ │ │ └── SpacesAPIImplTest.java │ │ │ └── util/ │ │ │ ├── PathsTest.java │ │ │ ├── TestPaths.java │ │ │ └── gzip/ │ │ │ └── GzipFilterTest.java │ │ └── util/ │ │ └── TextUtilTest.java │ └── resources/ │ ├── META-INF/ │ │ └── services/ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ ├── WEB-INF/ │ │ ├── classes/ │ │ │ ├── invalid/ │ │ │ │ └── security-policy.properties │ │ │ ├── security-policy.properties │ │ │ └── split/ │ │ │ ├── security-module-filesystem.properties │ │ │ ├── security-module-homes.properties │ │ │ ├── security-module-perspective.properties │ │ │ ├── security-module-priorities.properties │ │ │ ├── security-module-roles.properties │ │ │ └── security-policy.properties │ │ └── web.xml │ ├── plugins/ │ │ └── plugin.txt │ └── test-app/ │ └── test-app.nocache.js ├── uberfire-client-api/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── client/ │ │ │ ├── annotations/ │ │ │ │ ├── DefaultPosition.java │ │ │ │ ├── Intercept.java │ │ │ │ ├── Perspective.java │ │ │ │ ├── SplashBodyHeight.java │ │ │ │ ├── SplashFilter.java │ │ │ │ ├── WorkbenchClientEditor.java │ │ │ │ ├── WorkbenchContext.java │ │ │ │ ├── WorkbenchContextId.java │ │ │ │ ├── WorkbenchEditor.java │ │ │ │ ├── WorkbenchMenu.java │ │ │ │ ├── WorkbenchPanel.java │ │ │ │ ├── WorkbenchPartTitle.java │ │ │ │ ├── WorkbenchPartTitleDecoration.java │ │ │ │ ├── WorkbenchPartView.java │ │ │ │ ├── WorkbenchPerspective.java │ │ │ │ ├── WorkbenchPopup.java │ │ │ │ ├── WorkbenchScreen.java │ │ │ │ ├── WorkbenchSplashScreen.java │ │ │ │ └── WorkbenchToolBar.java │ │ │ ├── callbacks/ │ │ │ │ └── Callback.java │ │ │ ├── mvp/ │ │ │ │ ├── HasPresenter.java │ │ │ │ ├── LockRequiredEvent.java │ │ │ │ ├── LockTarget.java │ │ │ │ ├── RenameInProgressEvent.java │ │ │ │ ├── SaveInProgressEvent.java │ │ │ │ ├── UberElement.java │ │ │ │ ├── UberElemental.java │ │ │ │ ├── UberView.java │ │ │ │ └── UpdatedLockStatusEvent.java │ │ │ ├── promise/ │ │ │ │ ├── PromisePolyfillBootstrapper.java │ │ │ │ ├── PromisePolyfillClientBundle.java │ │ │ │ └── Promises.java │ │ │ ├── resources/ │ │ │ │ ├── UberfireResources.java │ │ │ │ ├── i18n/ │ │ │ │ │ └── UberfireConstants.java │ │ │ │ └── images/ │ │ │ │ └── UberfireImageResources.java │ │ │ ├── util/ │ │ │ │ ├── Clipboard.java │ │ │ │ └── Cookie.java │ │ │ └── workbench/ │ │ │ ├── events/ │ │ │ │ ├── ChangeTitleWidgetEvent.java │ │ │ │ └── NewSplashScreenActiveEvent.java │ │ │ ├── ouia/ │ │ │ │ ├── OuiaAttribute.java │ │ │ │ ├── OuiaComponent.java │ │ │ │ ├── OuiaComponentIdAttribute.java │ │ │ │ └── OuiaComponentTypeAttribute.java │ │ │ └── type/ │ │ │ ├── AnyResourceType.java │ │ │ ├── ClientResourceType.java │ │ │ ├── ClientTypeRegistry.java │ │ │ ├── DotResourceType.java │ │ │ └── impl/ │ │ │ └── ClientTypeRegistryImpl.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ ├── UberfireClientAPI.gwt.xml │ │ └── client/ │ │ └── resources/ │ │ └── i18n/ │ │ ├── UberfireConstants.properties │ │ ├── UberfireConstants_de.properties │ │ ├── UberfireConstants_es.properties │ │ ├── UberfireConstants_fr.properties │ │ ├── UberfireConstants_it.properties │ │ ├── UberfireConstants_ja.properties │ │ ├── UberfireConstants_pt_BR.properties │ │ └── UberfireConstants_zh_CN.properties │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── client/ │ ├── util/ │ │ └── CookieTest.java │ └── workbench/ │ └── ouia/ │ ├── OuiaComponentIdAttributeTest.java │ └── OuiaComponentTypeAttributeTest.java ├── uberfire-commons/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── commons/ │ │ │ ├── async/ │ │ │ │ ├── DescriptiveRunnable.java │ │ │ │ └── DescriptiveThreadFactory.java │ │ │ ├── cluster/ │ │ │ │ ├── ClusterJMSService.java │ │ │ │ ├── ClusterParameters.java │ │ │ │ ├── ClusterService.java │ │ │ │ ├── ConnectionMode.java │ │ │ │ └── events/ │ │ │ │ ├── ClusterEventObserver.java │ │ │ │ └── ClusterSerializedCDIMessageWrapper.java │ │ │ ├── clusterapi/ │ │ │ │ └── Clustered.java │ │ │ ├── concurrent/ │ │ │ │ ├── ExecutorServiceProducer.java │ │ │ │ ├── FSWatch.java │ │ │ │ ├── Indexing.java │ │ │ │ ├── Managed.java │ │ │ │ ├── RestApi.java │ │ │ │ └── Unmanaged.java │ │ │ ├── config/ │ │ │ │ └── ConfigProperties.java │ │ │ ├── data/ │ │ │ │ ├── Cacheable.java │ │ │ │ ├── Pair.java │ │ │ │ └── Triple.java │ │ │ ├── lifecycle/ │ │ │ │ ├── Disposable.java │ │ │ │ ├── PriorityDisposable.java │ │ │ │ └── PriorityDisposableRegistry.java │ │ │ ├── lock/ │ │ │ │ ├── LockExecuteReleaseTemplate.java │ │ │ │ └── LockService.java │ │ │ ├── message/ │ │ │ │ ├── AsyncCallback.java │ │ │ │ ├── MessageHandler.java │ │ │ │ ├── MessageHandlerResolver.java │ │ │ │ ├── MessageService.java │ │ │ │ └── MessageType.java │ │ │ ├── regex/ │ │ │ │ └── util/ │ │ │ │ ├── AntPathMatcher.java │ │ │ │ └── GlobToRegEx.java │ │ │ ├── services/ │ │ │ │ └── cdi/ │ │ │ │ ├── ApplicationStarted.java │ │ │ │ ├── Startable.java │ │ │ │ ├── Startup.java │ │ │ │ ├── StartupType.java │ │ │ │ └── Veto.java │ │ │ └── uuid/ │ │ │ └── UUID.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── commons/ │ │ └── UberfireCommons.gwt.xml │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── commons/ │ ├── cluster/ │ │ ├── BaseClusterJMSServiceTest.java │ │ ├── ClusterJMSJNDIServiceTest.java │ │ ├── ClusterJMSRemoteServiceTest.java │ │ ├── ClusterJMSServiceTest.java │ │ └── events/ │ │ └── ClusterEventObserverTest.java │ ├── concurrent/ │ │ └── ExecutorServiceProducerTest.java │ ├── lifecycle/ │ │ └── PriorityDisposableRegistryTest.java │ ├── regex/ │ │ └── util/ │ │ └── GlobToRegExTest.java │ └── uuid/ │ └── UUIDTest.java ├── uberfire-experimental/ │ ├── pom.xml │ ├── uberfire-experimental-api/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── experimental/ │ │ │ ├── definition/ │ │ │ │ └── annotations/ │ │ │ │ └── ExperimentalFeature.java │ │ │ └── service/ │ │ │ ├── ExperimentalFeaturesRegistryService.java │ │ │ ├── auth/ │ │ │ │ └── ExperimentalActivitiesAuthorizationManager.java │ │ │ ├── backend/ │ │ │ │ ├── BackendExperimentalFeatureDefRegistry.java │ │ │ │ ├── BackendExperimentalFeaturesRegistryService.java │ │ │ │ ├── ExperimentalFeaturesSession.java │ │ │ │ └── impl/ │ │ │ │ └── ExperimentalFeaturesSessionImpl.java │ │ │ ├── definition/ │ │ │ │ ├── ExperimentalFeatureDefRegistry.java │ │ │ │ ├── ExperimentalFeatureDefinition.java │ │ │ │ ├── ExperimentalFeatureDefinitionProvider.java │ │ │ │ └── impl/ │ │ │ │ └── ExperimentalFeatureDefRegistryImpl.java │ │ │ ├── editor/ │ │ │ │ ├── EditableExperimentalFeature.java │ │ │ │ └── FeaturesEditorService.java │ │ │ ├── events/ │ │ │ │ ├── ExperimentalFeatureModifiedEvent.java │ │ │ │ ├── NonPortableExperimentalFeatureModifiedEvent.java │ │ │ │ └── PortableExperimentalFeatureModifiedEvent.java │ │ │ ├── registry/ │ │ │ │ ├── ExperimentalFeature.java │ │ │ │ ├── ExperimentalFeaturesRegistry.java │ │ │ │ └── impl/ │ │ │ │ ├── ExperimentalFeatureImpl.java │ │ │ │ └── ExperimentalFeaturesRegistryImpl.java │ │ │ └── security/ │ │ │ ├── GlobalExperimentalFeatureAction.java │ │ │ └── GlobalExperimentalFeatureResourceType.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── ErraiApp.properties │ │ └── org/ │ │ └── uberfire/ │ │ └── experimental/ │ │ └── UberfireExperimentalAPI.gwt.xml │ ├── uberfire-experimental-backend/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── experimental/ │ │ │ │ └── service/ │ │ │ │ ├── BackendExperimentalFeaturesRegistryServiceImpl.java │ │ │ │ ├── definition/ │ │ │ │ │ └── impl/ │ │ │ │ │ └── CDIBackendFeatureDefRegistry.java │ │ │ │ └── storage/ │ │ │ │ ├── ExperimentalFeaturesStorage.java │ │ │ │ ├── impl/ │ │ │ │ │ └── ExperimentalFeaturesStorageImpl.java │ │ │ │ ├── migration/ │ │ │ │ │ ├── StorageMigration.java │ │ │ │ │ ├── StorageMigrationService.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── StorageMigrationServiceImpl.java │ │ │ │ │ └── migrations/ │ │ │ │ │ └── V2StorageMigration.java │ │ │ │ ├── scoped/ │ │ │ │ │ ├── ExperimentalStorageScope.java │ │ │ │ │ ├── ScopedExperimentalFeaturesStorage.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── AbstractScopedExperimentalFeaturesStorage.java │ │ │ │ │ ├── GlobalExperimentalFeaturesStorageImpl.java │ │ │ │ │ └── UserExperimentalFeaturesStorageImpl.java │ │ │ │ └── util/ │ │ │ │ └── ExperimentalConstants.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── experimental/ │ │ │ └── service/ │ │ │ ├── BackendExperimentalFeaturesRegistryServiceImplTest.java │ │ │ ├── storage/ │ │ │ │ ├── impl/ │ │ │ │ │ └── ExperimentalFeaturesStorageImplTest.java │ │ │ │ ├── migration/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── StorageMigrationServiceImplTest.java │ │ │ │ │ └── migrations/ │ │ │ │ │ └── V2StorageMigrationTest.java │ │ │ │ └── scoped/ │ │ │ │ └── impl/ │ │ │ │ ├── AbstractExperimentalFeaturesStorageTest.java │ │ │ │ ├── GlobalExperimentalFeaturesStorageImplTest.java │ │ │ │ └── UserExperimentalFeaturesStorageImplTest.java │ │ │ └── util/ │ │ │ └── TestUtils.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ └── test/ │ │ ├── global/ │ │ │ ├── extraFeatures.txt │ │ │ ├── missingFeatures.txt │ │ │ └── regularFeatures.txt │ │ └── user/ │ │ ├── extraFeatures.txt │ │ ├── missingFeatures.txt │ │ └── regularFeatures.txt │ └── uberfire-experimental-client/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── experimental/ │ │ │ └── client/ │ │ │ ├── UberfireExperimentalEntryPoint.java │ │ │ ├── disabled/ │ │ │ │ ├── component/ │ │ │ │ │ ├── DisabledFeatureComponent.java │ │ │ │ │ ├── DisabledFeatureComponentView.java │ │ │ │ │ ├── DisabledFeatureComponentViewImpl.css │ │ │ │ │ ├── DisabledFeatureComponentViewImpl.html │ │ │ │ │ └── DisabledFeatureComponentViewImpl.java │ │ │ │ └── screen/ │ │ │ │ └── DisabledFeatureActivity.java │ │ │ ├── editor/ │ │ │ │ ├── ExperimentalFeaturesEditorScreen.java │ │ │ │ ├── ExperimentalFeaturesEditorScreenView.java │ │ │ │ ├── ExperimentalFeaturesEditorScreenViewImpl.css │ │ │ │ ├── ExperimentalFeaturesEditorScreenViewImpl.html │ │ │ │ ├── ExperimentalFeaturesEditorScreenViewImpl.java │ │ │ │ └── group/ │ │ │ │ ├── ExperimentalFeaturesGroup.java │ │ │ │ ├── ExperimentalFeaturesGroupView.java │ │ │ │ ├── ExperimentalFeaturesGroupViewImpl.css │ │ │ │ ├── ExperimentalFeaturesGroupViewImpl.html │ │ │ │ ├── ExperimentalFeaturesGroupViewImpl.java │ │ │ │ └── feature/ │ │ │ │ ├── ExperimentalFeatureEditor.java │ │ │ │ ├── ExperimentalFeatureEditorView.java │ │ │ │ ├── ExperimentalFeatureEditorViewImpl.css │ │ │ │ ├── ExperimentalFeatureEditorViewImpl.html │ │ │ │ └── ExperimentalFeatureEditorViewImpl.java │ │ │ ├── perspective/ │ │ │ │ └── ExperimentalFeaturesPerspective.java │ │ │ ├── resources/ │ │ │ │ └── i18n/ │ │ │ │ └── UberfireExperimentalConstants.java │ │ │ ├── service/ │ │ │ │ ├── ClientExperimentalFeaturesDefRegistry.java │ │ │ │ ├── ClientExperimentalFeaturesRegistryService.java │ │ │ │ ├── auth/ │ │ │ │ │ ├── ExperimentalActivitiesAuthorizationManagerImpl.java │ │ │ │ │ └── ExperimentalActivityReference.java │ │ │ │ └── impl/ │ │ │ │ ├── CDIClientFeatureDefRegistry.java │ │ │ │ └── ClientExperimentalFeaturesRegistryServiceImpl.java │ │ │ ├── util/ │ │ │ │ └── ExperimentalUtils.java │ │ │ └── workbench/ │ │ │ └── type/ │ │ │ └── ExperimentalAwareClientTypeRegistryImpl.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── experimental/ │ │ ├── UberfireExperimentalClient.gwt.xml │ │ └── client/ │ │ └── resources/ │ │ └── i18n/ │ │ ├── UberfireExperimentalConstants.properties │ │ ├── UberfireExperimentalConstants_es.properties │ │ ├── UberfireExperimentalConstants_fr.properties │ │ ├── UberfireExperimentalConstants_it.properties │ │ └── UberfireExperimentalConstants_ja.properties │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── experimental/ │ └── client/ │ ├── disabled/ │ │ ├── component/ │ │ │ └── DisabledFeatureComponentTest.java │ │ └── screen/ │ │ └── DisabledFeatureActivityTest.java │ ├── editor/ │ │ ├── ExperimentalFeaturesEditorScreenTest.java │ │ └── group/ │ │ ├── ExperimentalFeaturesGroupTest.java │ │ ├── TestExperimentalFeaturesGroup.java │ │ └── feature/ │ │ └── ExperimentalFeatureEditorTest.java │ ├── service/ │ │ ├── auth/ │ │ │ └── ExperimentalActivitiesAuthorizationManagerImplTest.java │ │ └── impl/ │ │ └── ClientExperimentalFeaturesRegistryServiceImplTest.java │ ├── test/ │ │ ├── TestExperimentalActivityReference.java │ │ ├── TestExperimentalFeatureDefRegistry.java │ │ └── model/ │ │ ├── TestExperimentalScreen1Activity.java │ │ ├── TestExperimentalScreen2Activity.java │ │ └── TestNonExperimentalScreenActivity.java │ └── workbench/ │ └── type/ │ ├── ExperimentalAwareClientTypeRegistryImplTest.java │ └── test/ │ ├── api/ │ │ ├── DiagramResourceType.java │ │ ├── FormResourceType.java │ │ ├── JavaResourceType.java │ │ ├── SpreadSheetResourceType.java │ │ ├── TextFileResourceType.java │ │ └── WrongClientResourceType.java │ └── client/ │ ├── ClientDiagramResourceType.java │ ├── ClientFormResourceType.java │ ├── ClientJavaResourceType.java │ ├── ClientSpreadSheetResourceType.java │ └── ClientTextFileResourceType.java ├── uberfire-extensions/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-apps/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-apps-api/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── apps/ │ │ │ │ │ └── api/ │ │ │ │ │ ├── AppsPersistenceAPI.java │ │ │ │ │ ├── Directory.java │ │ │ │ │ └── DirectoryBreadcrumb.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── ErraiApp.properties │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── apps/ │ │ │ │ └── UberfireAppsAPI.gwt.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── apps/ │ │ │ └── api/ │ │ │ └── DirectoryBreadcrumbTest.java │ │ ├── uberfire-apps-backend/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── apps/ │ │ │ │ └── impl/ │ │ │ │ └── AppsPersistenceImpl.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── beans.xml │ │ └── uberfire-apps-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── apps/ │ │ │ │ └── client/ │ │ │ │ ├── AppsEntryPoint.java │ │ │ │ ├── AppsPerspective.java │ │ │ │ ├── home/ │ │ │ │ │ ├── AppsHomePresenter.java │ │ │ │ │ ├── AppsHomeView.java │ │ │ │ │ ├── AppsHomeView.ui.xml │ │ │ │ │ └── components/ │ │ │ │ │ ├── TilesApp.java │ │ │ │ │ ├── TilesApp.ui.xml │ │ │ │ │ └── popup/ │ │ │ │ │ ├── DirectoryNameValidator.java │ │ │ │ │ ├── NewDirectoryPopup.java │ │ │ │ │ └── NewDirectoryPopup.ui.xml │ │ │ │ └── resources/ │ │ │ │ ├── AppsCss.java │ │ │ │ ├── WebAppResource.java │ │ │ │ └── i18n/ │ │ │ │ └── CommonConstants.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── apps/ │ │ │ ├── UberfireAppsClient.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ ├── css/ │ │ │ │ └── apps.css │ │ │ └── i18n/ │ │ │ ├── CommonConstants.properties │ │ │ ├── CommonConstants_de.properties │ │ │ ├── CommonConstants_es.properties │ │ │ ├── CommonConstants_fr.properties │ │ │ ├── CommonConstants_it.properties │ │ │ ├── CommonConstants_ja.properties │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ └── CommonConstants_zh_CN.properties │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── apps/ │ │ └── client/ │ │ └── home/ │ │ └── components/ │ │ └── popup/ │ │ └── DirectoryNameValidatorTest.java │ ├── uberfire-commons-editor/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-commons-editor-api/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── editor/ │ │ │ │ │ └── commons/ │ │ │ │ │ ├── backend/ │ │ │ │ │ │ └── version/ │ │ │ │ │ │ ├── PathResolver.java │ │ │ │ │ │ └── VersionRecordService.java │ │ │ │ │ ├── file/ │ │ │ │ │ │ ├── DefaultMetadata.java │ │ │ │ │ │ └── exports/ │ │ │ │ │ │ ├── FileExportsPreferences.java │ │ │ │ │ │ ├── PdfExportPreferences.java │ │ │ │ │ │ ├── PdfFormatValidator.java │ │ │ │ │ │ ├── PdfOrientationValidator.java │ │ │ │ │ │ └── PdfUnitValidator.java │ │ │ │ │ ├── readonly/ │ │ │ │ │ │ └── ReadOnlyPathPlaceRequest.java │ │ │ │ │ ├── service/ │ │ │ │ │ │ ├── CopyService.java │ │ │ │ │ │ ├── DeleteService.java │ │ │ │ │ │ ├── PathNamingService.java │ │ │ │ │ │ ├── RenameService.java │ │ │ │ │ │ ├── ValidationService.java │ │ │ │ │ │ ├── htmleditor/ │ │ │ │ │ │ │ └── HtmlEditorService.java │ │ │ │ │ │ ├── restriction/ │ │ │ │ │ │ │ └── PathOperationRestriction.java │ │ │ │ │ │ ├── restrictor/ │ │ │ │ │ │ │ ├── CopyRestrictor.java │ │ │ │ │ │ │ ├── DeleteRestrictor.java │ │ │ │ │ │ │ ├── PathOperationRestrictor.java │ │ │ │ │ │ │ └── RenameRestrictor.java │ │ │ │ │ │ └── support/ │ │ │ │ │ │ ├── SupportsCopy.java │ │ │ │ │ │ ├── SupportsCreate.java │ │ │ │ │ │ ├── SupportsDelete.java │ │ │ │ │ │ ├── SupportsRead.java │ │ │ │ │ │ ├── SupportsRename.java │ │ │ │ │ │ ├── SupportsSaveAndRename.java │ │ │ │ │ │ └── SupportsUpdate.java │ │ │ │ │ ├── template/ │ │ │ │ │ │ ├── TemplateRenderer.java │ │ │ │ │ │ └── mustache/ │ │ │ │ │ │ └── MustacheTemplateRenderer.java │ │ │ │ │ └── version/ │ │ │ │ │ ├── CurrentBranch.java │ │ │ │ │ ├── VersionService.java │ │ │ │ │ ├── events/ │ │ │ │ │ │ └── RestoreEvent.java │ │ │ │ │ └── impl/ │ │ │ │ │ └── PortableVersionRecord.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── editor/ │ │ │ │ └── commons/ │ │ │ │ └── UberfireCommonsEditorAPI.gwt.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── editor/ │ │ │ └── commons/ │ │ │ └── file/ │ │ │ └── exports/ │ │ │ ├── FileExportsPreferencesTest.java │ │ │ └── PdfValidatorsTest.java │ │ ├── uberfire-commons-editor-backend/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── editor/ │ │ │ │ │ └── commons/ │ │ │ │ │ └── backend/ │ │ │ │ │ ├── service/ │ │ │ │ │ │ ├── CopyServiceImpl.java │ │ │ │ │ │ ├── DeleteServiceImpl.java │ │ │ │ │ │ ├── RenameServiceImpl.java │ │ │ │ │ │ ├── SaveAndRenameServiceImpl.java │ │ │ │ │ │ ├── ValidationServiceImpl.java │ │ │ │ │ │ ├── helper/ │ │ │ │ │ │ │ ├── CopyHelper.java │ │ │ │ │ │ │ ├── DeleteHelper.java │ │ │ │ │ │ │ └── RenameHelper.java │ │ │ │ │ │ ├── htmleditor/ │ │ │ │ │ │ │ └── HtmlEditorServiceImpl.java │ │ │ │ │ │ ├── naming/ │ │ │ │ │ │ │ └── PathNamingServiceImpl.java │ │ │ │ │ │ └── restriction/ │ │ │ │ │ │ └── LockRestrictor.java │ │ │ │ │ ├── validation/ │ │ │ │ │ │ ├── DefaultFileNameValidator.java │ │ │ │ │ │ ├── FileNameValidator.java │ │ │ │ │ │ └── ValidationUtils.java │ │ │ │ │ └── version/ │ │ │ │ │ ├── PathResolverImpl.java │ │ │ │ │ ├── VersionRecordServiceImpl.java │ │ │ │ │ ├── VersionServiceImpl.java │ │ │ │ │ └── VersionUtil.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── editor/ │ │ │ │ └── commons/ │ │ │ │ └── backend/ │ │ │ │ ├── service/ │ │ │ │ │ ├── CopyServiceImplTest.java │ │ │ │ │ ├── DeleteServiceImplTest.java │ │ │ │ │ ├── RenameServiceImplTest.java │ │ │ │ │ ├── SaveAndRenameServiceImplTest.java │ │ │ │ │ ├── htmleditor/ │ │ │ │ │ │ └── HtmlEditorServiceImplTest.java │ │ │ │ │ ├── naming/ │ │ │ │ │ │ └── PathNamingServiceImplTest.java │ │ │ │ │ └── restriction/ │ │ │ │ │ └── LockRestrictorTest.java │ │ │ │ ├── validation/ │ │ │ │ │ ├── ValidationUtils_ParameterizedArtifactIdTest.java │ │ │ │ │ ├── ValidationUtils_ParameterizedFilenameTest.java │ │ │ │ │ └── ValidationUtils_ParameterizedJavaIdTest.java │ │ │ │ └── version/ │ │ │ │ ├── MockIOService.java │ │ │ │ ├── VersionRecordServiceImplTest.java │ │ │ │ └── VersionServiceImplTest.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ └── uberfire-commons-editor-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── editor/ │ │ │ │ └── commons/ │ │ │ │ └── client/ │ │ │ │ ├── BaseEditor.java │ │ │ │ ├── BaseEditorEntryPoint.java │ │ │ │ ├── BaseEditorView.java │ │ │ │ ├── BaseEditorViewImpl.java │ │ │ │ ├── EditorTitle.java │ │ │ │ ├── event/ │ │ │ │ │ ├── AbstractConcurrentOperationEvent.java │ │ │ │ │ ├── ConcurrentDeleteAcceptedEvent.java │ │ │ │ │ ├── ConcurrentDeleteIgnoredEvent.java │ │ │ │ │ ├── ConcurrentRenameAcceptedEvent.java │ │ │ │ │ └── ConcurrentRenameIgnoredEvent.java │ │ │ │ ├── file/ │ │ │ │ │ ├── CommandWithFileNameAndCommitMessage.java │ │ │ │ │ ├── CopyPopUpViewProducer.java │ │ │ │ │ ├── Customizable.java │ │ │ │ │ ├── FileNameAndCommitMessage.java │ │ │ │ │ ├── RestoreUtil.java │ │ │ │ │ ├── exports/ │ │ │ │ │ │ ├── AbstractFileExport.java │ │ │ │ │ │ ├── FileExport.java │ │ │ │ │ │ ├── FileExportProducer.java │ │ │ │ │ │ ├── FileExportResources.java │ │ │ │ │ │ ├── ImageDataUriContent.java │ │ │ │ │ │ ├── ImageFileExport.java │ │ │ │ │ │ ├── PdfDocument.java │ │ │ │ │ │ ├── PdfFileExport.java │ │ │ │ │ │ ├── TextContent.java │ │ │ │ │ │ ├── TextFileExport.java │ │ │ │ │ │ ├── jso/ │ │ │ │ │ │ │ ├── FileExportScriptInjector.java │ │ │ │ │ │ │ ├── JsFileSaver.java │ │ │ │ │ │ │ ├── JsPdf.java │ │ │ │ │ │ │ ├── JsPdfSettings.java │ │ │ │ │ │ │ └── svg/ │ │ │ │ │ │ │ ├── C2S.java │ │ │ │ │ │ │ ├── C2SContext2D.java │ │ │ │ │ │ │ └── C2SSettings.java │ │ │ │ │ │ └── svg/ │ │ │ │ │ │ ├── Context2DFactory.java │ │ │ │ │ │ ├── IContext2D.java │ │ │ │ │ │ ├── SvgExportSettings.java │ │ │ │ │ │ └── SvgFileExport.java │ │ │ │ │ └── popups/ │ │ │ │ │ ├── CommonModalBuilder.java │ │ │ │ │ ├── CopyPopUpPresenter.java │ │ │ │ │ ├── CopyPopUpView.html │ │ │ │ │ ├── CopyPopUpView.java │ │ │ │ │ ├── DeletePopUpPresenter.java │ │ │ │ │ ├── DeletePopUpView.html │ │ │ │ │ ├── DeletePopUpView.java │ │ │ │ │ ├── RenamePopUpPresenter.java │ │ │ │ │ ├── RenamePopUpView.html │ │ │ │ │ ├── RenamePopUpView.java │ │ │ │ │ ├── RenamePopUpView.less │ │ │ │ │ ├── RestorePopUpPresenter.java │ │ │ │ │ ├── RestorePopUpView.html │ │ │ │ │ ├── RestorePopUpView.java │ │ │ │ │ ├── SavePopUpPresenter.java │ │ │ │ │ ├── SavePopUpView.html │ │ │ │ │ ├── SavePopUpView.java │ │ │ │ │ ├── commons/ │ │ │ │ │ │ ├── ToggleCommentPresenter.java │ │ │ │ │ │ ├── ToggleCommentView.html │ │ │ │ │ │ └── ToggleCommentView.java │ │ │ │ │ └── elemental2/ │ │ │ │ │ └── Elemental2Modal.java │ │ │ │ ├── history/ │ │ │ │ │ ├── SaveButton.java │ │ │ │ │ ├── VersionHistoryPresenter.java │ │ │ │ │ ├── VersionHistoryPresenterView.java │ │ │ │ │ ├── VersionHistoryPresenterViewImpl.java │ │ │ │ │ ├── VersionHistoryScreenPlace.java │ │ │ │ │ ├── VersionMenuDropDownButton.java │ │ │ │ │ ├── VersionMenuDropDownButtonView.java │ │ │ │ │ ├── VersionMenuDropDownButtonViewImpl.java │ │ │ │ │ ├── VersionMenuDropDownButtonViewImpl.ui.xml │ │ │ │ │ ├── VersionMenuItem.java │ │ │ │ │ ├── VersionMenuItemLabel.java │ │ │ │ │ ├── VersionMenuItemLabel.ui.xml │ │ │ │ │ ├── VersionRecordManager.java │ │ │ │ │ ├── ViewAllLabel.java │ │ │ │ │ ├── ViewAllLabel.ui.xml │ │ │ │ │ └── event/ │ │ │ │ │ └── VersionSelectedEvent.java │ │ │ │ ├── htmleditor/ │ │ │ │ │ ├── HtmlEditor.java │ │ │ │ │ ├── HtmlEditorLibraryLoader.java │ │ │ │ │ ├── HtmlEditorPresenter.java │ │ │ │ │ ├── HtmlEditorView.css │ │ │ │ │ ├── HtmlEditorView.html │ │ │ │ │ ├── HtmlEditorView.java │ │ │ │ │ └── HtmlResourceType.java │ │ │ │ ├── menu/ │ │ │ │ │ ├── BasicFileMenuBuilder.java │ │ │ │ │ ├── BasicFileMenuBuilderImpl.java │ │ │ │ │ ├── DownloadMenuItemBuilder.java │ │ │ │ │ ├── HasLockSyncMenuStateHelper.java │ │ │ │ │ ├── MenuItems.java │ │ │ │ │ ├── RestoreVersionCommandProvider.java │ │ │ │ │ └── common/ │ │ │ │ │ ├── CurrentBranchProducer.java │ │ │ │ │ ├── DefaultCurrentBranch.java │ │ │ │ │ └── SaveAndRenameCommandBuilder.java │ │ │ │ ├── resources/ │ │ │ │ │ ├── CommonImages.java │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── CommonConstants.java │ │ │ │ │ └── Constants.java │ │ │ │ ├── template/ │ │ │ │ │ └── mustache/ │ │ │ │ │ ├── ClientMustacheTemplateRenderer.java │ │ │ │ │ ├── Mustache.java │ │ │ │ │ └── MustacheSource.java │ │ │ │ └── validation/ │ │ │ │ ├── DefaultFileNameValidator.java │ │ │ │ ├── ValidationErrorReason.java │ │ │ │ ├── Validator.java │ │ │ │ ├── ValidatorCallback.java │ │ │ │ └── ValidatorWithReasonCallback.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── editor/ │ │ │ └── commons/ │ │ │ ├── UberfireCommonsEditorClient.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ └── i18n/ │ │ │ ├── CommonConstants.properties │ │ │ ├── CommonConstants_de.properties │ │ │ ├── CommonConstants_es.properties │ │ │ ├── CommonConstants_fr.properties │ │ │ ├── CommonConstants_it.properties │ │ │ ├── CommonConstants_ja.properties │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ ├── CommonConstants_zh_CN.properties │ │ │ ├── Constants.properties │ │ │ ├── Constants_es.properties │ │ │ ├── Constants_fr.properties │ │ │ ├── Constants_it.properties │ │ │ └── Constants_ja.properties │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── editor/ │ │ └── commons/ │ │ └── client/ │ │ ├── BaseEditorRenameTest.java │ │ ├── BaseEditorTest.java │ │ ├── BaseEditorValidationTest.java │ │ ├── KieEditorTest.java │ │ ├── file/ │ │ │ ├── exports/ │ │ │ │ ├── AbstractFileExportTest.java │ │ │ │ ├── FileExportProducerTest.java │ │ │ │ ├── ImageDataUriContentTest.java │ │ │ │ ├── ImageFileExportTest.java │ │ │ │ ├── PdfDocumentTest.java │ │ │ │ ├── PdfFileExportTest.java │ │ │ │ ├── TextContentTest.java │ │ │ │ ├── TextFileExportTest.java │ │ │ │ ├── jso/ │ │ │ │ │ ├── FileExportScriptInjectorTest.java │ │ │ │ │ └── svg/ │ │ │ │ │ └── C2SContext2DTest.java │ │ │ │ └── svg/ │ │ │ │ ├── Context2DFactoryTest.java │ │ │ │ └── SvgFileExportTest.java │ │ │ └── popups/ │ │ │ ├── CommonModalBuilderTest.java │ │ │ ├── CopyPopUpPresenterTest.java │ │ │ ├── DeletePopUpPresenterTest.java │ │ │ ├── RenamePopUpPresenterTest.java │ │ │ ├── RestorePopUpPresenterTest.java │ │ │ └── SavePopUpPresenterTest.java │ │ ├── history/ │ │ │ ├── Helper.java │ │ │ ├── VersionHistoryPresenterTest.java │ │ │ ├── VersionMenuDropDownButtonTest.java │ │ │ ├── VersionRecordManagerOpenOlderVersionTest.java │ │ │ ├── VersionRecordManagerTest.java │ │ │ ├── VersionSelectedEventMock.java │ │ │ ├── VersionServiceCallerMock.java │ │ │ └── VersionServiceMock.java │ │ ├── htmleditor/ │ │ │ ├── HtmlEditorLibraryLoaderTest.java │ │ │ ├── HtmlEditorPresenterTest.java │ │ │ ├── HtmlEditorTest.java │ │ │ └── HtmlEditorViewTest.java │ │ ├── menu/ │ │ │ ├── BasicFileMenuBuilderTest.java │ │ │ ├── DownloadMenuItemBuilderTest.java │ │ │ └── common/ │ │ │ ├── CurrentBranchProducerTest.java │ │ │ ├── DefaultCurrentBranchTest.java │ │ │ └── SaveAndRenameCommandBuilderTest.java │ │ └── template/ │ │ └── mustache/ │ │ └── ClientMustacheTemplateRendererTest.java │ ├── uberfire-layout-editor/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-layout-editor-api/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── layout/ │ │ │ │ │ └── editor/ │ │ │ │ │ └── api/ │ │ │ │ │ ├── LayoutServices.java │ │ │ │ │ ├── PerspectiveServices.java │ │ │ │ │ ├── css/ │ │ │ │ │ │ ├── CssAlignment.java │ │ │ │ │ │ ├── CssAllowedValue.java │ │ │ │ │ │ ├── CssColour.java │ │ │ │ │ │ ├── CssFloat.java │ │ │ │ │ │ ├── CssFontSize.java │ │ │ │ │ │ ├── CssFontWeight.java │ │ │ │ │ │ ├── CssProperty.java │ │ │ │ │ │ ├── CssRule.java │ │ │ │ │ │ ├── CssRuleList.java │ │ │ │ │ │ ├── CssTextDecoration.java │ │ │ │ │ │ ├── CssValue.java │ │ │ │ │ │ └── CssValueType.java │ │ │ │ │ └── editor/ │ │ │ │ │ ├── LayoutColumn.java │ │ │ │ │ ├── LayoutComponent.java │ │ │ │ │ ├── LayoutComponentPart.java │ │ │ │ │ ├── LayoutInstance.java │ │ │ │ │ ├── LayoutRow.java │ │ │ │ │ └── LayoutTemplate.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── ErraiApp.properties │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── layout/ │ │ │ │ └── editor/ │ │ │ │ └── UberfireLayoutEditorAPI.gwt.xml │ │ │ └── test/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── layout/ │ │ │ └── editor/ │ │ │ └── api/ │ │ │ ├── css/ │ │ │ │ └── CssRuleTest.java │ │ │ └── editor/ │ │ │ └── LayoutTemplateTest.java │ │ ├── uberfire-layout-editor-backend/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── layout/ │ │ │ │ │ └── editor/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── LayoutServicesImpl.java │ │ │ │ │ ├── PerspectiveServicesImpl.java │ │ │ │ │ └── old/ │ │ │ │ │ └── perspective/ │ │ │ │ │ └── editor/ │ │ │ │ │ ├── ColumnEditor.java │ │ │ │ │ ├── HTMLEditor.java │ │ │ │ │ ├── PerspectiveEditor.java │ │ │ │ │ ├── RowEditor.java │ │ │ │ │ └── ScreenEditor.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── layout/ │ │ │ │ └── editor/ │ │ │ │ └── impl/ │ │ │ │ ├── LayoutServicesImplTest.java │ │ │ │ └── PerspectiveServicesImplTest.java │ │ │ └── resources/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── layout/ │ │ │ └── editor/ │ │ │ └── impl/ │ │ │ ├── 12withHTMLComponent.txt │ │ │ ├── BigLayout.txt │ │ │ ├── DeprecatedComplexPerspectiveEditor.txt │ │ │ ├── DeprecatedEmptyPerspectiveEditor.txt │ │ │ ├── DeprecatedMoreColumnsPerspectiveEditor.txt │ │ │ ├── LayoutWithComponentWithParts.txt │ │ │ └── SubColumnsLayout.txt │ │ └── uberfire-layout-editor-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── layout/ │ │ │ │ └── editor/ │ │ │ │ └── client/ │ │ │ │ ├── LayoutComponentPaletteScreen.java │ │ │ │ ├── LayoutEditorEntryPoint.java │ │ │ │ ├── LayoutEditorPluginImpl.java │ │ │ │ ├── LayoutEditorPresenter.java │ │ │ │ ├── LayoutEditorPropertiesScreen.java │ │ │ │ ├── LayoutEditorView.css │ │ │ │ ├── LayoutEditorView.html │ │ │ │ ├── LayoutEditorView.java │ │ │ │ ├── api/ │ │ │ │ │ ├── ComponentDropEvent.java │ │ │ │ │ ├── ComponentDropType.java │ │ │ │ │ ├── ComponentRemovedEvent.java │ │ │ │ │ ├── EditorWidget.java │ │ │ │ │ ├── HasConfiguration.java │ │ │ │ │ ├── HasDragAndDropSettings.java │ │ │ │ │ ├── HasModalConfiguration.java │ │ │ │ │ ├── InternalDragComponent.java │ │ │ │ │ ├── LayoutDragComponent.java │ │ │ │ │ ├── LayoutDragComponentGroup.java │ │ │ │ │ ├── LayoutDragComponentPalette.java │ │ │ │ │ ├── LayoutEditor.java │ │ │ │ │ ├── LayoutEditorElement.java │ │ │ │ │ ├── LayoutEditorElementPart.java │ │ │ │ │ ├── LayoutEditorElementType.java │ │ │ │ │ ├── LayoutEditorPlugin.java │ │ │ │ │ ├── LayoutElementVisitor.java │ │ │ │ │ ├── LayoutElementWithProperties.java │ │ │ │ │ ├── ModalConfigurationContext.java │ │ │ │ │ ├── PanelConfigurationContext.java │ │ │ │ │ └── RenderingContext.java │ │ │ │ ├── components/ │ │ │ │ │ ├── columns/ │ │ │ │ │ │ ├── Column.java │ │ │ │ │ │ ├── ColumnWithComponents.java │ │ │ │ │ │ ├── ColumnWithComponentsView.css │ │ │ │ │ │ ├── ColumnWithComponentsView.html │ │ │ │ │ │ ├── ColumnWithComponentsView.java │ │ │ │ │ │ ├── ComponentColumn.java │ │ │ │ │ │ ├── ComponentColumnPart.java │ │ │ │ │ │ ├── ComponentColumnView.css │ │ │ │ │ │ ├── ComponentColumnView.html │ │ │ │ │ │ └── ComponentColumnView.java │ │ │ │ │ ├── container/ │ │ │ │ │ │ ├── Container.java │ │ │ │ │ │ ├── ContainerView.css │ │ │ │ │ │ ├── ContainerView.html │ │ │ │ │ │ └── ContainerView.java │ │ │ │ │ └── rows/ │ │ │ │ │ ├── EmptyDropRow.java │ │ │ │ │ ├── EmptyDropRowView.css │ │ │ │ │ ├── EmptyDropRowView.html │ │ │ │ │ ├── EmptyDropRowView.java │ │ │ │ │ ├── Row.java │ │ │ │ │ ├── RowDnDEvent.java │ │ │ │ │ ├── RowDrop.java │ │ │ │ │ ├── RowView.css │ │ │ │ │ ├── RowView.html │ │ │ │ │ └── RowView.java │ │ │ │ ├── event/ │ │ │ │ │ ├── LayoutEditorElementSelectEvent.java │ │ │ │ │ ├── LayoutEditorElementUnselectEvent.java │ │ │ │ │ ├── LayoutElementClearAllPropertiesEvent.java │ │ │ │ │ └── LayoutElementPropertyChangedEvent.java │ │ │ │ ├── generator/ │ │ │ │ │ ├── AbstractLayoutGenerator.java │ │ │ │ │ ├── BootstrapLayoutGenerator.java │ │ │ │ │ ├── BootstrapLayoutGeneratorDriver.java │ │ │ │ │ ├── LayoutGenerator.java │ │ │ │ │ └── LayoutGeneratorDriver.java │ │ │ │ ├── infra/ │ │ │ │ │ ├── BeanHelper.java │ │ │ │ │ ├── ColumnDrop.java │ │ │ │ │ ├── ColumnDropContext.java │ │ │ │ │ ├── ColumnResizeEvent.java │ │ │ │ │ ├── ColumnSizeBuilder.java │ │ │ │ │ ├── ConfigurationContext.java │ │ │ │ │ ├── ContainerResizeEvent.java │ │ │ │ │ ├── DnDManager.java │ │ │ │ │ ├── DndDataJSONConverter.java │ │ │ │ │ ├── DragComponentEndEvent.java │ │ │ │ │ ├── DragHelperComponentColumn.java │ │ │ │ │ ├── HTML5DnDHelper.java │ │ │ │ │ ├── LayoutDragComponentHelper.java │ │ │ │ │ ├── LayoutEditorCssHelper.java │ │ │ │ │ ├── LayoutEditorFocusController.java │ │ │ │ │ ├── LayoutTemplateAdapter.java │ │ │ │ │ ├── NameValidator.java │ │ │ │ │ ├── RowResizeEvent.java │ │ │ │ │ ├── RowSizeBuilder.java │ │ │ │ │ ├── UniqueIDGenerator.java │ │ │ │ │ └── experimental/ │ │ │ │ │ └── DisabledExperimentalLayoutComponent.java │ │ │ │ ├── resources/ │ │ │ │ │ ├── LayoutEditorCss.java │ │ │ │ │ ├── WebAppResource.java │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── CommonConstants.java │ │ │ │ │ ├── CssAllowedValueConstants.java │ │ │ │ │ └── PropertiesConstants.java │ │ │ │ ├── validator/ │ │ │ │ │ ├── LayoutEditorPropertyLengthValidator.java │ │ │ │ │ └── LayoutEditorPropertyNumberValidator.java │ │ │ │ └── widgets/ │ │ │ │ ├── KebabWidget.html │ │ │ │ ├── KebabWidget.java │ │ │ │ ├── LayoutComponentPaletteGroupProvider.java │ │ │ │ ├── LayoutComponentPalettePresenter.java │ │ │ │ ├── LayoutComponentPaletteView.css │ │ │ │ ├── LayoutComponentPaletteView.html │ │ │ │ ├── LayoutComponentPaletteView.java │ │ │ │ ├── LayoutDragComponentGroupPresenter.java │ │ │ │ ├── LayoutDragComponentGroupView.css │ │ │ │ ├── LayoutDragComponentGroupView.html │ │ │ │ ├── LayoutDragComponentGroupView.java │ │ │ │ ├── LayoutDragComponentWidget.html │ │ │ │ ├── LayoutDragComponentWidget.java │ │ │ │ ├── LayoutEditorPropertiesPresenter.java │ │ │ │ ├── LayoutEditorPropertiesView.css │ │ │ │ ├── LayoutEditorPropertiesView.html │ │ │ │ ├── LayoutEditorPropertiesView.java │ │ │ │ ├── LayoutElementPropertiesPresenter.java │ │ │ │ └── LayoutElementPropertiesView.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── layout/ │ │ │ └── editor/ │ │ │ ├── UberfireLayoutEditorClient.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ ├── css/ │ │ │ │ └── layout-editor.css │ │ │ └── i18n/ │ │ │ ├── CommonConstants.properties │ │ │ ├── CommonConstants_de.properties │ │ │ ├── CommonConstants_es.properties │ │ │ ├── CommonConstants_fr.properties │ │ │ ├── CommonConstants_it.properties │ │ │ ├── CommonConstants_ja.properties │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ ├── CommonConstants_zh_CN.properties │ │ │ ├── CssAllowedValueConstants.properties │ │ │ ├── CssAllowedValueConstants_es.properties │ │ │ ├── CssAllowedValueConstants_fr.properties │ │ │ ├── CssAllowedValueConstants_it.properties │ │ │ ├── CssAllowedValueConstants_ja.properties │ │ │ ├── PropertiesConstants.properties │ │ │ ├── PropertiesConstants_de.properties │ │ │ ├── PropertiesConstants_es.properties │ │ │ ├── PropertiesConstants_fr.properties │ │ │ ├── PropertiesConstants_it.properties │ │ │ ├── PropertiesConstants_ja.properties │ │ │ ├── PropertiesConstants_pt_BR.properties │ │ │ └── PropertiesConstants_zh_CN.properties │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── layout/ │ │ │ └── editor/ │ │ │ └── client/ │ │ │ ├── AbstractLayoutEditorTest.java │ │ │ ├── LayoutComponentPalettePresenterTest.java │ │ │ ├── LayoutEditorPluginImplTest.java │ │ │ ├── LayoutEditorPresenterTest.java │ │ │ ├── LayoutEditorPropertiesPresenterTest.java │ │ │ ├── LayoutElementPropertiesPresenterTest.java │ │ │ ├── components/ │ │ │ │ ├── FullLayoutTest.java │ │ │ │ ├── columns/ │ │ │ │ │ ├── ColumnWithComponentsTest.java │ │ │ │ │ ├── ComponentColumnTest.java │ │ │ │ │ └── ComponentColumnViewTest.java │ │ │ │ ├── container/ │ │ │ │ │ └── ContainerTest.java │ │ │ │ └── rows/ │ │ │ │ └── RowTest.java │ │ │ ├── generator/ │ │ │ │ └── LayoutGeneratorTest.java │ │ │ ├── infra/ │ │ │ │ ├── LayoutDragComponentHelperTest.java │ │ │ │ ├── LayoutEditorCssHelperTest.java │ │ │ │ ├── LayoutEditorFocusControllerTest.java │ │ │ │ └── UniqueIDGeneratorTest.java │ │ │ └── test/ │ │ │ ├── TestLayoutComponentPaletteGroupProvider.java │ │ │ ├── TestLayoutDragComponent.java │ │ │ ├── group1/ │ │ │ │ ├── Group1LayoutComponentPaletteGroupProvider.java │ │ │ │ ├── Group1LayoutDragComponent1.java │ │ │ │ ├── Group1LayoutDragComponent2.java │ │ │ │ └── Group1LayoutDragComponent3.java │ │ │ ├── group2/ │ │ │ │ ├── Group2LayoutComponentPaletteGroupProvider.java │ │ │ │ ├── Group2LayoutDragComponent1.java │ │ │ │ └── Group2LayoutDragComponent2.java │ │ │ └── group3/ │ │ │ ├── Group3LayoutComponentPaletteGroupProvider.java │ │ │ └── Group3LayoutDragComponent1.java │ │ └── resources/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── layout/ │ │ └── editor/ │ │ └── client/ │ │ ├── columnWithComponentsLayout.txt │ │ ├── fullLayoutFluid.txt │ │ ├── fullLayoutPage.txt │ │ ├── sampleFullFluidLayout.txt │ │ ├── sampleFullPageLayout.txt │ │ ├── singleRowComponentLayout.txt │ │ ├── singleRowComponentLayoutWithParts.txt │ │ └── singleRowTwoComponentsLayout.txt │ ├── uberfire-metadata/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-metadata-api/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── metadata/ │ │ │ ├── MetadataConfig.java │ │ │ ├── engine/ │ │ │ │ ├── BatchIndexListener.java │ │ │ │ ├── Index.java │ │ │ │ ├── IndexManager.java │ │ │ │ ├── Indexer.java │ │ │ │ ├── IndexerScheduler.java │ │ │ │ ├── MetaIndexEngine.java │ │ │ │ ├── MetaModelStore.java │ │ │ │ └── Observer.java │ │ │ ├── event/ │ │ │ │ ├── BatchIndexEvent.java │ │ │ │ └── IndexEvent.java │ │ │ ├── metamodel/ │ │ │ │ ├── InMemoryMetaModelStore.java │ │ │ │ ├── MetaModelBuilder.java │ │ │ │ └── NullMetaModelStore.java │ │ │ ├── model/ │ │ │ │ ├── KCluster.java │ │ │ │ ├── KObject.java │ │ │ │ ├── KObjectId.java │ │ │ │ ├── KObjectKey.java │ │ │ │ ├── KObjectSimpleKey.java │ │ │ │ ├── KProperty.java │ │ │ │ ├── PropertyBag.java │ │ │ │ ├── impl/ │ │ │ │ │ ├── KObjectImpl.java │ │ │ │ │ ├── KObjectKeyImpl.java │ │ │ │ │ ├── KPropertyImpl.java │ │ │ │ │ ├── MetaObjectImpl.java │ │ │ │ │ └── MetaPropertyImpl.java │ │ │ │ └── schema/ │ │ │ │ ├── MetaObject.java │ │ │ │ ├── MetaProperty.java │ │ │ │ └── MetaType.java │ │ │ ├── provider/ │ │ │ │ └── IndexProvider.java │ │ │ └── search/ │ │ │ ├── ClusterSegment.java │ │ │ ├── DateRange.java │ │ │ ├── IOSearchService.java │ │ │ └── SearchIndex.java │ │ ├── uberfire-metadata-backends/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ ├── uberfire-metadata-backend-infinispan/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── metadata/ │ │ │ │ │ │ └── backend/ │ │ │ │ │ │ └── infinispan/ │ │ │ │ │ │ ├── InfinispanSearchConfig.java │ │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ │ ├── InfinispanException.java │ │ │ │ │ │ │ └── RetryException.java │ │ │ │ │ │ ├── ickl/ │ │ │ │ │ │ │ ├── FieldConverter.java │ │ │ │ │ │ │ ├── FieldConverterImpl.java │ │ │ │ │ │ │ ├── IckleConverter.java │ │ │ │ │ │ │ └── converters/ │ │ │ │ │ │ │ ├── BooleanQueryConverter.java │ │ │ │ │ │ │ ├── QueryConverter.java │ │ │ │ │ │ │ ├── RegexpQueryConverter.java │ │ │ │ │ │ │ ├── TermQueryConverter.java │ │ │ │ │ │ │ └── WildcardQueryConverter.java │ │ │ │ │ │ ├── proto/ │ │ │ │ │ │ │ ├── KObjectMarshaller.java │ │ │ │ │ │ │ └── schema/ │ │ │ │ │ │ │ ├── Field.java │ │ │ │ │ │ │ ├── Message.java │ │ │ │ │ │ │ ├── ProtobufScope.java │ │ │ │ │ │ │ ├── ProtobufType.java │ │ │ │ │ │ │ ├── Schema.java │ │ │ │ │ │ │ └── SchemaGenerator.java │ │ │ │ │ │ ├── provider/ │ │ │ │ │ │ │ ├── InfinispanConfiguration.java │ │ │ │ │ │ │ ├── InfinispanContext.java │ │ │ │ │ │ │ ├── InfinispanIndexProvider.java │ │ │ │ │ │ │ ├── InfinispanPingService.java │ │ │ │ │ │ │ ├── InfinispanSchemaStore.java │ │ │ │ │ │ │ ├── KieProtostreamMarshaller.java │ │ │ │ │ │ │ ├── LoginHandler.java │ │ │ │ │ │ │ └── MappingProvider.java │ │ │ │ │ │ ├── search/ │ │ │ │ │ │ │ └── InfinispanSearchIndex.java │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ ├── AttributesUtil.java │ │ │ │ │ │ ├── InfinispanFieldNames.java │ │ │ │ │ │ └── Retry.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── clustered.xml │ │ │ │ │ ├── infinispan-indexed-template.xml │ │ │ │ │ └── infinispan-non-indexed-template.xml │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── metadata/ │ │ │ │ │ └── backend/ │ │ │ │ │ └── infinispan/ │ │ │ │ │ ├── ickl/ │ │ │ │ │ │ ├── IcklConverterTest.java │ │ │ │ │ │ └── converters/ │ │ │ │ │ │ ├── BooleanQueryConverterTest.java │ │ │ │ │ │ ├── TermQueryConverterTest.java │ │ │ │ │ │ └── WildcardQueryConverterTest.java │ │ │ │ │ ├── proto/ │ │ │ │ │ │ └── schema/ │ │ │ │ │ │ └── SchemaGeneratorTest.java │ │ │ │ │ ├── provider/ │ │ │ │ │ │ ├── InfinispanContextTest.java │ │ │ │ │ │ ├── InfinispanPingServiceTest.java │ │ │ │ │ │ ├── InfinispanSchemaStoreTest.java │ │ │ │ │ │ └── KieProtostreamMarshallerTest.java │ │ │ │ │ └── utils/ │ │ │ │ │ ├── AttributesUtilTest.java │ │ │ │ │ └── RetryTest.java │ │ │ │ └── resources/ │ │ │ │ ├── infinispan.xml │ │ │ │ ├── log4j.xml │ │ │ │ ├── logback.xml │ │ │ │ └── proto/ │ │ │ │ ├── multi-field-message.proto │ │ │ │ ├── schema.proto │ │ │ │ └── single-field-message.proto │ │ │ └── uberfire-metadata-backend-lucene/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── metadata/ │ │ │ │ └── backend/ │ │ │ │ └── lucene/ │ │ │ │ ├── LuceneConfig.java │ │ │ │ ├── analyzer/ │ │ │ │ │ ├── FilenameAnalyzer.java │ │ │ │ │ └── LowerCaseTokenizer.java │ │ │ │ ├── fields/ │ │ │ │ │ ├── FieldFactory.java │ │ │ │ │ └── SimpleFieldFactory.java │ │ │ │ ├── index/ │ │ │ │ │ ├── BaseLuceneIndex.java │ │ │ │ │ ├── CustomAnalyzerWrapperFactory.java │ │ │ │ │ ├── LuceneIndex.java │ │ │ │ │ ├── LuceneIndexFactory.java │ │ │ │ │ ├── LuceneIndexManager.java │ │ │ │ │ └── directory/ │ │ │ │ │ ├── DeleteCommand.java │ │ │ │ │ ├── Directory.java │ │ │ │ │ ├── DirectoryFactory.java │ │ │ │ │ ├── DirectoryLuceneIndex.java │ │ │ │ │ └── DirectoryType.java │ │ │ │ ├── model/ │ │ │ │ │ └── KClusterImpl.java │ │ │ │ ├── provider/ │ │ │ │ │ └── LuceneIndexProvider.java │ │ │ │ ├── search/ │ │ │ │ │ └── LuceneSearchIndex.java │ │ │ │ └── util/ │ │ │ │ ├── KObjectUtil.java │ │ │ │ └── Serializer.java │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── metadata/ │ │ │ └── backend/ │ │ │ └── lucene/ │ │ │ └── index/ │ │ │ ├── LuceneIndexManagerTest.java │ │ │ └── directory/ │ │ │ └── DirectoryFactoryTest.java │ │ └── uberfire-metadata-commons-io/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── metadata/ │ │ │ └── io/ │ │ │ ├── BatchIndex.java │ │ │ ├── ConstrainedIndexerScheduler.java │ │ │ ├── CoreIndexer.java │ │ │ ├── DisposedException.java │ │ │ ├── IOSearchServiceImpl.java │ │ │ ├── IOServiceIndexedImpl.java │ │ │ ├── IOServiceIndexedUtil.java │ │ │ ├── IndexableIOEvent.java │ │ │ ├── IndexerDispatcher.java │ │ │ ├── IndexersFactory.java │ │ │ ├── KObjectUtil.java │ │ │ ├── MetadataConfigBuilder.java │ │ │ ├── SimpleIndexerScheduler.java │ │ │ ├── index/ │ │ │ │ └── MetadataIndexEngine.java │ │ │ └── util/ │ │ │ └── MultiIndexerLock.java │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── metadata/ │ │ │ └── io/ │ │ │ ├── BatchIndexKeepFileTest.java │ │ │ ├── IOServiceIndexedTest.java │ │ │ ├── common/ │ │ │ │ ├── ConstrainedIndexerSchedulerTest.java │ │ │ │ ├── MetadataIndexEngineBatchTest.java │ │ │ │ ├── MultiIndexerLockTest.java │ │ │ │ └── util/ │ │ │ │ └── TestFileSystemProvider.java │ │ │ ├── infinispan/ │ │ │ │ ├── BaseIndexTest.java │ │ │ │ ├── BatchIndexConcurrencyTest.java │ │ │ │ ├── BatchIndexSingleThreadTest.java │ │ │ │ ├── BatchIndexTest.java │ │ │ │ ├── ComplexFieldsTest.java │ │ │ │ ├── FullTextSearchIndexTest.java │ │ │ │ ├── IOSearchServiceImplTest.java │ │ │ │ ├── IOServiceIndexedDeleteFileTest.java │ │ │ │ ├── IOServiceIndexedDotFileGitImplTest.java │ │ │ │ ├── IOServiceIndexedDotFileGitInternalImplTest.java │ │ │ │ ├── IOServiceIndexedGitImplTest.java │ │ │ │ ├── IOServiceIndexedSortingTest.java │ │ │ │ ├── IndexTest.java │ │ │ │ ├── ReplaceIndexedObjectTest.java │ │ │ │ └── suite/ │ │ │ │ ├── InfinispanTestProperties.java │ │ │ │ └── InfinispanTestSuite.java │ │ │ └── lucene/ │ │ │ ├── BaseIndexTest.java │ │ │ ├── BatchIndexConcurrencyTest.java │ │ │ ├── BatchIndexSingleThreadTest.java │ │ │ ├── BatchIndexTest.java │ │ │ ├── IOSearchServiceImplTest.java │ │ │ ├── IOServiceIndexedDeleteFileTest.java │ │ │ ├── IOServiceIndexedDotFileGitImplTest.java │ │ │ ├── IOServiceIndexedDotFileGitInternalImplTest.java │ │ │ ├── IOServiceIndexedGitImplTest.java │ │ │ ├── IOServiceIndexedSortingTest.java │ │ │ ├── LuceneFullTextSearchIndexTest.java │ │ │ └── LuceneSearchIndexTest.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ ├── byteman/ │ │ │ ├── elastic.btm │ │ │ ├── infinispan.btm │ │ │ └── lucene.btm │ │ ├── ispn.properties │ │ ├── log4j.properties │ │ └── logback-test.xml │ ├── uberfire-preferences-ui-client/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── preferences/ │ │ │ │ └── client/ │ │ │ │ ├── PreferencesEntryPoint.java │ │ │ │ ├── admin/ │ │ │ │ │ ├── AdminPagePerspective.java │ │ │ │ │ ├── AdminPagePresenter.java │ │ │ │ │ ├── AdminPageView.css │ │ │ │ │ ├── AdminPageView.html │ │ │ │ │ ├── AdminPageView.java │ │ │ │ │ ├── category/ │ │ │ │ │ │ ├── AdminPageCategoryPresenter.java │ │ │ │ │ │ ├── AdminPageCategoryView.css │ │ │ │ │ │ ├── AdminPageCategoryView.html │ │ │ │ │ │ └── AdminPageCategoryView.java │ │ │ │ │ ├── item/ │ │ │ │ │ │ ├── AdminPageItemPresenter.java │ │ │ │ │ │ ├── AdminPageItemView.css │ │ │ │ │ │ ├── AdminPageItemView.html │ │ │ │ │ │ └── AdminPageItemView.java │ │ │ │ │ └── page/ │ │ │ │ │ ├── AdminPage.java │ │ │ │ │ ├── AdminPageImpl.java │ │ │ │ │ ├── AdminPageOptions.java │ │ │ │ │ └── AdminTool.java │ │ │ │ ├── annotations/ │ │ │ │ │ └── PreferenceForm.java │ │ │ │ ├── base/ │ │ │ │ │ └── BasePreferenceForm.java │ │ │ │ ├── central/ │ │ │ │ │ ├── PreferencesCentralNavBarScreen.java │ │ │ │ │ ├── PreferencesCentralPerspective.java │ │ │ │ │ ├── actions/ │ │ │ │ │ │ ├── PreferencesCentralActionsScreen.java │ │ │ │ │ │ ├── PreferencesCentralActionsView.css │ │ │ │ │ │ ├── PreferencesCentralActionsView.html │ │ │ │ │ │ └── PreferencesCentralActionsView.java │ │ │ │ │ ├── form/ │ │ │ │ │ │ ├── DefaultPreferenceForm.java │ │ │ │ │ │ ├── DefaultPreferenceFormView.html │ │ │ │ │ │ └── DefaultPreferenceFormView.java │ │ │ │ │ ├── hierarchy/ │ │ │ │ │ │ ├── HierarchyInternalItemPresenter.java │ │ │ │ │ │ ├── HierarchyItemPresenter.java │ │ │ │ │ │ ├── HierarchyItemView.java │ │ │ │ │ │ ├── HierarchyLeafItemPresenter.java │ │ │ │ │ │ ├── HierarchyStructurePresenter.java │ │ │ │ │ │ └── HierarchyStructureView.java │ │ │ │ │ ├── screen/ │ │ │ │ │ │ ├── PreferencesRootScreen.java │ │ │ │ │ │ ├── PreferencesRootView.html │ │ │ │ │ │ ├── PreferencesRootView.java │ │ │ │ │ │ └── PreferencesRootView.less │ │ │ │ │ └── tree/ │ │ │ │ │ ├── TreeHierarchyInternalItemPresenter.java │ │ │ │ │ ├── TreeHierarchyInternalItemView.css │ │ │ │ │ ├── TreeHierarchyInternalItemView.html │ │ │ │ │ ├── TreeHierarchyInternalItemView.java │ │ │ │ │ ├── TreeHierarchyLeafItemPresenter.java │ │ │ │ │ ├── TreeHierarchyLeafItemView.css │ │ │ │ │ ├── TreeHierarchyLeafItemView.html │ │ │ │ │ ├── TreeHierarchyLeafItemView.java │ │ │ │ │ ├── TreeHierarchyStructurePresenter.java │ │ │ │ │ ├── TreeHierarchyStructureView.css │ │ │ │ │ ├── TreeHierarchyStructureView.html │ │ │ │ │ ├── TreeHierarchyStructureView.java │ │ │ │ │ └── TreeView.java │ │ │ │ ├── event/ │ │ │ │ │ ├── AbstractHierarchyItemEvent.java │ │ │ │ │ ├── HierarchyItemFormInitializationEvent.java │ │ │ │ │ ├── HierarchyItemSelectedEvent.java │ │ │ │ │ ├── PreferencesCentralActionsConfigurationEvent.java │ │ │ │ │ ├── PreferencesCentralInitializationEvent.java │ │ │ │ │ ├── PreferencesCentralPreSaveEvent.java │ │ │ │ │ ├── PreferencesCentralSaveEvent.java │ │ │ │ │ └── PreferencesCentralUndoChangesEvent.java │ │ │ │ ├── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ └── Constants.java │ │ │ │ └── utils/ │ │ │ │ └── PreferenceFormBeansInfo.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── preferences/ │ │ │ ├── UberfirePreferences.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ └── i18n/ │ │ │ ├── Constants.properties │ │ │ ├── Constants_de.properties │ │ │ ├── Constants_es.properties │ │ │ ├── Constants_fr.properties │ │ │ ├── Constants_it.properties │ │ │ ├── Constants_ja.properties │ │ │ ├── Constants_pt_BR.properties │ │ │ └── Constants_zh_CN.properties │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── preferences/ │ │ └── client/ │ │ ├── admin/ │ │ │ ├── AdminPagePerspectiveTest.java │ │ │ ├── AdminPagePresenterTest.java │ │ │ ├── category/ │ │ │ │ └── AdminPageCategoryPresenterTest.java │ │ │ ├── item/ │ │ │ │ └── AdminPageItemPresenterTest.java │ │ │ └── page/ │ │ │ └── AdminPageImplTest.java │ │ ├── base/ │ │ │ └── BasePreferenceFormTest.java │ │ ├── central/ │ │ │ ├── actions/ │ │ │ │ └── PreferencesCentralActionsScreenTest.java │ │ │ ├── form/ │ │ │ │ ├── DefaultPreferenceFormTest.java │ │ │ │ └── EnumForComboTest.java │ │ │ ├── screen/ │ │ │ │ └── PreferencesRootScreenTest.java │ │ │ └── tree/ │ │ │ └── TreeHierarchyStructurePresenterTest.java │ │ └── utils/ │ │ └── PreferenceFormBeansInfoTest.java │ ├── uberfire-runtime-plugins/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-runtime-plugins-api/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── plugin/ │ │ │ │ ├── event/ │ │ │ │ │ ├── BasePluginEvent.java │ │ │ │ │ ├── MediaAdded.java │ │ │ │ │ ├── MediaDeleted.java │ │ │ │ │ ├── NewPluginRegistered.java │ │ │ │ │ ├── PluginAdded.java │ │ │ │ │ ├── PluginDeleted.java │ │ │ │ │ ├── PluginRenamed.java │ │ │ │ │ ├── PluginSaved.java │ │ │ │ │ └── PluginUnregistered.java │ │ │ │ ├── exception/ │ │ │ │ │ └── PluginAlreadyExists.java │ │ │ │ ├── model/ │ │ │ │ │ ├── Activity.java │ │ │ │ │ ├── CodeType.java │ │ │ │ │ ├── DynamicMenu.java │ │ │ │ │ ├── DynamicMenuItem.java │ │ │ │ │ ├── Framework.java │ │ │ │ │ ├── Language.java │ │ │ │ │ ├── LayoutEditorModel.java │ │ │ │ │ ├── Media.java │ │ │ │ │ ├── Plugin.java │ │ │ │ │ ├── PluginContent.java │ │ │ │ │ ├── PluginSimpleContent.java │ │ │ │ │ ├── PluginType.java │ │ │ │ │ └── RuntimePlugin.java │ │ │ │ ├── service/ │ │ │ │ │ └── PluginServices.java │ │ │ │ └── type/ │ │ │ │ ├── BasePluginResourceTypeDefinition.java │ │ │ │ ├── DynamicMenuResourceTypeDefinition.java │ │ │ │ ├── EditorPluginResourceTypeDefinition.java │ │ │ │ ├── PerspectiveLayoutPluginResourceTypeDefinition.java │ │ │ │ ├── ScreenPluginResourceTypeDefinition.java │ │ │ │ ├── SplashPluginResourceTypeDefinition.java │ │ │ │ ├── TagsConverterUtil.java │ │ │ │ └── TypeConverterUtil.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── plugin/ │ │ │ └── RuntimePluginAPI.gwt.xml │ │ ├── uberfire-runtime-plugins-backend/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── plugin/ │ │ │ │ │ └── backend/ │ │ │ │ │ ├── JSRegistry.java │ │ │ │ │ ├── MediaServletURI.java │ │ │ │ │ ├── MediaServletURIProducer.java │ │ │ │ │ ├── PluginMediaServlet.java │ │ │ │ │ └── PluginServicesImpl.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── beans.xml │ │ │ │ └── frameworks/ │ │ │ │ ├── angular.dependency │ │ │ │ └── knockout.dependency │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── plugin/ │ │ │ │ └── backend/ │ │ │ │ ├── JSRegistryTest.java │ │ │ │ ├── MediaServletURIProducerTest.java │ │ │ │ ├── PluginMediaServletTest.java │ │ │ │ ├── PluginSamples.java │ │ │ │ └── PluginServicesImplTest.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── services/ │ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── plugin/ │ │ │ └── backend/ │ │ │ ├── angular_css.txt │ │ │ ├── angular_main.txt │ │ │ ├── angular_template.txt │ │ │ ├── angular_todo_registry.txt │ │ │ ├── empty_screen_registry.txt │ │ │ ├── screen_with_title_and_name_registry.txt │ │ │ ├── screen_with_title_registry.txt │ │ │ ├── splash_main.txt │ │ │ ├── splash_screen_registry.txt │ │ │ └── splash_template.txt │ │ └── uberfire-runtime-plugins-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── plugin/ │ │ │ │ └── client/ │ │ │ │ ├── RuntimePluginsEntryPoint.java │ │ │ │ ├── code/ │ │ │ │ │ ├── CodeElement.java │ │ │ │ │ └── CodeList.java │ │ │ │ ├── config/ │ │ │ │ │ └── PluginConfigService.java │ │ │ │ ├── editor/ │ │ │ │ │ ├── DynamicMenuEditorPresenter.java │ │ │ │ │ ├── DynamicMenuEditorView.java │ │ │ │ │ ├── DynamicMenuEditorView.ui.xml │ │ │ │ │ ├── EditorPlugInEditorPresenter.java │ │ │ │ │ ├── EditorPlugInEditorView.java │ │ │ │ │ ├── EditorPlugInEditorView.ui.xml │ │ │ │ │ ├── RuntimePluginBaseEditor.java │ │ │ │ │ ├── RuntimePluginBaseView.java │ │ │ │ │ ├── ScreenEditorPresenter.java │ │ │ │ │ ├── ScreenEditorView.java │ │ │ │ │ ├── ScreenEditorView.ui.xml │ │ │ │ │ ├── SplashEditorPresenter.java │ │ │ │ │ ├── SplashEditorView.java │ │ │ │ │ └── SplashEditorView.ui.xml │ │ │ │ ├── explorer/ │ │ │ │ │ ├── PluginExplorerScreen.java │ │ │ │ │ └── PluginExplorerScreen.ui.xml │ │ │ │ ├── info/ │ │ │ │ │ └── PluginsInfo.java │ │ │ │ ├── perspective/ │ │ │ │ │ ├── PlugInAuthoringPerspective.java │ │ │ │ │ └── editor/ │ │ │ │ │ ├── PerspectiveEditorPresenter.java │ │ │ │ │ ├── PerspectiveEditorView.java │ │ │ │ │ ├── PerspectiveEditorView.ui.xml │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── PerspectiveEditorComponentGroupProvider.java │ │ │ │ │ │ ├── PerspectiveEditorCoreComponent.java │ │ │ │ │ │ ├── PerspectiveEditorCoreGroupProvider.java │ │ │ │ │ │ ├── PerspectiveEditorNavComponent.java │ │ │ │ │ │ └── PerspectiveEditorNavGroupProvider.java │ │ │ │ │ ├── components/ │ │ │ │ │ │ └── popup/ │ │ │ │ │ │ ├── AddTag.java │ │ │ │ │ │ └── AddTag.ui.xml │ │ │ │ │ ├── events/ │ │ │ │ │ │ └── PerspectiveEditorFocusEvent.java │ │ │ │ │ ├── generator/ │ │ │ │ │ │ ├── PerspectiveEditorActivity.java │ │ │ │ │ │ ├── PerspectiveEditorGenerator.java │ │ │ │ │ │ └── PerspectiveEditorScreenActivity.java │ │ │ │ │ └── layout/ │ │ │ │ │ └── editor/ │ │ │ │ │ ├── HTMLLayoutDragComponent.java │ │ │ │ │ ├── PerspectiveEditorSettings.java │ │ │ │ │ ├── ScreenLayoutDragComponent.java │ │ │ │ │ ├── TargetDivDragComponent.java │ │ │ │ │ ├── TargetDivList.java │ │ │ │ │ └── popups/ │ │ │ │ │ ├── EditHTMLPresenter.java │ │ │ │ │ ├── EditHTMLView.html │ │ │ │ │ ├── EditHTMLView.java │ │ │ │ │ ├── EditScreen.java │ │ │ │ │ ├── EditScreen.ui.xml │ │ │ │ │ ├── EditTargetDiv.java │ │ │ │ │ └── EditTargetDiv.ui.xml │ │ │ │ ├── plugins/ │ │ │ │ │ └── RuntimePluginStartup.java │ │ │ │ ├── resources/ │ │ │ │ │ ├── PluginCss.java │ │ │ │ │ ├── WebAppResource.java │ │ │ │ │ ├── css/ │ │ │ │ │ │ └── plugin.css │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── CommonConstants.java │ │ │ │ │ ├── Constants.java │ │ │ │ │ ├── PerspectiveEditorPaletteConstants.java │ │ │ │ │ ├── PerspectiveEditorPaletteI18n.java │ │ │ │ │ └── PerspectiveEditorPaletteI18nImpl.java │ │ │ │ ├── security/ │ │ │ │ │ └── PluginController.java │ │ │ │ ├── type/ │ │ │ │ │ ├── DynamicMenuResourceType.java │ │ │ │ │ ├── EditorPluginResourceType.java │ │ │ │ │ ├── PerspectiveLayoutPluginResourceType.java │ │ │ │ │ ├── ScreenPluginResourceType.java │ │ │ │ │ └── SplashPluginResourceType.java │ │ │ │ ├── validation/ │ │ │ │ │ ├── NameValidator.java │ │ │ │ │ ├── PluginNameValidator.java │ │ │ │ │ └── RuleValidator.java │ │ │ │ └── widget/ │ │ │ │ ├── cell/ │ │ │ │ │ └── IconCell.java │ │ │ │ ├── media/ │ │ │ │ │ ├── MediaLibraryWidget.java │ │ │ │ │ └── MediaLibraryWidget.ui.xml │ │ │ │ ├── navigator/ │ │ │ │ │ ├── PluginNavList.java │ │ │ │ │ └── PluginNavList.ui.xml │ │ │ │ ├── plugin/ │ │ │ │ │ ├── GeneralPluginEditor.java │ │ │ │ │ └── GeneralPluginEditor.ui.xml │ │ │ │ ├── popup/ │ │ │ │ │ ├── NewPluginPopUp.java │ │ │ │ │ ├── NewPluginPopUpView.java │ │ │ │ │ ├── NewPluginPopUpViewImpl.java │ │ │ │ │ └── NewPluginPopUpViewImpl.ui.xml │ │ │ │ └── split/ │ │ │ │ ├── HorizontalSplit.java │ │ │ │ ├── Splitter.java │ │ │ │ └── VerticalSplit.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── plugin/ │ │ │ ├── RuntimePluginClient.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ └── i18n/ │ │ │ ├── CommonConstants.properties │ │ │ ├── CommonConstants_de.properties │ │ │ ├── CommonConstants_es.properties │ │ │ ├── CommonConstants_fr.properties │ │ │ ├── CommonConstants_it.properties │ │ │ ├── CommonConstants_ja.properties │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ ├── CommonConstants_zh_CN.properties │ │ │ ├── Constants.properties │ │ │ ├── Constants_es.properties │ │ │ ├── Constants_fr.properties │ │ │ ├── Constants_it.properties │ │ │ ├── Constants_ja.properties │ │ │ ├── PerspectiveEditorPaletteConstants.properties │ │ │ ├── PerspectiveEditorPaletteConstants_es.properties │ │ │ ├── PerspectiveEditorPaletteConstants_fr.properties │ │ │ ├── PerspectiveEditorPaletteConstants_it.properties │ │ │ └── PerspectiveEditorPaletteConstants_ja.properties │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── plugin/ │ │ │ └── client/ │ │ │ ├── editor/ │ │ │ │ ├── DynamicMenuEditorPresenterTest.java │ │ │ │ ├── DynamicMenuUpdateIndexTest.java │ │ │ │ └── RuntimePluginBaseEditorTest.java │ │ │ ├── info/ │ │ │ │ └── PluginsInfoTest.java │ │ │ ├── perspective/ │ │ │ │ └── editor/ │ │ │ │ ├── PerspectiveEditorPresenterTest.java │ │ │ │ ├── generator/ │ │ │ │ │ └── PerspectiveEditorGeneratorTest.java │ │ │ │ └── layout/ │ │ │ │ └── editor/ │ │ │ │ ├── ScreenLayoutDragComponentTest.java │ │ │ │ ├── TargetDivListTest.java │ │ │ │ └── popups/ │ │ │ │ ├── EditHTMLPresenterTest.java │ │ │ │ └── EditScreenTest.java │ │ │ ├── validation/ │ │ │ │ ├── NameValidatorTest.java │ │ │ │ ├── PluginNameValidatorTest.java │ │ │ │ └── RuleValidatorTest.java │ │ │ └── widget/ │ │ │ ├── media/ │ │ │ │ └── MediaLibraryWidgetTest.java │ │ │ ├── plugin/ │ │ │ │ └── GeneralPluginEditorTest.java │ │ │ └── popup/ │ │ │ └── NewPluginPopUpTest.java │ │ └── resources/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── plugin/ │ │ └── client/ │ │ └── perspective/ │ │ └── editor/ │ │ └── layout/ │ │ └── editor/ │ │ └── fullLayoutPage.txt │ ├── uberfire-security/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-security-management/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── pom.xml │ │ │ ├── uberfire-security-management-api/ │ │ │ │ ├── .gitignore │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── security/ │ │ │ │ │ │ └── management/ │ │ │ │ │ │ ├── api/ │ │ │ │ │ │ │ ├── AbstractEntityManager.java │ │ │ │ │ │ │ ├── Capability.java │ │ │ │ │ │ │ ├── CapabilityStatus.java │ │ │ │ │ │ │ ├── ContextualManager.java │ │ │ │ │ │ │ ├── GroupManager.java │ │ │ │ │ │ │ ├── GroupManagerSettings.java │ │ │ │ │ │ │ ├── RoleManager.java │ │ │ │ │ │ │ ├── RoleManagerSettings.java │ │ │ │ │ │ │ ├── Settings.java │ │ │ │ │ │ │ ├── UserManagementService.java │ │ │ │ │ │ │ ├── UserManager.java │ │ │ │ │ │ │ ├── UserManagerSettings.java │ │ │ │ │ │ │ ├── UserSystemManager.java │ │ │ │ │ │ │ ├── event/ │ │ │ │ │ │ │ │ └── UserDeletedEvent.java │ │ │ │ │ │ │ ├── exception/ │ │ │ │ │ │ │ │ ├── ClientNotFoundException.java │ │ │ │ │ │ │ │ ├── EntityNotFoundException.java │ │ │ │ │ │ │ │ ├── GroupNotFoundException.java │ │ │ │ │ │ │ │ ├── InvalidEntityIdentifierException.java │ │ │ │ │ │ │ │ ├── NoImplementationAvailableException.java │ │ │ │ │ │ │ │ ├── OperationFailedException.java │ │ │ │ │ │ │ │ ├── RealmManagementNotAuthorizedException.java │ │ │ │ │ │ │ │ ├── SecurityManagementException.java │ │ │ │ │ │ │ │ ├── UnsupportedServiceCapabilityException.java │ │ │ │ │ │ │ │ ├── UserAlreadyExistsException.java │ │ │ │ │ │ │ │ └── UserNotFoundException.java │ │ │ │ │ │ │ ├── service/ │ │ │ │ │ │ │ │ ├── GroupManagerService.java │ │ │ │ │ │ │ │ ├── RoleManagerService.java │ │ │ │ │ │ │ │ └── UserManagerService.java │ │ │ │ │ │ │ └── validation/ │ │ │ │ │ │ │ ├── EntityValidator.java │ │ │ │ │ │ │ ├── GroupValidator.java │ │ │ │ │ │ │ ├── RoleValidator.java │ │ │ │ │ │ │ └── UserValidator.java │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── GroupManagerSettingsImpl.java │ │ │ │ │ │ ├── RoleManagerSettingsImpl.java │ │ │ │ │ │ ├── SearchRequestImpl.java │ │ │ │ │ │ ├── SearchResponseImpl.java │ │ │ │ │ │ ├── SettingsImpl.java │ │ │ │ │ │ ├── UserAttributeImpl.java │ │ │ │ │ │ └── UserManagerSettingsImpl.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── security/ │ │ │ │ │ └── management/ │ │ │ │ │ └── UberfireSecurityManagementAPI.gwt.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── security/ │ │ │ │ └── management/ │ │ │ │ └── api/ │ │ │ │ └── validation/ │ │ │ │ ├── GroupValidatorTest.java │ │ │ │ └── UserValidatorTest.java │ │ │ ├── uberfire-security-management-backend/ │ │ │ │ ├── .gitignore │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── security/ │ │ │ │ │ │ └── management/ │ │ │ │ │ │ ├── BackendUserSystemManager.java │ │ │ │ │ │ ├── UberfireRoleManager.java │ │ │ │ │ │ ├── search/ │ │ │ │ │ │ │ ├── AbstractRuntimeSearchEngine.java │ │ │ │ │ │ │ ├── GroupsIdentifierRuntimeSearchEngine.java │ │ │ │ │ │ │ ├── GroupsRuntimeSearchEngine.java │ │ │ │ │ │ │ ├── IdentifierRuntimeSearchEngine.java │ │ │ │ │ │ │ ├── RolesRuntimeSearchEngine.java │ │ │ │ │ │ │ ├── RuntimeSearchEngine.java │ │ │ │ │ │ │ ├── UsersIdentifierRuntimeSearchEngine.java │ │ │ │ │ │ │ └── UsersRuntimeSearchEngine.java │ │ │ │ │ │ ├── service/ │ │ │ │ │ │ │ ├── AbstractUserManagementService.java │ │ │ │ │ │ │ ├── GroupManagerServiceImpl.java │ │ │ │ │ │ │ ├── RoleManagerServiceImpl.java │ │ │ │ │ │ │ └── UserManagerServiceImpl.java │ │ │ │ │ │ ├── util/ │ │ │ │ │ │ │ └── SecurityManagementUtils.java │ │ │ │ │ │ └── validation/ │ │ │ │ │ │ ├── GroupValidatorImpl.java │ │ │ │ │ │ ├── RoleValidatorImpl.java │ │ │ │ │ │ └── UserValidatorImpl.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── security/ │ │ │ │ │ └── management/ │ │ │ │ │ └── UberfireSecurityManagementMessages.properties │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── security/ │ │ │ │ └── management/ │ │ │ │ ├── BackendUserSystemManagerTest.java │ │ │ │ ├── BaseTest.java │ │ │ │ ├── UberfireRoleManagerTest.java │ │ │ │ ├── search/ │ │ │ │ │ └── GroupsRuntimeSearchEngineTest.java │ │ │ │ └── util/ │ │ │ │ └── SecurityManagementUtilsTest.java │ │ │ ├── uberfire-security-management-client/ │ │ │ │ ├── .gitignore │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── security/ │ │ │ │ │ │ └── management/ │ │ │ │ │ │ └── client/ │ │ │ │ │ │ ├── ClientSecurityExceptionMessageResolver.java │ │ │ │ │ │ ├── ClientUserSystemManager.java │ │ │ │ │ │ ├── editor/ │ │ │ │ │ │ │ ├── Driver.java │ │ │ │ │ │ │ ├── Editor.java │ │ │ │ │ │ │ ├── HasRestrictedValues.java │ │ │ │ │ │ │ ├── Viewer.java │ │ │ │ │ │ │ ├── group/ │ │ │ │ │ │ │ │ ├── GroupEditor.java │ │ │ │ │ │ │ │ └── GroupEditorDriver.java │ │ │ │ │ │ │ ├── role/ │ │ │ │ │ │ │ │ ├── RoleEditor.java │ │ │ │ │ │ │ │ └── RoleEditorDriver.java │ │ │ │ │ │ │ └── user/ │ │ │ │ │ │ │ ├── UserAssignedGroupsEditor.java │ │ │ │ │ │ │ ├── UserAssignedGroupsExplorer.java │ │ │ │ │ │ │ ├── UserAssignedRolesEditor.java │ │ │ │ │ │ │ ├── UserAssignedRolesExplorer.java │ │ │ │ │ │ │ ├── UserAttributesEditor.java │ │ │ │ │ │ │ ├── UserEditor.java │ │ │ │ │ │ │ └── UserEditorDriver.java │ │ │ │ │ │ ├── resources/ │ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ │ └── UsersManagementClientConstants.java │ │ │ │ │ │ └── validation/ │ │ │ │ │ │ ├── ClientGroupValidator.java │ │ │ │ │ │ ├── ClientRoleValidator.java │ │ │ │ │ │ └── ClientUserValidator.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── security/ │ │ │ │ │ └── management/ │ │ │ │ │ ├── UberfireSecurityManagementClient.gwt.xml │ │ │ │ │ └── client/ │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── UsersManagementClientConstants.properties │ │ │ │ │ ├── UsersManagementClientConstants_de.properties │ │ │ │ │ ├── UsersManagementClientConstants_es.properties │ │ │ │ │ ├── UsersManagementClientConstants_fr.properties │ │ │ │ │ ├── UsersManagementClientConstants_it.properties │ │ │ │ │ ├── UsersManagementClientConstants_ja.properties │ │ │ │ │ ├── UsersManagementClientConstants_pt_BR.properties │ │ │ │ │ └── UsersManagementClientConstants_zh_CN.properties │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── security/ │ │ │ │ └── management/ │ │ │ │ └── client/ │ │ │ │ ├── ClientSecurityExceptionMessageResolverTest.java │ │ │ │ ├── ClientUserSystemManagerTest.java │ │ │ │ └── editor/ │ │ │ │ └── user/ │ │ │ │ └── UserEditorDriverTest.java │ │ │ ├── uberfire-security-management-client-wb/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── security/ │ │ │ │ │ │ └── management/ │ │ │ │ │ │ └── client/ │ │ │ │ │ │ ├── ResourceBundleEntryPoint.java │ │ │ │ │ │ ├── perspectives/ │ │ │ │ │ │ │ └── SecurityManagementPerspective.java │ │ │ │ │ │ ├── resources/ │ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ │ └── UsersManagementWorkbenchConstants.java │ │ │ │ │ │ └── screens/ │ │ │ │ │ │ ├── BaseScreen.java │ │ │ │ │ │ ├── BaseScreenView.java │ │ │ │ │ │ ├── BaseScreenView.ui.xml │ │ │ │ │ │ ├── editor/ │ │ │ │ │ │ │ ├── GroupEditorScreen.java │ │ │ │ │ │ │ ├── RoleEditorScreen.java │ │ │ │ │ │ │ └── UserEditorScreen.java │ │ │ │ │ │ ├── explorer/ │ │ │ │ │ │ │ ├── SecurityExplorerScreen.java │ │ │ │ │ │ │ ├── SecurityExplorerView.java │ │ │ │ │ │ │ └── SecurityExplorerView.ui.xml │ │ │ │ │ │ └── home/ │ │ │ │ │ │ ├── SecurityManagementHomeScreen.java │ │ │ │ │ │ ├── SecurityManagementHomeView.html │ │ │ │ │ │ └── SecurityManagementHomeView.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── security/ │ │ │ │ │ └── management/ │ │ │ │ │ ├── UberfireSecurityManagementWorkbench.gwt.xml │ │ │ │ │ └── client/ │ │ │ │ │ └── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── SecurityManagementHomeConstants.properties │ │ │ │ │ ├── SecurityManagementHomeConstants_es.properties │ │ │ │ │ ├── SecurityManagementHomeConstants_fr.properties │ │ │ │ │ ├── SecurityManagementHomeConstants_it.properties │ │ │ │ │ ├── SecurityManagementHomeConstants_ja.properties │ │ │ │ │ ├── UsersManagementWorkbenchConstants.properties │ │ │ │ │ ├── UsersManagementWorkbenchConstants_de.properties │ │ │ │ │ ├── UsersManagementWorkbenchConstants_es.properties │ │ │ │ │ ├── UsersManagementWorkbenchConstants_fr.properties │ │ │ │ │ ├── UsersManagementWorkbenchConstants_it.properties │ │ │ │ │ ├── UsersManagementWorkbenchConstants_ja.properties │ │ │ │ │ ├── UsersManagementWorkbenchConstants_pt_BR.properties │ │ │ │ │ └── UsersManagementWorkbenchConstants_zh_CN.properties │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── security/ │ │ │ │ └── management/ │ │ │ │ └── client/ │ │ │ │ ├── perspectives/ │ │ │ │ │ └── SecurityManagementPerspectiveTest.java │ │ │ │ └── screens/ │ │ │ │ ├── editor/ │ │ │ │ │ ├── GroupEditorScreenTest.java │ │ │ │ │ ├── RoleEditorScreenTest.java │ │ │ │ │ └── UserEditorScreenTest.java │ │ │ │ └── explorer/ │ │ │ │ └── SecurityExplorerScreenTest.java │ │ │ ├── uberfire-security-management-keycloak/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── security/ │ │ │ │ │ │ └── management/ │ │ │ │ │ │ └── keycloak/ │ │ │ │ │ │ ├── BaseClientFactory.java │ │ │ │ │ │ ├── BaseKeyCloakManager.java │ │ │ │ │ │ ├── CredentialsClientFactory.java │ │ │ │ │ │ ├── KCAdapterClientFactory.java │ │ │ │ │ │ ├── KCAdapterUserManagementService.java │ │ │ │ │ │ ├── KCCredentialsUserManagementService.java │ │ │ │ │ │ ├── KeyCloakGroupManager.java │ │ │ │ │ │ ├── KeyCloakUserManager.java │ │ │ │ │ │ ├── client/ │ │ │ │ │ │ │ ├── ClientFactory.java │ │ │ │ │ │ │ ├── Keycloak.java │ │ │ │ │ │ │ ├── auth/ │ │ │ │ │ │ │ │ ├── BearerAuthenticationInterceptor.java │ │ │ │ │ │ │ │ ├── TokenManager.java │ │ │ │ │ │ │ │ ├── TokenService.java │ │ │ │ │ │ │ │ ├── adapter/ │ │ │ │ │ │ │ │ │ └── KCAdapterContextTokenManager.java │ │ │ │ │ │ │ │ └── credentials/ │ │ │ │ │ │ │ │ ├── AccessTokenResponse.java │ │ │ │ │ │ │ │ ├── AuthSettings.java │ │ │ │ │ │ │ │ └── AuthTokenManager.java │ │ │ │ │ │ │ └── resource/ │ │ │ │ │ │ │ ├── ClientResource.java │ │ │ │ │ │ │ ├── ClientsResource.java │ │ │ │ │ │ │ ├── RealmResource.java │ │ │ │ │ │ │ ├── RealmsResource.java │ │ │ │ │ │ │ ├── RoleMappingResource.java │ │ │ │ │ │ │ ├── RoleResource.java │ │ │ │ │ │ │ ├── RoleScopeResource.java │ │ │ │ │ │ │ ├── RolesResource.java │ │ │ │ │ │ │ ├── UserResource.java │ │ │ │ │ │ │ └── UsersResource.java │ │ │ │ │ │ └── elytron/ │ │ │ │ │ │ ├── KeyCloakElytronIdentityHelper.java │ │ │ │ │ │ └── KeyCloakElytronIdentityHelperProducer.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ └── beans.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── security/ │ │ │ │ └── management/ │ │ │ │ └── keycloak/ │ │ │ │ ├── BaseKeyCloakTest.java │ │ │ │ ├── DefaultKeyCloakTest.java │ │ │ │ ├── KCCredentialsUserManagementServiceTest.java │ │ │ │ ├── KCSSOUserManagementServiceTest.java │ │ │ │ ├── KeyCloakGroupManagerTest.java │ │ │ │ ├── KeyCloakUserManagerTest.java │ │ │ │ ├── client/ │ │ │ │ │ └── auth/ │ │ │ │ │ ├── AuthenticationClientExecutionInterceptorTest.java │ │ │ │ │ ├── adapter/ │ │ │ │ │ │ └── KCAdapterContextTokenManagerTest.java │ │ │ │ │ └── credentials/ │ │ │ │ │ └── AuthTokenManagerTest.java │ │ │ │ └── elytron/ │ │ │ │ ├── KeyCloakElytronIdentityHelperProducerTest.java │ │ │ │ └── KeyCloakElytronIdentityHelperTest.java │ │ │ ├── uberfire-security-management-wildfly/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── security/ │ │ │ │ │ └── management/ │ │ │ │ │ └── wildfly/ │ │ │ │ │ ├── cli/ │ │ │ │ │ │ ├── BaseWildflyCLIManager.java │ │ │ │ │ │ ├── WildflyCLIUserManagementService.java │ │ │ │ │ │ ├── WildflyGroupFileSystemCLIManager.java │ │ │ │ │ │ └── WildflyUserFileSystemCLIManager.java │ │ │ │ │ └── filesystem/ │ │ │ │ │ ├── RealmProvider.java │ │ │ │ │ ├── WildflyGroupFileSystemManager.java │ │ │ │ │ ├── WildflyUserFileSystemManager.java │ │ │ │ │ └── WildflyUserManagementService.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── uberfire-widgets-security-management/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── security/ │ │ │ │ │ └── management/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ ├── SecurityManagementConstants.java │ │ │ │ │ │ └── UsersManagementWidgetsConstants.java │ │ │ │ │ └── widgets/ │ │ │ │ │ ├── management/ │ │ │ │ │ │ ├── ChangePassword.java │ │ │ │ │ │ ├── ChangePasswordView.java │ │ │ │ │ │ ├── ChangePasswordView.ui.xml │ │ │ │ │ │ ├── CreateEntity.java │ │ │ │ │ │ ├── CreateEntityView.java │ │ │ │ │ │ ├── CreateEntityView.ui.xml │ │ │ │ │ │ ├── editor/ │ │ │ │ │ │ │ ├── AssignedEntitiesEditor.java │ │ │ │ │ │ │ ├── AssignedEntitiesExplorer.java │ │ │ │ │ │ │ ├── AssignedEntitiesExplorerView.java │ │ │ │ │ │ │ ├── AssignedEntitiesExplorerView.ui.xml │ │ │ │ │ │ │ ├── AssignedEntitiesInlineEditor.java │ │ │ │ │ │ │ ├── AssignedEntitiesInlineEditorView.java │ │ │ │ │ │ │ ├── AssignedEntitiesInlineEditorView.ui.xml │ │ │ │ │ │ │ ├── AssignedEntitiesModalEditor.java │ │ │ │ │ │ │ ├── AssignedEntitiesModalEditorView.java │ │ │ │ │ │ │ ├── AssignedEntitiesModalEditorView.ui.xml │ │ │ │ │ │ │ ├── acl/ │ │ │ │ │ │ │ │ ├── ACLEditor.java │ │ │ │ │ │ │ │ ├── ACLEditorView.html │ │ │ │ │ │ │ │ ├── ACLEditorView.java │ │ │ │ │ │ │ │ ├── ACLSettings.java │ │ │ │ │ │ │ │ ├── ACLSettingsView.css │ │ │ │ │ │ │ │ ├── ACLSettingsView.html │ │ │ │ │ │ │ │ ├── ACLSettingsView.java │ │ │ │ │ │ │ │ ├── ACLViewer.java │ │ │ │ │ │ │ │ ├── ACLViewerView.html │ │ │ │ │ │ │ │ ├── ACLViewerView.java │ │ │ │ │ │ │ │ ├── PriorityDropDown.java │ │ │ │ │ │ │ │ └── node/ │ │ │ │ │ │ │ │ ├── BasePermissionNodeEditor.java │ │ │ │ │ │ │ │ ├── BasePermissionNodeViewer.java │ │ │ │ │ │ │ │ ├── LeafPermissionNodeEditor.java │ │ │ │ │ │ │ │ ├── LeafPermissionNodeEditorView.css │ │ │ │ │ │ │ │ ├── LeafPermissionNodeEditorView.html │ │ │ │ │ │ │ │ ├── LeafPermissionNodeEditorView.java │ │ │ │ │ │ │ │ ├── LeafPermissionNodeViewer.java │ │ │ │ │ │ │ │ ├── LeafPermissionNodeViewerView.html │ │ │ │ │ │ │ │ ├── LeafPermissionNodeViewerView.java │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeEditor.java │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeEditorView.css │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeEditorView.html │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeEditorView.java │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeViewer.java │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeViewerView.css │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeViewerView.html │ │ │ │ │ │ │ │ ├── MultiplePermissionNodeViewerView.java │ │ │ │ │ │ │ │ ├── PermissionExceptionSwitch.java │ │ │ │ │ │ │ │ ├── PermissionExceptionSwitchView.css │ │ │ │ │ │ │ │ ├── PermissionExceptionSwitchView.html │ │ │ │ │ │ │ │ ├── PermissionExceptionSwitchView.java │ │ │ │ │ │ │ │ ├── PermissionNodeEditor.java │ │ │ │ │ │ │ │ ├── PermissionNodeViewer.java │ │ │ │ │ │ │ │ ├── PermissionSwitch.java │ │ │ │ │ │ │ │ ├── PermissionSwitchToogle.java │ │ │ │ │ │ │ │ ├── PermissionSwitchView.css │ │ │ │ │ │ │ │ ├── PermissionSwitchView.html │ │ │ │ │ │ │ │ ├── PermissionSwitchView.java │ │ │ │ │ │ │ │ └── PermissionWidgetFactory.java │ │ │ │ │ │ │ ├── group/ │ │ │ │ │ │ │ │ ├── GroupEditor.java │ │ │ │ │ │ │ │ ├── GroupEditorView.java │ │ │ │ │ │ │ │ ├── GroupEditorView.ui.xml │ │ │ │ │ │ │ │ ├── GroupUsersAssignment.java │ │ │ │ │ │ │ │ └── workflow/ │ │ │ │ │ │ │ │ ├── GroupCreationWorkflow.java │ │ │ │ │ │ │ │ └── GroupEditorWorkflow.java │ │ │ │ │ │ │ ├── role/ │ │ │ │ │ │ │ │ ├── RoleEditor.java │ │ │ │ │ │ │ │ ├── RoleEditorView.java │ │ │ │ │ │ │ │ ├── RoleEditorView.ui.xml │ │ │ │ │ │ │ │ └── workflow/ │ │ │ │ │ │ │ │ ├── BaseRoleEditorWorkflow.java │ │ │ │ │ │ │ │ └── RoleEditorWorkflow.java │ │ │ │ │ │ │ ├── user/ │ │ │ │ │ │ │ │ ├── NewUserAttributeEditor.java │ │ │ │ │ │ │ │ ├── NewUserAttributeEditorView.java │ │ │ │ │ │ │ │ ├── NewUserAttributeEditorView.ui.xml │ │ │ │ │ │ │ │ ├── UserAssignedEntitiesEditor.java │ │ │ │ │ │ │ │ ├── UserAssignedEntitiesExplorer.java │ │ │ │ │ │ │ │ ├── UserAssignedGroupsEditor.java │ │ │ │ │ │ │ │ ├── UserAssignedGroupsExplorer.java │ │ │ │ │ │ │ │ ├── UserAssignedRolesEditor.java │ │ │ │ │ │ │ │ ├── UserAssignedRolesExplorer.java │ │ │ │ │ │ │ │ ├── UserAttributesEditor.java │ │ │ │ │ │ │ │ ├── UserAttributesEditorView.java │ │ │ │ │ │ │ │ ├── UserAttributesEditorView.ui.xml │ │ │ │ │ │ │ │ ├── UserEditor.java │ │ │ │ │ │ │ │ ├── UserEditorView.java │ │ │ │ │ │ │ │ ├── UserEditorView.ui.xml │ │ │ │ │ │ │ │ └── workflow/ │ │ │ │ │ │ │ │ ├── BaseUserEditorWorkflow.java │ │ │ │ │ │ │ │ ├── UserCreationWorkflow.java │ │ │ │ │ │ │ │ └── UserEditorWorkflow.java │ │ │ │ │ │ │ └── workflow/ │ │ │ │ │ │ │ ├── EntityWorkflowView.java │ │ │ │ │ │ │ ├── EntityWorkflowViewImpl.java │ │ │ │ │ │ │ └── EntityWorkflowViewImpl.ui.xml │ │ │ │ │ │ ├── events/ │ │ │ │ │ │ │ ├── AddUsersToGroupEvent.java │ │ │ │ │ │ │ ├── ChangePasswordEvent.java │ │ │ │ │ │ │ ├── ContextualEvent.java │ │ │ │ │ │ │ ├── CreateGroupEvent.java │ │ │ │ │ │ │ ├── CreateUserAttributeEvent.java │ │ │ │ │ │ │ ├── CreateUserEvent.java │ │ │ │ │ │ │ ├── DeleteGroupEvent.java │ │ │ │ │ │ │ ├── DeleteUserAttributeEvent.java │ │ │ │ │ │ │ ├── DeleteUserEvent.java │ │ │ │ │ │ │ ├── HomePerspectiveChangedEvent.java │ │ │ │ │ │ │ ├── NewGroupEvent.java │ │ │ │ │ │ │ ├── NewUserEvent.java │ │ │ │ │ │ │ ├── OnChangePasswordEvent.java │ │ │ │ │ │ │ ├── OnDeleteEvent.java │ │ │ │ │ │ │ ├── OnEditEvent.java │ │ │ │ │ │ │ ├── OnErrorEvent.java │ │ │ │ │ │ │ ├── OnRemoveUserGroupEvent.java │ │ │ │ │ │ │ ├── OnRemoveUserRoleEvent.java │ │ │ │ │ │ │ ├── OnShowEvent.java │ │ │ │ │ │ │ ├── OnUpdateUserGroupsEvent.java │ │ │ │ │ │ │ ├── OnUpdateUserRolesEvent.java │ │ │ │ │ │ │ ├── PermissionChangedEvent.java │ │ │ │ │ │ │ ├── PermissionNodeAddedEvent.java │ │ │ │ │ │ │ ├── PermissionNodeRemovedEvent.java │ │ │ │ │ │ │ ├── PriorityChangedEvent.java │ │ │ │ │ │ │ ├── ReadGroupEvent.java │ │ │ │ │ │ │ ├── ReadRoleEvent.java │ │ │ │ │ │ │ ├── ReadUserEvent.java │ │ │ │ │ │ │ ├── RemoveUserGroupEvent.java │ │ │ │ │ │ │ ├── SaveGroupEvent.java │ │ │ │ │ │ │ ├── SaveRoleEvent.java │ │ │ │ │ │ │ ├── SaveUserEvent.java │ │ │ │ │ │ │ └── UpdateUserAttributeEvent.java │ │ │ │ │ │ ├── explorer/ │ │ │ │ │ │ │ ├── AbstractEntityExplorer.java │ │ │ │ │ │ │ ├── EntitiesExplorerView.java │ │ │ │ │ │ │ ├── EntitiesExplorerViewImpl.java │ │ │ │ │ │ │ ├── EntitiesExplorerViewImpl.ui.xml │ │ │ │ │ │ │ ├── ExplorerViewContext.java │ │ │ │ │ │ │ ├── GroupsExplorer.java │ │ │ │ │ │ │ ├── RolesExplorer.java │ │ │ │ │ │ │ ├── UserGroupsExplorer.java │ │ │ │ │ │ │ ├── UserGroupsExplorerView.java │ │ │ │ │ │ │ ├── UserGroupsExplorerView.ui.xml │ │ │ │ │ │ │ └── UsersExplorer.java │ │ │ │ │ │ └── list/ │ │ │ │ │ │ ├── EntitiesList.java │ │ │ │ │ │ ├── EntitiesListView.java │ │ │ │ │ │ ├── EntitiesListView.ui.xml │ │ │ │ │ │ ├── EntitiesPagedList.java │ │ │ │ │ │ ├── GroupsList.java │ │ │ │ │ │ ├── RolesList.java │ │ │ │ │ │ └── UsersList.java │ │ │ │ │ └── popup/ │ │ │ │ │ ├── ConfirmBox.java │ │ │ │ │ ├── ConfirmBoxView.java │ │ │ │ │ ├── ErrorBox.java │ │ │ │ │ ├── ErrorBoxView.java │ │ │ │ │ ├── LoadingBox.java │ │ │ │ │ └── LoadingBoxView.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── security/ │ │ │ │ └── management/ │ │ │ │ ├── UberfireSecurityManagementWidgets.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── SecurityManagementConstants.properties │ │ │ │ ├── SecurityManagementConstants_es.properties │ │ │ │ ├── SecurityManagementConstants_fr.properties │ │ │ │ ├── SecurityManagementConstants_it.properties │ │ │ │ ├── SecurityManagementConstants_ja.properties │ │ │ │ ├── UsersManagementWidgetsConstants.properties │ │ │ │ ├── UsersManagementWidgetsConstants_de.properties │ │ │ │ ├── UsersManagementWidgetsConstants_es.properties │ │ │ │ ├── UsersManagementWidgetsConstants_fr.properties │ │ │ │ ├── UsersManagementWidgetsConstants_it.properties │ │ │ │ ├── UsersManagementWidgetsConstants_ja.properties │ │ │ │ ├── UsersManagementWidgetsConstants_pt_BR.properties │ │ │ │ └── UsersManagementWidgetsConstants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── security/ │ │ │ └── management/ │ │ │ └── client/ │ │ │ └── widgets/ │ │ │ ├── management/ │ │ │ │ ├── AbstractSecurityManagementTest.java │ │ │ │ ├── ChangePasswordTest.java │ │ │ │ ├── CreateEntityTest.java │ │ │ │ ├── editor/ │ │ │ │ │ ├── acl/ │ │ │ │ │ │ ├── ACLSettingsTest.java │ │ │ │ │ │ ├── LeafPermissionNodeEditorTest.java │ │ │ │ │ │ ├── LeafPermissionNodeViewerTest.java │ │ │ │ │ │ ├── MultiplePermissionNodeEditorTest.java │ │ │ │ │ │ ├── MultiplePermissionNodeViewerTest.java │ │ │ │ │ │ ├── PermissionExceptionSwitchTest.java │ │ │ │ │ │ ├── PermissionSwitchTest.java │ │ │ │ │ │ └── PriorityDropDownTest.java │ │ │ │ │ ├── group/ │ │ │ │ │ │ ├── GroupEditorTest.java │ │ │ │ │ │ ├── GroupUsersAssignmentTest.java │ │ │ │ │ │ └── workflow/ │ │ │ │ │ │ ├── GroupCreationWorkflowTest.java │ │ │ │ │ │ └── GroupEditorWorkflowTest.java │ │ │ │ │ ├── role/ │ │ │ │ │ │ └── workflow/ │ │ │ │ │ │ └── RoleEditorWorkflowTest.java │ │ │ │ │ └── user/ │ │ │ │ │ ├── NewUserAttributeEditorTest.java │ │ │ │ │ ├── UserAssignedGroupsEditorTest.java │ │ │ │ │ ├── UserAssignedGroupsExplorerTest.java │ │ │ │ │ ├── UserAssignedRolesEditorTest.java │ │ │ │ │ ├── UserAssignedRolesExplorerTest.java │ │ │ │ │ ├── UserAttributesEditorTest.java │ │ │ │ │ ├── UserEditorTest.java │ │ │ │ │ └── workflow/ │ │ │ │ │ ├── BaseUserEditorWorkflowTest.java │ │ │ │ │ ├── UserCreationWorkflowTest.java │ │ │ │ │ └── UserEditorWorkflowTest.java │ │ │ │ ├── explorer/ │ │ │ │ │ ├── EntitiesExplorerTest.java │ │ │ │ │ ├── GroupsExplorerTest.java │ │ │ │ │ ├── RolesExplorerTest.java │ │ │ │ │ ├── UserGroupsExplorerTest.java │ │ │ │ │ └── UsersExplorerTest.java │ │ │ │ └── list/ │ │ │ │ ├── EntitiesListTest.java │ │ │ │ └── EntitiesPagedListTest.java │ │ │ └── popup/ │ │ │ ├── ConfirmBoxTest.java │ │ │ ├── ErrorBoxTest.java │ │ │ └── LoadingBoxTest.java │ │ └── uberfire-servlet-security/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── security/ │ │ │ │ └── server/ │ │ │ │ ├── BasicAuthSecurityFilter.java │ │ │ │ ├── CacheHeadersFilter.java │ │ │ │ ├── CleanupSecurityCacheSessionListener.java │ │ │ │ ├── HttpRequestProducer.java │ │ │ │ ├── HttpServletRequestProducerExtension.java │ │ │ │ ├── LoginRedirectServlet.java │ │ │ │ ├── SecureHeadersConfig.java │ │ │ │ ├── SecureHeadersFilter.java │ │ │ │ ├── SecurityIntegrationFilter.java │ │ │ │ ├── ServletSecurityAuthenticationService.java │ │ │ │ ├── XSSServletFilter.java │ │ │ │ ├── XSSServletRequestWrapper.java │ │ │ │ └── io/ │ │ │ │ └── IOSecurityService.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── beans.xml │ │ │ └── services/ │ │ │ └── javax.enterprise.inject.spi.Extension │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── security/ │ │ └── server/ │ │ ├── BasicAuthSecurityFilterTest.java │ │ ├── CacheHeadersFilterTest.java │ │ ├── CleanupSecurityCacheSessionListenerTest.java │ │ ├── ServletSecurityAuthenticationServiceTest.java │ │ └── io/ │ │ ├── IOServiceSecuritySetupTest.java │ │ ├── MockAuthenticationService.java │ │ └── MockIOService.java │ ├── uberfire-simple-docks/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── uberfire-simple-docks-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── client/ │ │ │ │ ├── DocksEntryPoint.java │ │ │ │ ├── docks/ │ │ │ │ │ ├── UberfireDocksImpl.java │ │ │ │ │ └── view/ │ │ │ │ │ ├── DockResizeBar.java │ │ │ │ │ ├── DocksBar.java │ │ │ │ │ ├── DocksBars.java │ │ │ │ │ ├── bars/ │ │ │ │ │ │ ├── DocksCollapsedBar.java │ │ │ │ │ │ ├── DocksCollapsedBar.ui.xml │ │ │ │ │ │ ├── DocksExpandedBar.java │ │ │ │ │ │ └── DocksExpandedBar.ui.xml │ │ │ │ │ ├── items/ │ │ │ │ │ │ ├── AbstractDockItem.java │ │ │ │ │ │ ├── AbstractSideDockItem.java │ │ │ │ │ │ ├── SideDockItem.java │ │ │ │ │ │ ├── SideDockItem.ui.xml │ │ │ │ │ │ ├── SingleSideDockItem.java │ │ │ │ │ │ ├── SingleSideDockItem.ui.xml │ │ │ │ │ │ ├── SouthDockItem.java │ │ │ │ │ │ └── SouthDockItem.ui.xml │ │ │ │ │ └── menu/ │ │ │ │ │ └── MenuBuilder.java │ │ │ │ └── resources/ │ │ │ │ ├── DocksCss.java │ │ │ │ ├── WebAppResource.java │ │ │ │ └── i18n/ │ │ │ │ └── DockConstants.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ ├── UberfireDocksClient.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ ├── css/ │ │ │ │ └── docks.css │ │ │ └── i18n/ │ │ │ ├── CommonConstants.properties │ │ │ ├── CommonConstants_de.properties │ │ │ ├── CommonConstants_es.properties │ │ │ ├── CommonConstants_fr.properties │ │ │ ├── CommonConstants_it.properties │ │ │ ├── CommonConstants_ja.properties │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ └── CommonConstants_zh_CN.properties │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── client/ │ │ └── docks/ │ │ ├── UberfireDocksImplTest.java │ │ └── view/ │ │ ├── DockResizeBarTest.java │ │ ├── DocksBarsTest.java │ │ ├── DocksBars_OpenDockTest.java │ │ ├── bars/ │ │ │ ├── DocksCollapsedBarTest.java │ │ │ └── DocksExpandedBarTest.java │ │ └── items/ │ │ ├── AbstractDockItemOuiaTest.java │ │ ├── SideDockItemTest.java │ │ └── SouthDockItemTest.java │ ├── uberfire-widgets/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-widgets-commons/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── widgets/ │ │ │ │ │ └── common/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── CommonsEntryPoint.java │ │ │ │ │ ├── accordion/ │ │ │ │ │ │ └── TriggerWidget.java │ │ │ │ │ ├── animations/ │ │ │ │ │ │ ├── LinearFadeInAnimation.java │ │ │ │ │ │ ├── LinearFadeOutAnimation.java │ │ │ │ │ │ ├── Pause.java │ │ │ │ │ │ ├── SequencedAnimation.java │ │ │ │ │ │ └── Sequencer.java │ │ │ │ │ ├── breadcrumbs/ │ │ │ │ │ │ ├── UberfireBreadcrumbs.java │ │ │ │ │ │ ├── UberfireBreadcrumbsView.css │ │ │ │ │ │ ├── UberfireBreadcrumbsView.html │ │ │ │ │ │ ├── UberfireBreadcrumbsView.java │ │ │ │ │ │ ├── header/ │ │ │ │ │ │ │ ├── UberfireBreadcrumbsContainer.java │ │ │ │ │ │ │ ├── UberfireBreadcrumbsContainerImpl.css │ │ │ │ │ │ │ ├── UberfireBreadcrumbsContainerImpl.html │ │ │ │ │ │ │ └── UberfireBreadcrumbsContainerImpl.java │ │ │ │ │ │ └── widget/ │ │ │ │ │ │ ├── BreadcrumbPresenter.java │ │ │ │ │ │ ├── DefaultBreadcrumbsPresenter.java │ │ │ │ │ │ ├── DefaultBreadcrumbsView.css │ │ │ │ │ │ ├── DefaultBreadcrumbsView.html │ │ │ │ │ │ └── DefaultBreadcrumbsView.java │ │ │ │ │ ├── callbacks/ │ │ │ │ │ │ ├── CommandErrorCallback.java │ │ │ │ │ │ ├── DefaultErrorCallback.java │ │ │ │ │ │ └── HasBusyIndicatorDefaultErrorCallback.java │ │ │ │ │ ├── colorpicker/ │ │ │ │ │ │ ├── ColorChangedEvent.java │ │ │ │ │ │ ├── ColorChangedHandler.java │ │ │ │ │ │ ├── ColorPickerDialog.java │ │ │ │ │ │ ├── ColorUtils.java │ │ │ │ │ │ ├── HueChangedEvent.java │ │ │ │ │ │ ├── HueChangedHandler.java │ │ │ │ │ │ ├── HuePicker.java │ │ │ │ │ │ ├── SaturationLightnessPicker.java │ │ │ │ │ │ ├── canvas/ │ │ │ │ │ │ │ ├── Canvas.java │ │ │ │ │ │ │ ├── Gradient.java │ │ │ │ │ │ │ ├── ImageData.java │ │ │ │ │ │ │ └── RenderingContext.java │ │ │ │ │ │ └── dialog/ │ │ │ │ │ │ ├── Dialog.java │ │ │ │ │ │ ├── DialogClosedEvent.java │ │ │ │ │ │ └── DialogClosedHandler.java │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── AbstractConcurrentChangePopup.java │ │ │ │ │ │ ├── AbstractConcurrentChangePopup.ui.xml │ │ │ │ │ │ ├── AbstractLazyStackPanelHeader.java │ │ │ │ │ │ ├── AbstractRestrictedEntryTextBox.java │ │ │ │ │ │ ├── AddButton.java │ │ │ │ │ │ ├── BooleanTextBox.java │ │ │ │ │ │ ├── BusyIndicatorView.java │ │ │ │ │ │ ├── BusyPopup.java │ │ │ │ │ │ ├── BusyPopup.ui.xml │ │ │ │ │ │ ├── ClickableLabel.java │ │ │ │ │ │ ├── ConcurrentChangePopup.java │ │ │ │ │ │ ├── DatePicker.java │ │ │ │ │ │ ├── DatePickerFormatUtilities.java │ │ │ │ │ │ ├── DecoratedDisclosurePanel.java │ │ │ │ │ │ ├── DirtyableComposite.java │ │ │ │ │ │ ├── DirtyableContainer.java │ │ │ │ │ │ ├── DirtyableFlexTable.java │ │ │ │ │ │ ├── DirtyableHorizontalPane.java │ │ │ │ │ │ ├── DirtyableVerticalPane.java │ │ │ │ │ │ ├── DirtyableWidget.java │ │ │ │ │ │ ├── DropDownValueChanged.java │ │ │ │ │ │ ├── EditorWidget.java │ │ │ │ │ │ ├── FileInputButton.java │ │ │ │ │ │ ├── FileInputGroupButton.java │ │ │ │ │ │ ├── FileUpload.java │ │ │ │ │ │ ├── FileUpload.ui.xml │ │ │ │ │ │ ├── FileUploadFormEncoder.java │ │ │ │ │ │ ├── FormStyleItem.java │ │ │ │ │ │ ├── FormStyleItem.ui.xml │ │ │ │ │ │ ├── FormStyleLayout.java │ │ │ │ │ │ ├── HasBusyIndicator.java │ │ │ │ │ │ ├── HeaderHTML.java │ │ │ │ │ │ ├── HeaderHTML.ui.xml │ │ │ │ │ │ ├── IDirtyable.java │ │ │ │ │ │ ├── ImageButton.java │ │ │ │ │ │ ├── InfoCube.java │ │ │ │ │ │ ├── InfoCube.ui.xml │ │ │ │ │ │ ├── InfoPopup.java │ │ │ │ │ │ ├── LazyStackPanel.java │ │ │ │ │ │ ├── LazyStackPanelHeader.java │ │ │ │ │ │ ├── LazyStackPanelHeader.ui.xml │ │ │ │ │ │ ├── LazyStackPanelRow.java │ │ │ │ │ │ ├── LoadContentCommand.java │ │ │ │ │ │ ├── NumericBigDecimalTextBox.java │ │ │ │ │ │ ├── NumericBigIntegerTextBox.java │ │ │ │ │ │ ├── NumericByteTextBox.java │ │ │ │ │ │ ├── NumericDoubleTextBox.java │ │ │ │ │ │ ├── NumericFloatTextBox.java │ │ │ │ │ │ ├── NumericIntegerTextBox.java │ │ │ │ │ │ ├── NumericLongTextBox.java │ │ │ │ │ │ ├── NumericShortTextBox.java │ │ │ │ │ │ ├── NumericTextBox.java │ │ │ │ │ │ ├── Page.java │ │ │ │ │ │ ├── PrettyFormLayout.java │ │ │ │ │ │ ├── ResizableTextArea.java │ │ │ │ │ │ ├── SmallLabel.java │ │ │ │ │ │ ├── StackItemHeader.java │ │ │ │ │ │ ├── StackItemHeaderView.java │ │ │ │ │ │ ├── StackItemHeaderViewImpl.java │ │ │ │ │ │ ├── StackItemHeaderViewImpl.ui.xml │ │ │ │ │ │ ├── StyleHelper.java │ │ │ │ │ │ ├── Util.java │ │ │ │ │ │ ├── ValueChanged.java │ │ │ │ │ │ └── popups/ │ │ │ │ │ │ ├── BaseModal.java │ │ │ │ │ │ ├── ButtonPressed.java │ │ │ │ │ │ ├── FormStylePopup.java │ │ │ │ │ │ ├── FormStylePopup.ui.xml │ │ │ │ │ │ ├── YesNoCancelPopup.java │ │ │ │ │ │ ├── YesNoCancelPopup.ui.xml │ │ │ │ │ │ ├── errors/ │ │ │ │ │ │ │ ├── ErrorPopup.java │ │ │ │ │ │ │ └── ErrorPopup.ui.xml │ │ │ │ │ │ └── footers/ │ │ │ │ │ │ ├── GenericModalFooter.java │ │ │ │ │ │ ├── ModalFooterForceSaveReOpenCancelButtons.java │ │ │ │ │ │ ├── ModalFooterForceSaveReOpenCancelButtons.ui.xml │ │ │ │ │ │ ├── ModalFooterOKButton.java │ │ │ │ │ │ ├── ModalFooterOKButton.ui.xml │ │ │ │ │ │ ├── ModalFooterOKCancelButtons.java │ │ │ │ │ │ ├── ModalFooterOKCancelButtons.ui.xml │ │ │ │ │ │ ├── ModalFooterReOpenIgnoreButtons.java │ │ │ │ │ │ ├── ModalFooterReOpenIgnoreButtons.ui.xml │ │ │ │ │ │ ├── ModalFooterYesNoCancelButtons.java │ │ │ │ │ │ └── ModalFooterYesNoCancelButtons.ui.xml │ │ │ │ │ ├── diff2html/ │ │ │ │ │ │ ├── Diff2Html.java │ │ │ │ │ │ └── DiffOutputFormat.java │ │ │ │ │ ├── dropdown/ │ │ │ │ │ │ ├── EntryCreationEditor.java │ │ │ │ │ │ ├── EntryCreationLiveSearchService.java │ │ │ │ │ │ ├── InlineCreationEditor.java │ │ │ │ │ │ ├── LiveSearchCallback.java │ │ │ │ │ │ ├── LiveSearchDropDown.java │ │ │ │ │ │ ├── LiveSearchDropDownView.css │ │ │ │ │ │ ├── LiveSearchDropDownView.html │ │ │ │ │ │ ├── LiveSearchDropDownView.java │ │ │ │ │ │ ├── LiveSearchEntry.java │ │ │ │ │ │ ├── LiveSearchResults.java │ │ │ │ │ │ ├── LiveSearchSelectionHandler.java │ │ │ │ │ │ ├── LiveSearchSelectorItem.java │ │ │ │ │ │ ├── LiveSearchSelectorItemView.java │ │ │ │ │ │ ├── LiveSearchService.java │ │ │ │ │ │ ├── ModalCreationEditor.java │ │ │ │ │ │ ├── MultipleLiveSearchSelectionHandler.java │ │ │ │ │ │ ├── PerspectiveDropDown.java │ │ │ │ │ │ ├── PerspectiveNameProvider.java │ │ │ │ │ │ ├── SingleLiveSearchSelectionHandler.java │ │ │ │ │ │ ├── footer/ │ │ │ │ │ │ │ ├── LiveSearchFooter.java │ │ │ │ │ │ │ ├── LiveSearchFooterView.java │ │ │ │ │ │ │ ├── LiveSearchFooterViewImpl.css │ │ │ │ │ │ │ ├── LiveSearchFooterViewImpl.html │ │ │ │ │ │ │ └── LiveSearchFooterViewImpl.java │ │ │ │ │ │ ├── items/ │ │ │ │ │ │ │ ├── LiveSearchSelectorDropDownItem.java │ │ │ │ │ │ │ ├── LiveSearchSelectorDropDownItemView.java │ │ │ │ │ │ │ ├── LiveSearchSelectorDropDownItemViewImpl.css │ │ │ │ │ │ │ ├── LiveSearchSelectorDropDownItemViewImpl.html │ │ │ │ │ │ │ └── LiveSearchSelectorDropDownItemViewImpl.java │ │ │ │ │ │ └── noItems/ │ │ │ │ │ │ ├── NoItemsComponent.java │ │ │ │ │ │ ├── NoItemsComponentView.java │ │ │ │ │ │ ├── NoItemsComponentViewImpl.css │ │ │ │ │ │ ├── NoItemsComponentViewImpl.html │ │ │ │ │ │ └── NoItemsComponentViewImpl.java │ │ │ │ │ ├── forms/ │ │ │ │ │ │ ├── GetFormParamsEvent.java │ │ │ │ │ │ ├── RequestFormParamsEvent.java │ │ │ │ │ │ └── SetFormParamsEvent.java │ │ │ │ │ ├── menu/ │ │ │ │ │ │ ├── MenuItemDivider.java │ │ │ │ │ │ ├── MenuItemDividerView.html │ │ │ │ │ │ ├── MenuItemDividerView.java │ │ │ │ │ │ ├── MenuItemFactory.java │ │ │ │ │ │ ├── MenuItemHeader.java │ │ │ │ │ │ ├── MenuItemHeaderView.html │ │ │ │ │ │ ├── MenuItemHeaderView.java │ │ │ │ │ │ ├── MenuItemView.java │ │ │ │ │ │ ├── MenuItemWithIcon.java │ │ │ │ │ │ ├── MenuItemWithIconView.html │ │ │ │ │ │ ├── MenuItemWithIconView.java │ │ │ │ │ │ ├── RefreshMenuBuilder.java │ │ │ │ │ │ └── RefreshSelectorMenuBuilder.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ ├── CommonAltedImages.java │ │ │ │ │ │ ├── CommonCss.java │ │ │ │ │ │ ├── CommonImages.java │ │ │ │ │ │ ├── CommonResources.java │ │ │ │ │ │ ├── HtmlEditorResources.java │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ └── CommonConstants.java │ │ │ │ │ ├── select/ │ │ │ │ │ │ ├── NullSelectOption.java │ │ │ │ │ │ ├── SelectComponent.java │ │ │ │ │ │ ├── SelectOption.java │ │ │ │ │ │ ├── SelectOptionComponent.java │ │ │ │ │ │ ├── SelectOptionImpl.java │ │ │ │ │ │ ├── SelectOptionView.html │ │ │ │ │ │ ├── SelectOptionView.java │ │ │ │ │ │ ├── SelectView.html │ │ │ │ │ │ └── SelectView.java │ │ │ │ │ └── tables/ │ │ │ │ │ ├── ColumnPicker.java │ │ │ │ │ ├── ComparableImageResource.java │ │ │ │ │ ├── ComparableImageResourceCell.java │ │ │ │ │ ├── DataGridFilter.java │ │ │ │ │ ├── FilterPagedTable.java │ │ │ │ │ ├── FilterPagedTable.ui.xml │ │ │ │ │ ├── PagedTable.java │ │ │ │ │ ├── PagedTable.ui.xml │ │ │ │ │ ├── PopoverTextCell.java │ │ │ │ │ ├── ResizableHeader.java │ │ │ │ │ ├── SelectionColumn.java │ │ │ │ │ ├── SimpleTable.java │ │ │ │ │ ├── SimpleTable.ui.xml │ │ │ │ │ ├── SortDirection.java │ │ │ │ │ ├── SortableHeader.java │ │ │ │ │ ├── SortableHeaderGroup.java │ │ │ │ │ ├── TitledTextCell.java │ │ │ │ │ ├── TitledTextColumn.java │ │ │ │ │ └── popup/ │ │ │ │ │ ├── DataGridFilterSummary.java │ │ │ │ │ ├── NewFilterPopup.java │ │ │ │ │ ├── NewFilterPopup.ui.xml │ │ │ │ │ ├── NewTabFilterPopup.java │ │ │ │ │ └── NewTabFilterPopup.ui.xml │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── widgets/ │ │ │ │ └── common/ │ │ │ │ ├── UberfireWidgetsCommons.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ ├── css/ │ │ │ │ │ └── common.css │ │ │ │ ├── i18n/ │ │ │ │ │ ├── CommonConstants.properties │ │ │ │ │ ├── CommonConstants_de.properties │ │ │ │ │ ├── CommonConstants_es.properties │ │ │ │ │ ├── CommonConstants_fr.properties │ │ │ │ │ ├── CommonConstants_it.properties │ │ │ │ │ ├── CommonConstants_ja.properties │ │ │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ │ │ └── CommonConstants_zh_CN.properties │ │ │ │ └── js/ │ │ │ │ └── wysihtml/ │ │ │ │ └── parser_rules/ │ │ │ │ └── advanced_and_extended.js │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── widgets/ │ │ │ └── common/ │ │ │ └── client/ │ │ │ ├── breadcrumbs/ │ │ │ │ ├── UberfireBreadcrumbsTest.java │ │ │ │ └── widget/ │ │ │ │ └── DefaultBreadcrumbsPresenterTest.java │ │ │ ├── callbacks/ │ │ │ │ └── CommandErrorCallbackTest.java │ │ │ ├── common/ │ │ │ │ ├── BooleanTextBoxTest.java │ │ │ │ ├── DatePickerTest.java │ │ │ │ ├── FileUploadTest.java │ │ │ │ ├── FormStyleItemTest.java │ │ │ │ ├── FormStyleLayoutTest.java │ │ │ │ ├── InfoPopupTest.java │ │ │ │ ├── NumericIntegerTextBoxTest.java │ │ │ │ └── popups/ │ │ │ │ └── FormStylePopupTest.java │ │ │ ├── dropdown/ │ │ │ │ ├── AbstractEntryCreationLiveSearchServiceTest.java │ │ │ │ ├── InlineEntryCreationLiveSearchServiceTest.java │ │ │ │ ├── LiveSearchDropDownTest.java │ │ │ │ ├── ModalEntryCreationLiveSearchServiceTest.java │ │ │ │ ├── MultipleLiveSearchSelectionHandlerTest.java │ │ │ │ ├── PerspectiveDropDownTest.java │ │ │ │ ├── SingleLiveSearchSelectionHandlerTest.java │ │ │ │ ├── footer/ │ │ │ │ │ └── LiveSearchFooterTest.java │ │ │ │ └── noItems/ │ │ │ │ └── NoItemsComponentTest.java │ │ │ ├── menu/ │ │ │ │ ├── MenuItemFactoryTest.java │ │ │ │ ├── RefreshMenuBuilderTest.java │ │ │ │ └── RefreshSelectorMenuBuilderTest.java │ │ │ ├── select/ │ │ │ │ ├── SelectComponentTest.java │ │ │ │ └── SelectOptionComponentTest.java │ │ │ └── tables/ │ │ │ ├── ColumnPickerTest.java │ │ │ ├── FilterPagedTableTest.java │ │ │ ├── PagedTableTest.java │ │ │ └── SimpleTableTest.java │ │ ├── uberfire-widgets-core/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ ├── uberfire-widgets-core-ace/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── widgets/ │ │ │ │ │ └── common/ │ │ │ │ │ └── client/ │ │ │ │ │ └── ace/ │ │ │ │ │ ├── AceAnnotation.java │ │ │ │ │ ├── AceAnnotationType.java │ │ │ │ │ ├── AceCommand.java │ │ │ │ │ ├── AceCompletion.java │ │ │ │ │ ├── AceCompletionCallback.java │ │ │ │ │ ├── AceCompletionCallbackImpl.java │ │ │ │ │ ├── AceCompletionProvider.java │ │ │ │ │ ├── AceCompletionSnippet.java │ │ │ │ │ ├── AceCompletionSnippetSegment.java │ │ │ │ │ ├── AceCompletionSnippetSegmentLiteral.java │ │ │ │ │ ├── AceCompletionSnippetSegmentTabstopItem.java │ │ │ │ │ ├── AceCompletionValue.java │ │ │ │ │ ├── AceEditor.java │ │ │ │ │ ├── AceEditorCallback.java │ │ │ │ │ ├── AceEditorCursorPosition.java │ │ │ │ │ ├── AceEditorMode.java │ │ │ │ │ └── AceEditorTheme.java │ │ │ │ └── resources/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── widgets/ │ │ │ │ └── common/ │ │ │ │ ├── UberfireAceEditor.gwt.xml │ │ │ │ └── public/ │ │ │ │ └── ace/ │ │ │ │ ├── ace-compat.js │ │ │ │ ├── ace.js │ │ │ │ ├── cockpit.js │ │ │ │ ├── ext-beautify.js │ │ │ │ ├── ext-chromevox.js │ │ │ │ ├── ext-elastic_tabstops_lite.js │ │ │ │ ├── ext-emmet.js │ │ │ │ ├── ext-error_marker.js │ │ │ │ ├── ext-keybinding_menu.js │ │ │ │ ├── ext-language_tools.js │ │ │ │ ├── ext-linking.js │ │ │ │ ├── ext-modelist.js │ │ │ │ ├── ext-old_ie.js │ │ │ │ ├── ext-options.js │ │ │ │ ├── ext-prompt.js │ │ │ │ ├── ext-searchbox.js │ │ │ │ ├── ext-settings_menu.js │ │ │ │ ├── ext-spellcheck.js │ │ │ │ ├── ext-split.js │ │ │ │ ├── ext-static_highlight.js │ │ │ │ ├── ext-statusbar.js │ │ │ │ ├── ext-textarea.js │ │ │ │ ├── ext-themelist.js │ │ │ │ ├── ext-whitespace.js │ │ │ │ ├── keybinding-emacs.js │ │ │ │ ├── keybinding-vim.js │ │ │ │ ├── mode-abap.js │ │ │ │ ├── mode-actionscript.js │ │ │ │ ├── mode-ada.js │ │ │ │ ├── mode-apache_conf.js │ │ │ │ ├── mode-applescript.js │ │ │ │ ├── mode-asciidoc.js │ │ │ │ ├── mode-assembly_x86.js │ │ │ │ ├── mode-autohotkey.js │ │ │ │ ├── mode-batchfile.js │ │ │ │ ├── mode-c9search.js │ │ │ │ ├── mode-c_cpp.js │ │ │ │ ├── mode-cirru.js │ │ │ │ ├── mode-clojure.js │ │ │ │ ├── mode-cobol.js │ │ │ │ ├── mode-coffee.js │ │ │ │ ├── mode-coldfusion.js │ │ │ │ ├── mode-csharp.js │ │ │ │ ├── mode-css.js │ │ │ │ ├── mode-curly.js │ │ │ │ ├── mode-d.js │ │ │ │ ├── mode-dart.js │ │ │ │ ├── mode-diff.js │ │ │ │ ├── mode-django.js │ │ │ │ ├── mode-dockerfile.js │ │ │ │ ├── mode-dot.js │ │ │ │ ├── mode-ejs.js │ │ │ │ ├── mode-erlang.js │ │ │ │ ├── mode-forth.js │ │ │ │ ├── mode-ftl.js │ │ │ │ ├── mode-gherkin.js │ │ │ │ ├── mode-glsl.js │ │ │ │ ├── mode-golang.js │ │ │ │ ├── mode-groovy.js │ │ │ │ ├── mode-haml.js │ │ │ │ ├── mode-handlebars.js │ │ │ │ ├── mode-haskell.js │ │ │ │ ├── mode-haxe.js │ │ │ │ ├── mode-html.js │ │ │ │ ├── mode-html_completions.js │ │ │ │ ├── mode-html_ruby.js │ │ │ │ ├── mode-ini.js │ │ │ │ ├── mode-jack.js │ │ │ │ ├── mode-jade.js │ │ │ │ ├── mode-java.js │ │ │ │ ├── mode-javascript.js │ │ │ │ ├── mode-json.js │ │ │ │ ├── mode-jsoniq.js │ │ │ │ ├── mode-jsp.js │ │ │ │ ├── mode-jsx.js │ │ │ │ ├── mode-julia.js │ │ │ │ ├── mode-latex.js │ │ │ │ ├── mode-less.js │ │ │ │ ├── mode-liquid.js │ │ │ │ ├── mode-lisp.js │ │ │ │ ├── mode-livescript.js │ │ │ │ ├── mode-logiql.js │ │ │ │ ├── mode-lsl.js │ │ │ │ ├── mode-lua.js │ │ │ │ ├── mode-luapage.js │ │ │ │ ├── mode-lucene.js │ │ │ │ ├── mode-makefile.js │ │ │ │ ├── mode-markdown.js │ │ │ │ ├── mode-matlab.js │ │ │ │ ├── mode-mel.js │ │ │ │ ├── mode-mushcode.js │ │ │ │ ├── mode-mushcode_high_rules.js │ │ │ │ ├── mode-mysql.js │ │ │ │ ├── mode-nix.js │ │ │ │ ├── mode-objectivec.js │ │ │ │ ├── mode-ocaml.js │ │ │ │ ├── mode-pascal.js │ │ │ │ ├── mode-perl.js │ │ │ │ ├── mode-pgsql.js │ │ │ │ ├── mode-php.js │ │ │ │ ├── mode-plain_text.js │ │ │ │ ├── mode-powershell.js │ │ │ │ ├── mode-prolog.js │ │ │ │ ├── mode-properties.js │ │ │ │ ├── mode-protobuf.js │ │ │ │ ├── mode-python.js │ │ │ │ ├── mode-r.js │ │ │ │ ├── mode-rdoc.js │ │ │ │ ├── mode-rhtml.js │ │ │ │ ├── mode-ruby.js │ │ │ │ ├── mode-rust.js │ │ │ │ ├── mode-sass.js │ │ │ │ ├── mode-scad.js │ │ │ │ ├── mode-scala.js │ │ │ │ ├── mode-scheme.js │ │ │ │ ├── mode-scss.js │ │ │ │ ├── mode-sh.js │ │ │ │ ├── mode-sjs.js │ │ │ │ ├── mode-smarty.js │ │ │ │ ├── mode-snippets.js │ │ │ │ ├── mode-soy_template.js │ │ │ │ ├── mode-space.js │ │ │ │ ├── mode-sql.js │ │ │ │ ├── mode-stylus.js │ │ │ │ ├── mode-svg.js │ │ │ │ ├── mode-tcl.js │ │ │ │ ├── mode-tex.js │ │ │ │ ├── mode-text.js │ │ │ │ ├── mode-textile.js │ │ │ │ ├── mode-tmsnippet.js │ │ │ │ ├── mode-toml.js │ │ │ │ ├── mode-twig.js │ │ │ │ ├── mode-typescript.js │ │ │ │ ├── mode-vala.js │ │ │ │ ├── mode-vbscript.js │ │ │ │ ├── mode-velocity.js │ │ │ │ ├── mode-verilog.js │ │ │ │ ├── mode-vhdl.js │ │ │ │ ├── mode-xml.js │ │ │ │ ├── mode-xquery.js │ │ │ │ ├── mode-yaml.js │ │ │ │ ├── snippets/ │ │ │ │ │ ├── abap.js │ │ │ │ │ ├── actionscript.js │ │ │ │ │ ├── ada.js │ │ │ │ │ ├── apache_conf.js │ │ │ │ │ ├── applescript.js │ │ │ │ │ ├── asciidoc.js │ │ │ │ │ ├── assembly_x86.js │ │ │ │ │ ├── autohotkey.js │ │ │ │ │ ├── batchfile.js │ │ │ │ │ ├── c9search.js │ │ │ │ │ ├── c_cpp.js │ │ │ │ │ ├── cirru.js │ │ │ │ │ ├── clojure.js │ │ │ │ │ ├── cobol.js │ │ │ │ │ ├── coffee.js │ │ │ │ │ ├── coldfusion.js │ │ │ │ │ ├── csharp.js │ │ │ │ │ ├── css.js │ │ │ │ │ ├── curly.js │ │ │ │ │ ├── d.js │ │ │ │ │ ├── dart.js │ │ │ │ │ ├── diff.js │ │ │ │ │ ├── django.js │ │ │ │ │ ├── dockerfile.js │ │ │ │ │ ├── dot.js │ │ │ │ │ ├── ejs.js │ │ │ │ │ ├── erlang.js │ │ │ │ │ ├── forth.js │ │ │ │ │ ├── ftl.js │ │ │ │ │ ├── gherkin.js │ │ │ │ │ ├── glsl.js │ │ │ │ │ ├── golang.js │ │ │ │ │ ├── groovy.js │ │ │ │ │ ├── haml.js │ │ │ │ │ ├── handlebars.js │ │ │ │ │ ├── haskell.js │ │ │ │ │ ├── haxe.js │ │ │ │ │ ├── html.js │ │ │ │ │ ├── html_completions.js │ │ │ │ │ ├── html_ruby.js │ │ │ │ │ ├── ini.js │ │ │ │ │ ├── jack.js │ │ │ │ │ ├── jade.js │ │ │ │ │ ├── java.js │ │ │ │ │ ├── javascript.js │ │ │ │ │ ├── json.js │ │ │ │ │ ├── jsoniq.js │ │ │ │ │ ├── jsp.js │ │ │ │ │ ├── jsx.js │ │ │ │ │ ├── julia.js │ │ │ │ │ ├── latex.js │ │ │ │ │ ├── less.js │ │ │ │ │ ├── liquid.js │ │ │ │ │ ├── lisp.js │ │ │ │ │ ├── livescript.js │ │ │ │ │ ├── logiql.js │ │ │ │ │ ├── lsl.js │ │ │ │ │ ├── lua.js │ │ │ │ │ ├── luapage.js │ │ │ │ │ ├── lucene.js │ │ │ │ │ ├── makefile.js │ │ │ │ │ ├── markdown.js │ │ │ │ │ ├── matlab.js │ │ │ │ │ ├── mel.js │ │ │ │ │ ├── mushcode.js │ │ │ │ │ ├── mushcode_high_rules.js │ │ │ │ │ ├── mysql.js │ │ │ │ │ ├── nix.js │ │ │ │ │ ├── objectivec.js │ │ │ │ │ ├── ocaml.js │ │ │ │ │ ├── pascal.js │ │ │ │ │ ├── perl.js │ │ │ │ │ ├── pgsql.js │ │ │ │ │ ├── php.js │ │ │ │ │ ├── plain_text.js │ │ │ │ │ ├── powershell.js │ │ │ │ │ ├── prolog.js │ │ │ │ │ ├── properties.js │ │ │ │ │ ├── protobuf.js │ │ │ │ │ ├── python.js │ │ │ │ │ ├── r.js │ │ │ │ │ ├── rdoc.js │ │ │ │ │ ├── rhtml.js │ │ │ │ │ ├── ruby.js │ │ │ │ │ ├── rust.js │ │ │ │ │ ├── sass.js │ │ │ │ │ ├── scad.js │ │ │ │ │ ├── scala.js │ │ │ │ │ ├── scheme.js │ │ │ │ │ ├── scss.js │ │ │ │ │ ├── sh.js │ │ │ │ │ ├── sjs.js │ │ │ │ │ ├── smarty.js │ │ │ │ │ ├── snippets.js │ │ │ │ │ ├── soy_template.js │ │ │ │ │ ├── space.js │ │ │ │ │ ├── sql.js │ │ │ │ │ ├── stylus.js │ │ │ │ │ ├── svg.js │ │ │ │ │ ├── tcl.js │ │ │ │ │ ├── tex.js │ │ │ │ │ ├── text.js │ │ │ │ │ ├── textile.js │ │ │ │ │ ├── toml.js │ │ │ │ │ ├── twig.js │ │ │ │ │ ├── typescript.js │ │ │ │ │ ├── vala.js │ │ │ │ │ ├── vbscript.js │ │ │ │ │ ├── velocity.js │ │ │ │ │ ├── verilog.js │ │ │ │ │ ├── vhdl.js │ │ │ │ │ ├── xml.js │ │ │ │ │ ├── xquery.js │ │ │ │ │ └── yaml.js │ │ │ │ ├── theme-ambiance.js │ │ │ │ ├── theme-chaos.js │ │ │ │ ├── theme-chrome.js │ │ │ │ ├── theme-cloud9_day.js │ │ │ │ ├── theme-cloud9_night.js │ │ │ │ ├── theme-cloud9_night_low_color.js │ │ │ │ ├── theme-clouds.js │ │ │ │ ├── theme-clouds_midnight.js │ │ │ │ ├── theme-cobalt.js │ │ │ │ ├── theme-crimson_editor.js │ │ │ │ ├── theme-dawn.js │ │ │ │ ├── theme-dreamweaver.js │ │ │ │ ├── theme-eclipse.js │ │ │ │ ├── theme-github.js │ │ │ │ ├── theme-idle_fingers.js │ │ │ │ ├── theme-katzenmilch.js │ │ │ │ ├── theme-kr.js │ │ │ │ ├── theme-kr_theme.js │ │ │ │ ├── theme-kuroir.js │ │ │ │ ├── theme-merbivore.js │ │ │ │ ├── theme-merbivore_soft.js │ │ │ │ ├── theme-mono_industrial.js │ │ │ │ ├── theme-monokai.js │ │ │ │ ├── theme-pastel_on_dark.js │ │ │ │ ├── theme-solarized_dark.js │ │ │ │ ├── theme-solarized_light.js │ │ │ │ ├── theme-terminal.js │ │ │ │ ├── theme-textmate.js │ │ │ │ ├── theme-tomorrow.js │ │ │ │ ├── theme-tomorrow_night.js │ │ │ │ ├── theme-tomorrow_night_blue.js │ │ │ │ ├── theme-tomorrow_night_bright.js │ │ │ │ ├── theme-tomorrow_night_eighties.js │ │ │ │ ├── theme-twilight.js │ │ │ │ ├── theme-vibrant_ink.js │ │ │ │ ├── theme-xcode.js │ │ │ │ ├── worker-coffee.js │ │ │ │ ├── worker-css.js │ │ │ │ ├── worker-html.js │ │ │ │ ├── worker-javascript.js │ │ │ │ ├── worker-json.js │ │ │ │ ├── worker-lua.js │ │ │ │ ├── worker-php.js │ │ │ │ └── worker-xquery.js │ │ │ ├── uberfire-widgets-core-client/ │ │ │ │ ├── .gitignore │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── widgets/ │ │ │ │ │ │ └── core/ │ │ │ │ │ │ └── client/ │ │ │ │ │ │ ├── CoreEntryPoint.java │ │ │ │ │ │ ├── editors/ │ │ │ │ │ │ │ └── defaulteditor/ │ │ │ │ │ │ │ ├── DefaultEditorFileUpload.java │ │ │ │ │ │ │ ├── DefaultEditorFileUploadBase.java │ │ │ │ │ │ │ ├── DefaultEditorFileUploadBase.ui.xml │ │ │ │ │ │ │ ├── DefaultEditorNewFileUpload.java │ │ │ │ │ │ │ ├── DefaultFileEditorPresenter.java │ │ │ │ │ │ │ ├── DefaultFileEditorView.java │ │ │ │ │ │ │ └── DefaultFileEditorView.ui.xml │ │ │ │ │ │ ├── resources/ │ │ │ │ │ │ │ ├── CoreCss.java │ │ │ │ │ │ │ ├── CoreImages.java │ │ │ │ │ │ │ ├── CoreResources.java │ │ │ │ │ │ │ ├── TreeNavigatorResources.java │ │ │ │ │ │ │ ├── WizardCellListResources.java │ │ │ │ │ │ │ ├── WizardResources.java │ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ │ └── CoreConstants.java │ │ │ │ │ │ ├── screens/ │ │ │ │ │ │ │ └── iframe/ │ │ │ │ │ │ │ ├── IFrameScreenPresenter.java │ │ │ │ │ │ │ └── IFrameScreenView.java │ │ │ │ │ │ ├── tree/ │ │ │ │ │ │ │ ├── FSTreeItem.java │ │ │ │ │ │ │ ├── Tree.java │ │ │ │ │ │ │ └── TreeItem.java │ │ │ │ │ │ ├── wizards/ │ │ │ │ │ │ │ ├── AbstractWizard.java │ │ │ │ │ │ │ ├── Wizard.java │ │ │ │ │ │ │ ├── WizardPage.java │ │ │ │ │ │ │ ├── WizardPageSelectedEvent.java │ │ │ │ │ │ │ ├── WizardPageStatusChangeEvent.java │ │ │ │ │ │ │ ├── WizardPageTitle.java │ │ │ │ │ │ │ ├── WizardPageTitle.ui.xml │ │ │ │ │ │ │ ├── WizardPopupFooter.java │ │ │ │ │ │ │ ├── WizardPopupFooter.ui.xml │ │ │ │ │ │ │ ├── WizardView.java │ │ │ │ │ │ │ ├── WizardViewImpl.java │ │ │ │ │ │ │ └── WizardViewImpl.ui.xml │ │ │ │ │ │ └── workbench/ │ │ │ │ │ │ └── widgets/ │ │ │ │ │ │ └── popups/ │ │ │ │ │ │ └── activities/ │ │ │ │ │ │ └── notfound/ │ │ │ │ │ │ ├── ActivityNotFoundPresenter.java │ │ │ │ │ │ ├── ActivityNotFoundView.java │ │ │ │ │ │ └── ActivityNotFoundView.ui.xml │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── widgets/ │ │ │ │ │ └── core/ │ │ │ │ │ ├── UberfireWidgetsCore.gwt.xml │ │ │ │ │ └── client/ │ │ │ │ │ └── resources/ │ │ │ │ │ ├── css/ │ │ │ │ │ │ ├── TreeNavigator.css │ │ │ │ │ │ ├── Wizards.css │ │ │ │ │ │ └── WizardsCellList.css │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── CoreConstants.properties │ │ │ │ │ ├── CoreConstants_de.properties │ │ │ │ │ ├── CoreConstants_es.properties │ │ │ │ │ ├── CoreConstants_fr.properties │ │ │ │ │ ├── CoreConstants_it.properties │ │ │ │ │ ├── CoreConstants_ja.properties │ │ │ │ │ ├── CoreConstants_pt_BR.properties │ │ │ │ │ └── CoreConstants_zh_CN.properties │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── widgets/ │ │ │ │ └── core/ │ │ │ │ └── client/ │ │ │ │ ├── editors/ │ │ │ │ │ └── defaulteditor/ │ │ │ │ │ ├── DefaultEditorFileUploadBaseTestWrapper.java │ │ │ │ │ ├── DefaultEditorFileUploadParametersTest.java │ │ │ │ │ ├── DefaultEditorFileUploadTest.java │ │ │ │ │ └── UploadEventTest.java │ │ │ │ ├── tree/ │ │ │ │ │ ├── FSTreeItemTest.java │ │ │ │ │ ├── TreeItemTest.java │ │ │ │ │ └── TreeTest.java │ │ │ │ ├── wizards/ │ │ │ │ │ └── WizardViewImplTest.java │ │ │ │ └── workbench/ │ │ │ │ └── widgets/ │ │ │ │ └── popups/ │ │ │ │ └── activities/ │ │ │ │ └── notfound/ │ │ │ │ └── ActivityNotFoundPresenterTest.java │ │ │ └── uberfire-widgets-core-editors/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── widgets/ │ │ │ │ └── core/ │ │ │ │ └── client/ │ │ │ │ ├── editors/ │ │ │ │ │ ├── metafile/ │ │ │ │ │ │ └── MetaFileEditorPresenter.java │ │ │ │ │ └── texteditor/ │ │ │ │ │ ├── TextEditorPresenter.java │ │ │ │ │ ├── TextEditorView.java │ │ │ │ │ ├── TextEditorView.ui.xml │ │ │ │ │ ├── TextEditorWorkbenchEditor.java │ │ │ │ │ └── TextResourceType.java │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ └── EditorsConstants.java │ │ │ └── resources/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── widgets/ │ │ │ └── core/ │ │ │ └── client/ │ │ │ ├── UberfireWidgetsEditors.gwt.xml │ │ │ └── resources/ │ │ │ └── i18n/ │ │ │ ├── EditorsConstants.properties │ │ │ ├── EditorsConstants_de.properties │ │ │ ├── EditorsConstants_es.properties │ │ │ ├── EditorsConstants_fr.properties │ │ │ ├── EditorsConstants_it.properties │ │ │ ├── EditorsConstants_ja.properties │ │ │ ├── EditorsConstants_pt_BR.properties │ │ │ └── EditorsConstants_zh_CN.properties │ │ ├── uberfire-widgets-properties-editor/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ ├── uberfire-widgets-properties-editor-api/ │ │ │ │ ├── .gitignore │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── properties/ │ │ │ │ │ │ └── editor/ │ │ │ │ │ │ ├── model/ │ │ │ │ │ │ │ ├── CustomPropertyEditorFieldInfo.java │ │ │ │ │ │ │ ├── PropertyEditorCategory.java │ │ │ │ │ │ │ ├── PropertyEditorChangeEvent.java │ │ │ │ │ │ │ ├── PropertyEditorEvent.java │ │ │ │ │ │ │ ├── PropertyEditorFieldInfo.java │ │ │ │ │ │ │ ├── PropertyEditorFieldOption.java │ │ │ │ │ │ │ ├── PropertyEditorType.java │ │ │ │ │ │ │ ├── PropertyUtils.java │ │ │ │ │ │ │ └── validators/ │ │ │ │ │ │ │ ├── ColorValidator.java │ │ │ │ │ │ │ ├── LongValidator.java │ │ │ │ │ │ │ ├── MandatoryValidator.java │ │ │ │ │ │ │ ├── PropertyFieldValidator.java │ │ │ │ │ │ │ └── TextValidator.java │ │ │ │ │ │ └── service/ │ │ │ │ │ │ └── BeanPropertyEditorBuilderService.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ └── ErraiApp.properties │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── properties/ │ │ │ │ │ └── editor/ │ │ │ │ │ └── PropertiesEditorAPI.gwt.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── properties/ │ │ │ │ └── editor/ │ │ │ │ └── model/ │ │ │ │ ├── PropertyEditorEventTest.java │ │ │ │ ├── PropertyUtilsTest.java │ │ │ │ └── validators/ │ │ │ │ └── MandatoryValidatorTest.java │ │ │ ├── uberfire-widgets-properties-editor-backend/ │ │ │ │ ├── .gitignore │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── uberfire/ │ │ │ │ │ │ └── ext/ │ │ │ │ │ │ └── properties/ │ │ │ │ │ │ └── editor/ │ │ │ │ │ │ └── server/ │ │ │ │ │ │ └── BeanPropertyEditorBuilder.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ └── beans.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── properties/ │ │ │ │ └── editor/ │ │ │ │ └── server/ │ │ │ │ ├── BeanPropertyEditorBuilderTest.java │ │ │ │ └── beans/ │ │ │ │ ├── ComplexPlanBean.java │ │ │ │ ├── SampleEnum.java │ │ │ │ ├── SamplePlanBean.java │ │ │ │ └── UnknownTypesBean.java │ │ │ └── uberfire-widgets-properties-editor-client/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── properties/ │ │ │ │ │ └── editor/ │ │ │ │ │ └── client/ │ │ │ │ │ ├── PropertyEditorHelper.java │ │ │ │ │ ├── PropertyEditorItemsWidget.java │ │ │ │ │ ├── PropertyEditorItemsWidget.ui.xml │ │ │ │ │ ├── PropertyEditorWidget.java │ │ │ │ │ ├── PropertyEditorWidget.ui.xml │ │ │ │ │ ├── fields/ │ │ │ │ │ │ ├── AbstractField.java │ │ │ │ │ │ ├── BooleanField.java │ │ │ │ │ │ ├── ColorField.java │ │ │ │ │ │ ├── ComboField.java │ │ │ │ │ │ ├── PropertyEditorFieldType.java │ │ │ │ │ │ ├── SecretTextField.java │ │ │ │ │ │ └── TextField.java │ │ │ │ │ ├── options/ │ │ │ │ │ │ └── PropertyEditorFieldOptionUtils.java │ │ │ │ │ ├── resources/ │ │ │ │ │ │ └── i18n/ │ │ │ │ │ │ └── CommonConstants.java │ │ │ │ │ └── widgets/ │ │ │ │ │ ├── AbstractPropertyEditorWidget.java │ │ │ │ │ ├── PropertyEditorCheckBox.java │ │ │ │ │ ├── PropertyEditorCheckBox.ui.xml │ │ │ │ │ ├── PropertyEditorColorPicker.java │ │ │ │ │ ├── PropertyEditorColorPicker.ui.xml │ │ │ │ │ ├── PropertyEditorComboBox.java │ │ │ │ │ ├── PropertyEditorComboBox.ui.xml │ │ │ │ │ ├── PropertyEditorItemButtons.java │ │ │ │ │ ├── PropertyEditorItemButtons.ui.xml │ │ │ │ │ ├── PropertyEditorItemLabel.java │ │ │ │ │ ├── PropertyEditorItemLabel.ui.xml │ │ │ │ │ ├── PropertyEditorItemWidget.java │ │ │ │ │ ├── PropertyEditorItemWidget.ui.xml │ │ │ │ │ ├── PropertyEditorPasswordTextBox.java │ │ │ │ │ ├── PropertyEditorPasswordTextBox.ui.xml │ │ │ │ │ ├── PropertyEditorTextBox.java │ │ │ │ │ └── PropertyEditorTextBox.ui.xml │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── properties/ │ │ │ │ └── editor/ │ │ │ │ ├── PropertiesEditorClient.gwt.xml │ │ │ │ └── client/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── CommonConstants.properties │ │ │ │ ├── CommonConstants_de.properties │ │ │ │ ├── CommonConstants_es.properties │ │ │ │ ├── CommonConstants_fr.properties │ │ │ │ ├── CommonConstants_it.properties │ │ │ │ ├── CommonConstants_ja.properties │ │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ │ └── CommonConstants_zh_CN.properties │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── properties/ │ │ │ └── editor/ │ │ │ └── client/ │ │ │ ├── PropertyEditorHelperTest.java │ │ │ ├── PropertyEditorWidgetTest.java │ │ │ └── options/ │ │ │ └── PropertyEditorFieldOptionUtilsTest.java │ │ ├── uberfire-widgets-sandbox/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── uberfire-widget-markdown/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── widgets/ │ │ │ │ └── sandbox/ │ │ │ │ └── client/ │ │ │ │ └── markdown/ │ │ │ │ ├── Markdown.java │ │ │ │ ├── Markdown.ui.xml │ │ │ │ ├── MarkdownTextContent.java │ │ │ │ ├── MarkdownUtil.java │ │ │ │ ├── editorlive/ │ │ │ │ │ ├── MarkdownLiveEditorPresenter.java │ │ │ │ │ ├── MarkdownLiveEditorView.java │ │ │ │ │ ├── MarkdownLiveEditorView.ui.xml │ │ │ │ │ ├── MarkdownLivePresenter.java │ │ │ │ │ ├── MarkdownLiveView.java │ │ │ │ │ └── MarkdownLiveView.ui.xml │ │ │ │ └── viewer/ │ │ │ │ ├── MarkdownPresenter.java │ │ │ │ ├── MarkdownType.java │ │ │ │ ├── MarkdownView.java │ │ │ │ └── MarkdownView.ui.xml │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── widgets/ │ │ │ └── sandbox/ │ │ │ ├── UberfireMarkdownWidget.gwt.xml │ │ │ └── public/ │ │ │ └── js/ │ │ │ └── showdown.js │ │ ├── uberfire-widgets-service/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ ├── uberfire-widgets-service-api/ │ │ │ │ ├── .gitignore │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── services/ │ │ │ │ │ └── shared/ │ │ │ │ │ └── preferences/ │ │ │ │ │ ├── GridColumnPreference.java │ │ │ │ │ ├── GridGlobalPreferences.java │ │ │ │ │ ├── GridPreferencesStore.java │ │ │ │ │ ├── GridSortedColumnPreference.java │ │ │ │ │ ├── MultiGridPreferencesStore.java │ │ │ │ │ ├── UserPreference.java │ │ │ │ │ ├── UserPreferencesService.java │ │ │ │ │ ├── UserPreferencesType.java │ │ │ │ │ └── UserWorkbenchPreferences.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ └── ErraiApp.properties │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── services/ │ │ │ │ └── UberfireWidgetsServicesAPI.gwt.xml │ │ │ └── uberfire-widgets-service-backend/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── services/ │ │ │ │ └── backend/ │ │ │ │ └── preferences/ │ │ │ │ └── UserPreferencesServiceImpl.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── uberfire-widgets-table/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── widgets/ │ │ │ │ └── table/ │ │ │ │ └── client/ │ │ │ │ ├── CheckboxCellImpl.java │ │ │ │ ├── ColumnChangedHandler.java │ │ │ │ ├── ColumnMeta.java │ │ │ │ ├── DataGrid.java │ │ │ │ ├── PagedTableHelper.java │ │ │ │ ├── ResizableMovableHeader.java │ │ │ │ ├── TableEntryPoint.java │ │ │ │ ├── UberfireColumnPicker.java │ │ │ │ ├── UberfirePagedTable.java │ │ │ │ ├── UberfirePagedTable.ui.xml │ │ │ │ ├── UberfireSimplePager.java │ │ │ │ ├── UberfireSimpleTable.java │ │ │ │ ├── UberfireSimpleTable.ui.xml │ │ │ │ └── resources/ │ │ │ │ ├── UFTableCss.java │ │ │ │ ├── UFTableResources.java │ │ │ │ ├── UberfireSimplePagerResources.java │ │ │ │ └── i18n/ │ │ │ │ └── CommonConstants.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── widgets/ │ │ │ └── table/ │ │ │ ├── UberfireTableWidget.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ ├── css/ │ │ │ │ ├── UberfireSimplePager.css │ │ │ │ └── uftable.css │ │ │ └── i18n/ │ │ │ ├── CommonConstants.properties │ │ │ ├── CommonConstants_de.properties │ │ │ ├── CommonConstants_es.properties │ │ │ ├── CommonConstants_fr.properties │ │ │ ├── CommonConstants_it.properties │ │ │ ├── CommonConstants_ja.properties │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ └── CommonConstants_zh_CN.properties │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── widgets/ │ │ └── table/ │ │ └── client/ │ │ ├── UberfireColumnPickerTest.java │ │ └── UberfireSimpleTableTest.java │ └── uberfire-wires/ │ ├── .gitignore │ ├── README.md │ ├── pom.xml │ ├── uberfire-wires-bayesian-network/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── uberfire-wires-bayesian-network-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── bayesian/ │ │ │ └── network/ │ │ │ └── client/ │ │ │ ├── events/ │ │ │ │ ├── BayesianTemplateSelectedEvent.java │ │ │ │ └── RenderBayesianNetworkEvent.java │ │ │ ├── factory/ │ │ │ │ ├── BaseFactory.java │ │ │ │ ├── BayesianFactory.java │ │ │ │ ├── BayesianNodeCategory.java │ │ │ │ ├── BayesianNodePaletteFactory.java │ │ │ │ └── ProbabilityFactory.java │ │ │ ├── perspectives/ │ │ │ │ └── WiresBayesianPerspective.java │ │ │ ├── screen/ │ │ │ │ └── BayesianScreen.java │ │ │ ├── shapes/ │ │ │ │ ├── EditableBayesianNode.java │ │ │ │ └── EditableBayesianProbability.java │ │ │ ├── templates/ │ │ │ │ ├── StencilTemplateBuilder.java │ │ │ │ ├── TemplateScreen.java │ │ │ │ ├── TemplateScreen.ui.xml │ │ │ │ ├── TemplateShape.java │ │ │ │ └── TemplatesGroup.java │ │ │ ├── utils/ │ │ │ │ └── BayesianUtils.java │ │ │ └── variables/ │ │ │ ├── BayesianVariablesScreen.java │ │ │ ├── BayesianVariablesScreen.ui.xml │ │ │ └── PorcentualsGroup.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── wires/ │ │ └── bayesian/ │ │ └── network/ │ │ └── BayesianNetworkClient.gwt.xml │ ├── uberfire-wires-bayesian-parser/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-wires-bayesian-parser-api/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── wires/ │ │ │ │ └── bayesian/ │ │ │ │ └── network/ │ │ │ │ └── parser/ │ │ │ │ └── client/ │ │ │ │ ├── builder/ │ │ │ │ │ └── BayesianBuilder.java │ │ │ │ ├── model/ │ │ │ │ │ ├── BayesNetwork.java │ │ │ │ │ └── BayesVariable.java │ │ │ │ ├── parser/ │ │ │ │ │ ├── Bif.java │ │ │ │ │ ├── Definition.java │ │ │ │ │ ├── Network.java │ │ │ │ │ ├── NetworkXml.java │ │ │ │ │ ├── Probability.java │ │ │ │ │ ├── Variable.java │ │ │ │ │ └── VariableXml.java │ │ │ │ └── service/ │ │ │ │ └── BayesianService.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── bayesian/ │ │ │ └── network/ │ │ │ └── parser/ │ │ │ └── BayesianNetworkAPI.gwt.xml │ │ └── uberfire-wires-bayesian-parser-backend/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── bayesian/ │ │ │ └── network/ │ │ │ └── parser/ │ │ │ └── backend/ │ │ │ └── BayesianServiceImpl.java │ │ └── resources/ │ │ └── META-INF/ │ │ └── beans.xml │ ├── uberfire-wires-bpmn/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-wires-bpmn-api/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── wires/ │ │ │ │ │ └── bpmn/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── category/ │ │ │ │ │ │ │ └── Process.java │ │ │ │ │ │ ├── model/ │ │ │ │ │ │ │ ├── BpmnEdge.java │ │ │ │ │ │ │ ├── BpmnGraph.java │ │ │ │ │ │ │ ├── BpmnGraphNode.java │ │ │ │ │ │ │ ├── Content.java │ │ │ │ │ │ │ ├── Copyable.java │ │ │ │ │ │ │ ├── Property.java │ │ │ │ │ │ │ ├── Role.java │ │ │ │ │ │ │ ├── impl/ │ │ │ │ │ │ │ │ ├── BpmnEditorContent.java │ │ │ │ │ │ │ │ ├── content/ │ │ │ │ │ │ │ │ │ └── DefaultContentImpl.java │ │ │ │ │ │ │ │ ├── edges/ │ │ │ │ │ │ │ │ │ └── BpmnEdgeImpl.java │ │ │ │ │ │ │ │ ├── nodes/ │ │ │ │ │ │ │ │ │ ├── EndProcessNode.java │ │ │ │ │ │ │ │ │ ├── ProcessNode.java │ │ │ │ │ │ │ │ │ └── StartProcessNode.java │ │ │ │ │ │ │ │ ├── properties/ │ │ │ │ │ │ │ │ │ └── DefaultPropertyImpl.java │ │ │ │ │ │ │ │ ├── roles/ │ │ │ │ │ │ │ │ │ └── DefaultRoleImpl.java │ │ │ │ │ │ │ │ ├── rules/ │ │ │ │ │ │ │ │ │ ├── CardinalityRuleImpl.java │ │ │ │ │ │ │ │ │ ├── ConnectionRuleImpl.java │ │ │ │ │ │ │ │ │ └── ContainmentRuleImpl.java │ │ │ │ │ │ │ │ └── types/ │ │ │ │ │ │ │ │ └── StringType.java │ │ │ │ │ │ │ └── rules/ │ │ │ │ │ │ │ ├── CardinalityRule.java │ │ │ │ │ │ │ ├── ConnectionRule.java │ │ │ │ │ │ │ ├── ContainmentRule.java │ │ │ │ │ │ │ ├── Rule.java │ │ │ │ │ │ │ ├── RuleById.java │ │ │ │ │ │ │ └── RuleByRole.java │ │ │ │ │ │ ├── service/ │ │ │ │ │ │ │ ├── BpmnService.java │ │ │ │ │ │ │ └── todo/ │ │ │ │ │ │ │ └── Metadata.java │ │ │ │ │ │ └── type/ │ │ │ │ │ │ └── BpmnResourceTypeDefinition.java │ │ │ │ │ └── beliefs/ │ │ │ │ │ └── graph/ │ │ │ │ │ ├── Edge.java │ │ │ │ │ ├── Graph.java │ │ │ │ │ ├── GraphNode.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── EdgeImpl.java │ │ │ │ │ ├── GraphImpl.java │ │ │ │ │ ├── GraphNodeImpl.java │ │ │ │ │ ├── GraphStore.java │ │ │ │ │ ├── ListGraphStore.java │ │ │ │ │ └── MapGraphStore.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── ErraiApp.properties │ │ │ │ │ └── beans.xml │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── wires/ │ │ │ │ └── bpmn/ │ │ │ │ └── WiresBpmnApi.gwt.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── bpmn/ │ │ │ └── api/ │ │ │ └── model/ │ │ │ └── impl/ │ │ │ ├── content/ │ │ │ │ └── CopyContentTest.java │ │ │ ├── edges/ │ │ │ │ └── CopyEdgesTest.java │ │ │ ├── nodes/ │ │ │ │ └── CopyNodesTest.java │ │ │ ├── properties/ │ │ │ │ └── CopyPropertiesTest.java │ │ │ └── roles/ │ │ │ └── CopyRolesTest.java │ │ ├── uberfire-wires-bpmn-backend/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── uberfire/ │ │ │ │ │ └── ext/ │ │ │ │ │ └── wires/ │ │ │ │ │ └── bpmn/ │ │ │ │ │ └── backend/ │ │ │ │ │ ├── BpmnPersistence.java │ │ │ │ │ ├── BpmnServiceImpl.java │ │ │ │ │ └── todo/ │ │ │ │ │ ├── CommentedOptionFactory.java │ │ │ │ │ ├── ExceptionUtilities.java │ │ │ │ │ ├── GenericPortableException.java │ │ │ │ │ └── MetadataFactory.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── bpmn/ │ │ │ └── backend/ │ │ │ └── BpmnServiceImplTest.java │ │ └── uberfire-wires-bpmn-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── wires/ │ │ │ │ └── bpmn/ │ │ │ │ └── client/ │ │ │ │ ├── BpmnEntryPoint.java │ │ │ │ ├── commands/ │ │ │ │ │ ├── Command.java │ │ │ │ │ ├── CommandManager.java │ │ │ │ │ ├── Result.java │ │ │ │ │ ├── ResultType.java │ │ │ │ │ ├── Results.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── AddEdgeCommand.java │ │ │ │ │ ├── AddGraphNodeCommand.java │ │ │ │ │ ├── BatchCommand.java │ │ │ │ │ ├── DefaultCommandManagerImpl.java │ │ │ │ │ ├── DefaultResultImpl.java │ │ │ │ │ ├── DefaultResultsImpl.java │ │ │ │ │ ├── DeleteEdgeCommand.java │ │ │ │ │ └── DeleteGraphNodeCommand.java │ │ │ │ ├── editor/ │ │ │ │ │ ├── BpmnEditorPresenter.java │ │ │ │ │ ├── BpmnEditorView.java │ │ │ │ │ ├── BpmnEditorViewImpl.java │ │ │ │ │ └── BpmnEditorViewImpl.ui.xml │ │ │ │ ├── explorer/ │ │ │ │ │ ├── BpmnExplorerPresenter.java │ │ │ │ │ ├── BpmnExplorerView.java │ │ │ │ │ ├── BpmnExplorerViewImpl.java │ │ │ │ │ └── BpmnExplorerViewImpl.ui.xml │ │ │ │ ├── perspectives/ │ │ │ │ │ └── BpmnPerspective.java │ │ │ │ ├── resources/ │ │ │ │ │ ├── BpmnEditorResources.java │ │ │ │ │ ├── css/ │ │ │ │ │ │ └── BpmnEditorCss.java │ │ │ │ │ ├── i18n/ │ │ │ │ │ │ └── BpmnEditorConstants.java │ │ │ │ │ └── images/ │ │ │ │ │ └── BpmnEditorImageResources.java │ │ │ │ ├── rules/ │ │ │ │ │ ├── RuleManager.java │ │ │ │ │ └── impl/ │ │ │ │ │ └── DefaultRuleManagerImpl.java │ │ │ │ └── type/ │ │ │ │ └── BpmnResourceType.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── bpmn/ │ │ │ ├── WiresBpmnClient.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ ├── css/ │ │ │ │ └── bpmn.css │ │ │ └── i18n/ │ │ │ ├── BpmnEditorConstants.properties │ │ │ ├── BpmnEditorConstants_de.properties │ │ │ ├── BpmnEditorConstants_es.properties │ │ │ ├── BpmnEditorConstants_fr.properties │ │ │ ├── BpmnEditorConstants_it.properties │ │ │ ├── BpmnEditorConstants_ja.properties │ │ │ ├── BpmnEditorConstants_pt_BR.properties │ │ │ └── BpmnEditorConstants_zh_CN.properties │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── wires/ │ │ └── bpmn/ │ │ └── client/ │ │ ├── AbstractBaseRuleTest.java │ │ ├── TestDummyNode.java │ │ ├── commands/ │ │ │ └── impl/ │ │ │ ├── AddEdgeCommandTest.java │ │ │ ├── AddGraphNodeCommandTest.java │ │ │ ├── BatchCommandTest.java │ │ │ ├── CommandManagerTest.java │ │ │ ├── DeleteEdgeCommandTest.java │ │ │ ├── DeleteGraphNodeCommandTest.java │ │ │ └── ResultsTest.java │ │ ├── editor/ │ │ │ └── BpmnEditorPresenterTest.java │ │ └── rules/ │ │ └── impl/ │ │ ├── CardinalityRulesTest.java │ │ ├── ConnectionRulesTest.java │ │ └── ContainmentRulesTest.java │ └── uberfire-wires-core/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-wires-core-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── core/ │ │ │ └── api/ │ │ │ ├── containers/ │ │ │ │ ├── ContainerManager.java │ │ │ │ ├── RequiresContainerManager.java │ │ │ │ └── WiresContainer.java │ │ │ ├── controlpoints/ │ │ │ │ ├── ControlPoint.java │ │ │ │ ├── ControlPointMoveHandler.java │ │ │ │ └── HasControlPoints.java │ │ │ ├── events/ │ │ │ │ ├── ClearEvent.java │ │ │ │ ├── ProgressEvent.java │ │ │ │ ├── ShapeAddedEvent.java │ │ │ │ ├── ShapeDeletedEvent.java │ │ │ │ ├── ShapeDragCompleteEvent.java │ │ │ │ ├── ShapeDragPreviewEvent.java │ │ │ │ └── ShapeSelectedEvent.java │ │ │ ├── factories/ │ │ │ │ ├── FactoryHelper.java │ │ │ │ ├── ShapeDragProxy.java │ │ │ │ ├── ShapeDragProxyCompleteCallback.java │ │ │ │ ├── ShapeDragProxyPreviewCallback.java │ │ │ │ ├── ShapeDropContext.java │ │ │ │ ├── ShapeFactory.java │ │ │ │ ├── ShapeGlyph.java │ │ │ │ └── categories/ │ │ │ │ └── Category.java │ │ │ ├── layout/ │ │ │ │ ├── LayoutManager.java │ │ │ │ └── RequiresLayoutManager.java │ │ │ ├── magnets/ │ │ │ │ ├── HasMagnets.java │ │ │ │ ├── Magnet.java │ │ │ │ ├── MagnetManager.java │ │ │ │ └── RequiresMagnetManager.java │ │ │ ├── properties/ │ │ │ │ └── PropertyEditorAdaptor.java │ │ │ ├── selection/ │ │ │ │ ├── RequiresSelectionManager.java │ │ │ │ └── SelectionManager.java │ │ │ └── shapes/ │ │ │ ├── OverridesFactoryDescription.java │ │ │ ├── RequiresShapesManager.java │ │ │ ├── ShapesManager.java │ │ │ ├── WiresBaseDynamicContainer.java │ │ │ ├── WiresBaseDynamicShape.java │ │ │ ├── WiresBaseShape.java │ │ │ └── WiresShape.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── wires/ │ │ └── core/ │ │ └── WiresCoreApi.gwt.xml │ ├── uberfire-wires-core-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── core/ │ │ │ └── client/ │ │ │ ├── actions/ │ │ │ │ ├── ActionShape.java │ │ │ │ ├── ActionsGroup.java │ │ │ │ ├── ActionsScreen.java │ │ │ │ ├── ActionsScreen.ui.xml │ │ │ │ └── StencilActionBuilder.java │ │ │ ├── canvas/ │ │ │ │ ├── FocusableLienzoPanel.java │ │ │ │ └── WiresCanvas.java │ │ │ ├── controlpoints/ │ │ │ │ ├── ConnectibleControlPoint.java │ │ │ │ └── DefaultControlPoint.java │ │ │ ├── factories/ │ │ │ │ ├── AbstractBaseFactory.java │ │ │ │ ├── ShapeFactoryCache.java │ │ │ │ ├── StringFactoryHelper.java │ │ │ │ └── categories/ │ │ │ │ ├── ConnectorCategory.java │ │ │ │ ├── ContainerCategory.java │ │ │ │ ├── FixedShapeCategory.java │ │ │ │ └── ShapeCategory.java │ │ │ ├── layers/ │ │ │ │ ├── LayerShape.java │ │ │ │ ├── LayersGroup.java │ │ │ │ ├── LayersScreen.java │ │ │ │ ├── LayersScreen.ui.xml │ │ │ │ └── StencilLayerBuilder.java │ │ │ ├── magnets/ │ │ │ │ └── DefaultMagnet.java │ │ │ ├── palette/ │ │ │ │ ├── BaseGroup.java │ │ │ │ ├── ConnectorsGroup.java │ │ │ │ ├── ContainersGroup.java │ │ │ │ ├── FixedShapesGroup.java │ │ │ │ ├── PaletteLayoutUtilities.java │ │ │ │ ├── PaletteScreen.java │ │ │ │ ├── PaletteScreen.ui.xml │ │ │ │ ├── PaletteShape.java │ │ │ │ ├── ShapesGroup.java │ │ │ │ └── StencilPaletteBuilder.java │ │ │ ├── progressbar/ │ │ │ │ └── ProgressBar.java │ │ │ ├── properties/ │ │ │ │ ├── DoubleValidator.java │ │ │ │ ├── PropertiesScreen.java │ │ │ │ ├── PropertiesScreen.ui.xml │ │ │ │ ├── PropertyEditorAdaptorsCache.java │ │ │ │ └── WiresComboPropertyEditorFieldInfo.java │ │ │ ├── resources/ │ │ │ │ ├── AppImages.java │ │ │ │ └── AppResource.java │ │ │ └── util/ │ │ │ ├── GeometryUtil.java │ │ │ ├── ShapeFactoryUtil.java │ │ │ └── ShapesUtils.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── wires/ │ │ └── core/ │ │ └── WiresCoreClient.gwt.xml │ ├── uberfire-wires-core-grids/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ext/ │ │ │ │ └── wires/ │ │ │ │ └── core/ │ │ │ │ └── grids/ │ │ │ │ └── client/ │ │ │ │ ├── model/ │ │ │ │ │ ├── Bounds.java │ │ │ │ │ ├── GridCell.java │ │ │ │ │ ├── GridCellEditAction.java │ │ │ │ │ ├── GridCellValue.java │ │ │ │ │ ├── GridColumn.java │ │ │ │ │ ├── GridData.java │ │ │ │ │ ├── GridRow.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── BaseBounds.java │ │ │ │ │ ├── BaseGridCell.java │ │ │ │ │ ├── BaseGridCellValue.java │ │ │ │ │ ├── BaseGridColumn.java │ │ │ │ │ ├── BaseGridData.java │ │ │ │ │ ├── BaseGridDataIndexManager.java │ │ │ │ │ ├── BaseGridDataSelectionsManager.java │ │ │ │ │ ├── BaseGridRow.java │ │ │ │ │ └── BaseHeaderMetaData.java │ │ │ │ ├── util/ │ │ │ │ │ ├── CellContextUtilities.java │ │ │ │ │ ├── ColumnIndexUtilities.java │ │ │ │ │ ├── CoordinateUtilities.java │ │ │ │ │ ├── GridHighlightHelper.java │ │ │ │ │ ├── Logging.java │ │ │ │ │ └── MathUtilities.java │ │ │ │ └── widget/ │ │ │ │ ├── context/ │ │ │ │ │ ├── GridBodyCellEditContext.java │ │ │ │ │ ├── GridBodyCellRenderContext.java │ │ │ │ │ ├── GridBodyColumnRenderContext.java │ │ │ │ │ ├── GridBodyRenderContext.java │ │ │ │ │ ├── GridBoundaryRenderContext.java │ │ │ │ │ ├── GridHeaderColumnRenderContext.java │ │ │ │ │ └── GridHeaderRenderContext.java │ │ │ │ ├── dnd/ │ │ │ │ │ ├── GridWidgetDnDHandlersState.java │ │ │ │ │ ├── GridWidgetDnDMouseDownHandler.java │ │ │ │ │ ├── GridWidgetDnDMouseMoveHandler.java │ │ │ │ │ ├── GridWidgetDnDMouseUpHandler.java │ │ │ │ │ ├── GridWidgetDnDProxy.java │ │ │ │ │ └── IsRowDragHandle.java │ │ │ │ ├── dom/ │ │ │ │ │ ├── DOMElementFactory.java │ │ │ │ │ ├── HasDOMElementResources.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── BaseDOMElement.java │ │ │ │ │ │ ├── CheckBoxDOMElement.java │ │ │ │ │ │ ├── ListBoxDOMElement.java │ │ │ │ │ │ └── TextBoxDOMElement.java │ │ │ │ │ ├── multiple/ │ │ │ │ │ │ ├── HasMultipleDOMElementResources.java │ │ │ │ │ │ ├── MultipleDOMElementFactory.java │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── BaseDOMElementFactory.java │ │ │ │ │ │ ├── CheckBoxDOMElementFactory.java │ │ │ │ │ │ └── TextBoxDOMElementFactory.java │ │ │ │ │ └── single/ │ │ │ │ │ ├── HasSingletonDOMElementResource.java │ │ │ │ │ ├── SingletonDOMElementFactory.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── BaseSingletonDOMElementFactory.java │ │ │ │ │ ├── ListBoxSingletonDOMElementFactory.java │ │ │ │ │ └── TextBoxSingletonDOMElementFactory.java │ │ │ │ ├── edit/ │ │ │ │ │ └── EditorPopup.java │ │ │ │ ├── grid/ │ │ │ │ │ ├── GridWidget.java │ │ │ │ │ ├── NodeMouseEventHandler.java │ │ │ │ │ ├── animation/ │ │ │ │ │ │ ├── GridWidgetEnterPinnedModeAnimation.java │ │ │ │ │ │ ├── GridWidgetExitPinnedModeAnimation.java │ │ │ │ │ │ ├── GridWidgetScrollIntoViewAnimation.java │ │ │ │ │ │ ├── MergableGridWidgetCollapseRowsAnimation.java │ │ │ │ │ │ └── MergableGridWidgetExpandRowsAnimation.java │ │ │ │ │ ├── columns/ │ │ │ │ │ │ ├── BooleanDOMElementColumn.java │ │ │ │ │ │ ├── ListBoxDOMElementSingletonColumn.java │ │ │ │ │ │ ├── RowNumberColumn.java │ │ │ │ │ │ ├── StringDOMElementColumn.java │ │ │ │ │ │ ├── StringDOMElementSingletonColumn.java │ │ │ │ │ │ └── StringPopupColumn.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── BaseGridWidget.java │ │ │ │ │ │ ├── BaseGridWidgetKeyboardHandler.java │ │ │ │ │ │ ├── BaseGridWidgetMouseClickHandler.java │ │ │ │ │ │ ├── BaseGridWidgetMouseDoubleClickHandler.java │ │ │ │ │ │ ├── BaseGridWidgetMouseEventHandler.java │ │ │ │ │ │ ├── BaseKeyboardOperation.java │ │ │ │ │ │ ├── DefaultGridWidgetCellSelectorMouseEventHandler.java │ │ │ │ │ │ ├── DefaultGridWidgetCollapsedCellMouseEventHandler.java │ │ │ │ │ │ ├── DefaultGridWidgetEditCellMouseEventHandler.java │ │ │ │ │ │ ├── DefaultGridWidgetLinkedColumnMouseEventHandler.java │ │ │ │ │ │ ├── DefaultGridWidgetPinnedModeMouseEventHandler.java │ │ │ │ │ │ ├── GridWidgetConnector.java │ │ │ │ │ │ ├── KeyboardOperation.java │ │ │ │ │ │ ├── KeyboardOperationClearCell.java │ │ │ │ │ │ ├── KeyboardOperationEditCell.java │ │ │ │ │ │ ├── KeyboardOperationInvokeContextMenuForSelectedCell.java │ │ │ │ │ │ ├── KeyboardOperationMove.java │ │ │ │ │ │ ├── KeyboardOperationMoveDown.java │ │ │ │ │ │ ├── KeyboardOperationMoveLeft.java │ │ │ │ │ │ ├── KeyboardOperationMoveRight.java │ │ │ │ │ │ ├── KeyboardOperationMoveUp.java │ │ │ │ │ │ ├── KeyboardOperationSelectBottomRightCell.java │ │ │ │ │ │ └── KeyboardOperationSelectTopLeftCell.java │ │ │ │ │ ├── keyboard/ │ │ │ │ │ │ └── KeyDownHandlerCommon.java │ │ │ │ │ ├── renderers/ │ │ │ │ │ │ ├── columns/ │ │ │ │ │ │ │ ├── GridColumnRenderer.java │ │ │ │ │ │ │ ├── impl/ │ │ │ │ │ │ │ │ ├── BaseGridColumnRenderer.java │ │ │ │ │ │ │ │ ├── BoundingBoxPathClipperFactory.java │ │ │ │ │ │ │ │ ├── ColumnRenderingStrategyFlattened.java │ │ │ │ │ │ │ │ ├── ColumnRenderingStrategyMerged.java │ │ │ │ │ │ │ │ ├── IntegerColumnRenderer.java │ │ │ │ │ │ │ │ └── StringColumnRenderer.java │ │ │ │ │ │ │ ├── multiple/ │ │ │ │ │ │ │ │ ├── GridColumnMultipleDOMElementRenderer.java │ │ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ │ │ ├── BaseGridColumnMultipleDOMElementRenderer.java │ │ │ │ │ │ │ │ ├── BooleanColumnDOMElementRenderer.java │ │ │ │ │ │ │ │ └── StringColumnDOMElementRenderer.java │ │ │ │ │ │ │ └── single/ │ │ │ │ │ │ │ ├── GridColumnSingletonDOMElementRenderer.java │ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ │ ├── BaseGridColumnSingletonDOMElementRenderer.java │ │ │ │ │ │ │ ├── ListBoxColumnDOMElementSingletonRenderer.java │ │ │ │ │ │ │ └── StringColumnDOMElementSingletonRenderer.java │ │ │ │ │ │ ├── grids/ │ │ │ │ │ │ │ ├── GridRenderer.java │ │ │ │ │ │ │ ├── SelectionsTransformer.java │ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ │ ├── BaseGridRenderer.java │ │ │ │ │ │ │ ├── BaseGridRendererHelper.java │ │ │ │ │ │ │ ├── DefaultSelectionsTransformer.java │ │ │ │ │ │ │ ├── FloatingSelectionsTransformer.java │ │ │ │ │ │ │ ├── GroupingToggle.java │ │ │ │ │ │ │ └── SelectedRange.java │ │ │ │ │ │ └── themes/ │ │ │ │ │ │ ├── GridRendererTheme.java │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── BlueTheme.java │ │ │ │ │ │ ├── GreenTheme.java │ │ │ │ │ │ ├── KIEColours.java │ │ │ │ │ │ ├── KIEStyles.java │ │ │ │ │ │ ├── MultiColouredTheme.java │ │ │ │ │ │ └── RedTheme.java │ │ │ │ │ └── selections/ │ │ │ │ │ ├── CellSelectionManager.java │ │ │ │ │ ├── CellSelectionStrategy.java │ │ │ │ │ ├── SelectionExtension.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── BaseCellSelectionManager.java │ │ │ │ │ ├── BaseCellSelectionStrategy.java │ │ │ │ │ ├── HeaderSingleCellSelectionStrategy.java │ │ │ │ │ ├── RangeSelectionStrategy.java │ │ │ │ │ └── RowSelectionStrategy.java │ │ │ │ ├── layer/ │ │ │ │ │ ├── GridLayer.java │ │ │ │ │ ├── GridSelectionManager.java │ │ │ │ │ ├── GridWidgetRegistry.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── DefaultGridLayer.java │ │ │ │ │ │ ├── GridLayerRedrawManager.java │ │ │ │ │ │ └── GridLienzoPanel.java │ │ │ │ │ └── pinning/ │ │ │ │ │ ├── GridPinnedModeManager.java │ │ │ │ │ ├── IsPinnedModeAware.java │ │ │ │ │ ├── TransformMediator.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── BoundaryTransformMediator.java │ │ │ │ │ ├── DefaultPinnedModeManager.java │ │ │ │ │ ├── GridTransformMediator.java │ │ │ │ │ └── RestrictedMousePanMediator.java │ │ │ │ └── scrollbars/ │ │ │ │ ├── GridLienzoScrollBars.java │ │ │ │ ├── GridLienzoScrollBounds.java │ │ │ │ ├── GridLienzoScrollHandler.java │ │ │ │ ├── GridLienzoScrollPosition.java │ │ │ │ ├── GridLienzoScrollUI.java │ │ │ │ └── GridLienzoScrollable.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── core/ │ │ │ └── grids/ │ │ │ └── WiresCoreGrids.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── wires/ │ │ └── core/ │ │ └── grids/ │ │ └── client/ │ │ ├── model/ │ │ │ ├── GridCellEditActionTest.java │ │ │ └── impl/ │ │ │ ├── BaseBoundsTest.java │ │ │ ├── BaseGridDataTest.java │ │ │ ├── BaseGridTest.java │ │ │ ├── GridCellSelectionsTest.java │ │ │ ├── GridCellSelectionsTransformationTest.java │ │ │ ├── GridColumnIndexingTest.java │ │ │ ├── GridColumnsTest.java │ │ │ ├── GridGroupingTest.java │ │ │ ├── GridMergingTest.java │ │ │ ├── GridRowsMergedTest.java │ │ │ └── GridRowsUnmergedTest.java │ │ ├── util/ │ │ │ ├── CellContextUtilitiesTest.java │ │ │ ├── ColumnIndexUtilitiesTest.java │ │ │ ├── CoordinateUtilitiesTest.java │ │ │ ├── GridHighlightHelperTest.java │ │ │ └── LoggingTest.java │ │ └── widget/ │ │ ├── dnd/ │ │ │ ├── GridWidgetDnDMouseDownHandlerTest.java │ │ │ ├── GridWidgetDnDMouseMoveHandlerTest.java │ │ │ └── GridWidgetDnDMouseUpHandlerTest.java │ │ ├── dom/ │ │ │ └── single/ │ │ │ └── impl/ │ │ │ ├── BaseSingletonDOMElementFactoryTest.java │ │ │ ├── ListBoxSingletonDOMElementFactoryTest.java │ │ │ └── TextBoxSingletonDOMElementFactoryTest.java │ │ ├── grid/ │ │ │ ├── NodeMouseEventHandlerTest.java │ │ │ ├── animation/ │ │ │ │ ├── GridWidgetEnterPinnedModeAnimationTest.java │ │ │ │ └── GridWidgetExitPinnedModeAnimationTest.java │ │ │ ├── columns/ │ │ │ │ └── BooleanDOMElementColumnTest.java │ │ │ ├── impl/ │ │ │ │ ├── BaseGridWidgetKeyboardHandlerTest.java │ │ │ │ ├── BaseGridWidgetMouseClickHandlerTest.java │ │ │ │ ├── BaseGridWidgetMouseDoubleClickHandlerTest.java │ │ │ │ ├── BaseGridWidgetRenderingTest.java │ │ │ │ ├── BaseGridWidgetRenderingTestUtils.java │ │ │ │ ├── BaseGridWidgetTest.java │ │ │ │ ├── BaseKeyboardOperationTest.java │ │ │ │ ├── DefaultGridWidgetCellSelectorMouseEventHandlerTest.java │ │ │ │ ├── DefaultGridWidgetCollapsedCellMouseEventHandlerTest.java │ │ │ │ ├── DefaultGridWidgetEditCellMouseEventHandlerTest.java │ │ │ │ ├── DefaultGridWidgetLinkedColumnMouseEventHandlerTest.java │ │ │ │ ├── DefaultGridWidgetPinnedModeMouseEventHandlerTest.java │ │ │ │ ├── KeyboardOperationInvokeContextMenuForSelectedCellTest.java │ │ │ │ ├── KeyboardOperationMoveDownTest.java │ │ │ │ ├── KeyboardOperationMoveLeftTest.java │ │ │ │ ├── KeyboardOperationMoveRightTest.java │ │ │ │ ├── KeyboardOperationMoveTest.java │ │ │ │ └── KeyboardOperationMoveUpTest.java │ │ │ ├── keyboard/ │ │ │ │ ├── BaseKeyDownHandlerCommonTest.java │ │ │ │ ├── KeyDownHandlerCommonEnterKeyTest.java │ │ │ │ ├── KeyDownHandlerCommonEscapeKeyTest.java │ │ │ │ ├── KeyDownHandlerCommonTabKeyTest.java │ │ │ │ └── KeyDownHandlerCommonTest.java │ │ │ ├── renderers/ │ │ │ │ ├── columns/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── BaseColumnRendererTest.java │ │ │ │ │ ├── ColumnRenderingStrategyFlattenedTest.java │ │ │ │ │ ├── ColumnRenderingStrategyMergedTest.java │ │ │ │ │ ├── IntegerColumnRendererTest.java │ │ │ │ │ └── StringColumnRendererTest.java │ │ │ │ └── grids/ │ │ │ │ └── impl/ │ │ │ │ ├── BaseGridRendererHelperTest.java │ │ │ │ ├── BaseGridRendererNonSelectionLayerTest.java │ │ │ │ ├── BaseGridRendererSelectionLayerTest.java │ │ │ │ └── BaseGridRendererTest.java │ │ │ └── selections/ │ │ │ ├── SelectionExtensionTest.java │ │ │ └── impl/ │ │ │ ├── BaseCellSelectionManagerTest.java │ │ │ ├── BaseCellSelectionStrategyTest.java │ │ │ ├── HeaderSingleCellSelectionStrategyTest.java │ │ │ ├── RangeSelectionStrategyMergedDataTest.java │ │ │ ├── RangeSelectionStrategyUnmergedDataTest.java │ │ │ ├── RowSelectionStrategyMergedDataTest.java │ │ │ └── RowSelectionStrategyUnmergedDataTest.java │ │ ├── layer/ │ │ │ ├── impl/ │ │ │ │ ├── DefaultGridLayerTest.java │ │ │ │ ├── GridLayerRedrawManagerTest.java │ │ │ │ └── GridLienzoPanelTest.java │ │ │ └── pinning/ │ │ │ └── impl/ │ │ │ ├── BoundaryMousePanMediatorTest.java │ │ │ ├── BoundaryTransformMediatorTest.java │ │ │ ├── DefaultPinnedModeManagerTest.java │ │ │ ├── GridTransformMediatorTest.java │ │ │ └── RestrictedMousePanMediatorTest.java │ │ └── scrollbars/ │ │ ├── GridLienzoScrollBarsTest.java │ │ ├── GridLienzoScrollBoundsTest.java │ │ ├── GridLienzoScrollHandlerTest.java │ │ ├── GridLienzoScrollPositionTest.java │ │ └── GridLienzoScrollUITest.java │ ├── uberfire-wires-core-scratchpad/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── wires/ │ │ │ └── core/ │ │ │ └── scratchpad/ │ │ │ └── client/ │ │ │ ├── canvas/ │ │ │ │ ├── WiresScratchPadDropContext.java │ │ │ │ └── WiresScratchPadScreen.java │ │ │ ├── factories/ │ │ │ │ ├── connectors/ │ │ │ │ │ ├── ArrowFactory.java │ │ │ │ │ ├── BezierCurveFactory.java │ │ │ │ │ └── LineFactory.java │ │ │ │ ├── containers/ │ │ │ │ │ ├── CircularContainerFactory.java │ │ │ │ │ └── RectangularContainerFactory.java │ │ │ │ ├── dynamic/ │ │ │ │ │ ├── CircleFactory.java │ │ │ │ │ └── RectangleFactory.java │ │ │ │ └── fixed/ │ │ │ │ ├── FixedCircleFactory.java │ │ │ │ └── FixedTextFactory.java │ │ │ ├── perspectives/ │ │ │ │ └── WiresScratchPadPerspective.java │ │ │ ├── properties/ │ │ │ │ ├── CssHexColourValidator.java │ │ │ │ ├── DefaultPropertyEditorAdaptor.java │ │ │ │ ├── WiresCirclePropertyEditorAdaptor.java │ │ │ │ ├── WiresFixedTextPropertyEditorAdaptor.java │ │ │ │ └── WiresRectanglePropertyEditorAdaptor.java │ │ │ └── shapes/ │ │ │ ├── WiresScratchPadDefaultShape.java │ │ │ ├── connectors/ │ │ │ │ ├── WiresArrow.java │ │ │ │ ├── WiresBezierCurve.java │ │ │ │ └── WiresLine.java │ │ │ ├── containers/ │ │ │ │ ├── WiresCircularContainer.java │ │ │ │ └── WiresRectangularContainer.java │ │ │ ├── dynamic/ │ │ │ │ ├── WiresCircle.java │ │ │ │ └── WiresRectangle.java │ │ │ └── fixed/ │ │ │ ├── WiresFixedCircle.java │ │ │ └── WiresFixedText.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── wires/ │ │ └── core/ │ │ └── scratchpad/ │ │ └── WiresCoreScratchPad.gwt.xml │ └── uberfire-wires-core-trees/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── wires/ │ │ └── core/ │ │ └── trees/ │ │ └── client/ │ │ ├── canvas/ │ │ │ ├── WiresTreeNodeConnector.java │ │ │ ├── WiresTreeNodeDropContext.java │ │ │ └── WiresTreesScreen.java │ │ ├── layout/ │ │ │ ├── WiresLayoutUtilities.java │ │ │ ├── WiresTreesDefaultLayout.java │ │ │ └── treelayout/ │ │ │ ├── AbstractTreeForTreeLayout.java │ │ │ ├── Configuration.java │ │ │ ├── DefaultConfiguration.java │ │ │ ├── NodeExtentProvider.java │ │ │ ├── Point2D.java │ │ │ ├── Rectangle2D.java │ │ │ ├── TreeForTreeLayout.java │ │ │ ├── TreeLayout.java │ │ │ └── util/ │ │ │ ├── IterableUtil.java │ │ │ ├── IteratorUtil.java │ │ │ └── ListUtil.java │ │ └── shapes/ │ │ └── WiresBaseTreeNode.java │ └── resources/ │ ├── META-INF/ │ │ ├── ErraiApp.properties │ │ └── beans.xml │ └── org/ │ └── uberfire/ │ └── ext/ │ └── wires/ │ └── core/ │ └── trees/ │ └── WiresCoreTrees.gwt.xml ├── uberfire-io/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── io/ │ │ │ ├── IOService.java │ │ │ ├── IOWatchService.java │ │ │ ├── attribute/ │ │ │ │ ├── DublinCoreAttributes.java │ │ │ │ ├── DublinCoreAttributesUtil.java │ │ │ │ └── DublinCoreView.java │ │ │ ├── impl/ │ │ │ │ ├── AbstractIOService.java │ │ │ │ ├── IOServiceDotFileImpl.java │ │ │ │ ├── IOServiceIdentifiable.java │ │ │ │ ├── IOServiceLockable.java │ │ │ │ └── IOServiceNio2WrapperImpl.java │ │ │ ├── lock/ │ │ │ │ └── BatchLockControl.java │ │ │ └── regex/ │ │ │ └── AntPathMatcher.java │ │ └── resources/ │ │ └── org/ │ │ └── uberfire/ │ │ └── io/ │ │ └── UberfireIO.gwt.xml │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── io/ │ │ ├── CommonIOExceptionsServiceDotFileTest.java │ │ ├── CommonIOServiceDotFileTest.java │ │ ├── GitIOServiceDotFileTest.java │ │ ├── OpenCloseTest.java │ │ ├── SimpleFSIOServiceDotFileTest.java │ │ ├── attribute/ │ │ │ ├── DotFileAttrViewTest.java │ │ │ └── DublinCoreTest.java │ │ ├── impl/ │ │ │ ├── BatchTest.java │ │ │ └── WatcherTest.java │ │ └── regex/ │ │ └── AntPathMatcherTest.java │ └── resources/ │ ├── META-INF/ │ │ └── services/ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ └── simplelogger.properties ├── uberfire-js/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── client/ │ │ │ ├── JSEntryPoint.java │ │ │ ├── editor/ │ │ │ │ ├── JSEditorActivity.java │ │ │ │ ├── JSNativeEditor.java │ │ │ │ └── type/ │ │ │ │ ├── JSClientResourceType.java │ │ │ │ └── JSNativeClientResourceType.java │ │ │ ├── exporter/ │ │ │ │ ├── EditorJSExporter.java │ │ │ │ ├── JSExporterUtils.java │ │ │ │ ├── PerspectiveJSExporter.java │ │ │ │ ├── PlaceManagerJSExporter.java │ │ │ │ ├── PluginJSExporter.java │ │ │ │ ├── ResourceTypeDefinitionJSExporter.java │ │ │ │ ├── SplashScreenJSExporter.java │ │ │ │ ├── UberfireJSAPIExporter.java │ │ │ │ ├── UberfireJSExporter.java │ │ │ │ └── VFSJSExporter.java │ │ │ ├── perspective/ │ │ │ │ ├── JSNativePerspective.java │ │ │ │ ├── JSPanelDefinition.java │ │ │ │ ├── JSPartDefinition.java │ │ │ │ └── JSWorkbenchPerspectiveActivity.java │ │ │ ├── plugin/ │ │ │ │ ├── JSNativePlugin.java │ │ │ │ ├── RuntimePluginsServiceProxy.java │ │ │ │ └── RuntimePluginsServiceProxyClientImpl.java │ │ │ ├── screen/ │ │ │ │ ├── JSNativeScreen.java │ │ │ │ └── JSWorkbenchScreenActivity.java │ │ │ └── splash/ │ │ │ ├── JSNativeSplashScreen.java │ │ │ └── JSSplashScreenActivity.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── UberfireJS.gwt.xml │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── client/ │ └── exporter/ │ └── JSExporterUtilsTest.java ├── uberfire-m2repo-editor/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-m2repo-editor-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── m2repo/ │ │ │ ├── exception/ │ │ │ │ └── InvalidValueException.java │ │ │ ├── model/ │ │ │ │ ├── HTMLFileManagerFields.java │ │ │ │ ├── JarListPageRequest.java │ │ │ │ └── JarListPageRow.java │ │ │ ├── preferences/ │ │ │ │ └── ArtifactRepositoryPreference.java │ │ │ ├── security/ │ │ │ │ └── MavenRepositoryPagedJarTableFeatures.java │ │ │ ├── service/ │ │ │ │ └── M2RepoService.java │ │ │ └── utils/ │ │ │ └── FileNameUtilities.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── guvnor/ │ │ └── m2repo/ │ │ └── GuvnorM2RepoEditorAPI.gwt.xml │ ├── uberfire-m2repo-editor-backend/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── m2repo/ │ │ │ │ └── backend/ │ │ │ │ └── server/ │ │ │ │ ├── ArtifactImpl.java │ │ │ │ ├── ExtendedM2RepoService.java │ │ │ │ ├── FixNotMavenizedArtifactInfo.java │ │ │ │ ├── GuvnorM2Repository.java │ │ │ │ ├── M2RepoServiceImpl.java │ │ │ │ ├── M2Servlet.java │ │ │ │ ├── M2ServletContextListener.java │ │ │ │ ├── helpers/ │ │ │ │ │ ├── FormData.java │ │ │ │ │ ├── HttpGetHelper.java │ │ │ │ │ ├── HttpPostHelper.java │ │ │ │ │ ├── HttpPutHelper.java │ │ │ │ │ └── PomModelResolver.java │ │ │ │ └── repositories/ │ │ │ │ ├── ArtifactRepository.java │ │ │ │ ├── ArtifactRepositoryProducer.java │ │ │ │ ├── ArtifactRepositoryService.java │ │ │ │ ├── DistributionManagementArtifactRepository.java │ │ │ │ ├── FileSystemArtifactRepository.java │ │ │ │ ├── LocalArtifactRepository.java │ │ │ │ ├── NullArtifactRepository.java │ │ │ │ └── Repository.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── m2repo/ │ │ │ └── backend/ │ │ │ └── server/ │ │ │ ├── FixNotMavenizedArtifactInfoTest.java │ │ │ ├── GAVResolverFromParentPomTest.java │ │ │ ├── GuvnorM2RepositoryTest.java │ │ │ ├── JarPathTest.java │ │ │ ├── M2MavenRepositoryServiceImplTest.java │ │ │ ├── M2RepoServiceCreator.java │ │ │ ├── M2RepoServiceImplM2RepoURLTest.java │ │ │ ├── M2ServletContextListenerTest.java │ │ │ ├── MockFileItem.java │ │ │ ├── helpers/ │ │ │ │ └── UploadInvalidPomTest.java │ │ │ └── repositories/ │ │ │ ├── ArtifactRepositoryServiceTest.java │ │ │ └── LocalArtifactRepositoryTest.java │ │ └── resources/ │ │ ├── not-mavenized-artifacts.properties │ │ └── org/ │ │ └── guvnor/ │ │ └── m2repo/ │ │ └── backend/ │ │ └── server/ │ │ ├── evaluation-12.1.1.jar │ │ ├── guvnor-m2repo-editor-backend-test-pom.xml │ │ ├── guvnor-m2repo-editor-backend-test-with-distribution-management.jar │ │ ├── guvnor-m2repo-editor-backend-test-with-pom.jar │ │ ├── guvnor-m2repo-editor-backend-test-without-pom.jar │ │ ├── helpers/ │ │ │ ├── broken-pom.xml │ │ │ ├── gav-pom-without-group.xml │ │ │ ├── gav-pom-without-version.xml │ │ │ └── non-existing-parent-gav-pom.xml │ │ ├── parent-gav-pom.xml │ │ ├── settings-security.xml │ │ ├── settings.xml │ │ └── uberfire-m2repo-editor-backend-100-SNAPSHOT.jar │ └── uberfire-m2repo-editor-client/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── m2repo/ │ │ │ └── client/ │ │ │ ├── M2RepoEditorEntryPoint.java │ │ │ ├── M2RepoEditorPresenter.java │ │ │ ├── editor/ │ │ │ │ ├── GAVEditor.java │ │ │ │ ├── JarDetailPopup.java │ │ │ │ ├── JarDetailPopup.ui.xml │ │ │ │ └── MavenRepositoryPagedJarTable.java │ │ │ ├── event/ │ │ │ │ ├── M2RepoRefreshEvent.java │ │ │ │ └── M2RepoSearchEvent.java │ │ │ ├── resources/ │ │ │ │ ├── M2RepoEditorResources.java │ │ │ │ ├── css/ │ │ │ │ │ └── StylesCss.java │ │ │ │ ├── i18n/ │ │ │ │ │ ├── M2Constants.java │ │ │ │ │ └── M2RepoEditorConstants.java │ │ │ │ └── images/ │ │ │ │ └── M2RepoEditorImageResources.java │ │ │ ├── upload/ │ │ │ │ ├── UploadFormPresenter.java │ │ │ │ ├── UploadFormView.java │ │ │ │ └── UploadFormViewImpl.java │ │ │ └── widgets/ │ │ │ ├── ArtifactListPresenter.java │ │ │ ├── ArtifactListPresenterImpl.java │ │ │ ├── ArtifactListView.java │ │ │ ├── ArtifactListViewImpl.java │ │ │ ├── ArtifactListViewImpl.ui.xml │ │ │ └── ColumnType.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── guvnor/ │ │ └── m2repo/ │ │ ├── GuvnorM2RepoEditorClient.gwt.xml │ │ └── client/ │ │ └── resources/ │ │ ├── css/ │ │ │ └── Styles.css │ │ └── i18n/ │ │ ├── M2Constants.properties │ │ ├── M2Constants_es.properties │ │ ├── M2Constants_fr.properties │ │ ├── M2Constants_it.properties │ │ ├── M2Constants_ja.properties │ │ ├── M2RepoEditorConstants.properties │ │ ├── M2RepoEditorConstants_de.properties │ │ ├── M2RepoEditorConstants_es.properties │ │ ├── M2RepoEditorConstants_fr.properties │ │ ├── M2RepoEditorConstants_it.properties │ │ ├── M2RepoEditorConstants_ja.properties │ │ ├── M2RepoEditorConstants_ja_JP.properties │ │ ├── M2RepoEditorConstants_pt_BR.properties │ │ └── M2RepoEditorConstants_zh_CN.properties │ └── test/ │ └── java/ │ └── org/ │ └── guvnor/ │ └── m2repo/ │ └── client/ │ ├── M2RepoEditorPresenterTest.java │ ├── editor/ │ │ └── MavenRepositoryPagedJarTableTest.java │ ├── upload/ │ │ ├── UploadFormTest.java │ │ └── UploadFormViewImplTest.java │ └── widgets/ │ └── ArtifactListTest.java ├── uberfire-message-console/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-message-console-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── messageconsole/ │ │ │ │ ├── allowlist/ │ │ │ │ │ └── MessageConsoleAllowList.java │ │ │ │ ├── events/ │ │ │ │ │ ├── FilteredMessagesEvent.java │ │ │ │ │ ├── MessageUtils.java │ │ │ │ │ ├── PublishBaseEvent.java │ │ │ │ │ ├── PublishBatchMessagesEvent.java │ │ │ │ │ ├── PublishMessagesEvent.java │ │ │ │ │ ├── SystemMessage.java │ │ │ │ │ └── UnpublishMessagesEvent.java │ │ │ │ └── utils/ │ │ │ │ └── CSVConverter.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── messageconsole/ │ │ │ └── GuvnorMessageConsoleAPI.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── messageconsole/ │ │ └── utils/ │ │ └── CSVConverterTest.java │ ├── uberfire-message-console-backend/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── messageconsole/ │ │ │ └── backend/ │ │ │ ├── BuildResultsObserver.java │ │ │ └── DefaultIndexEngineObserver.java │ │ └── resources/ │ │ └── META-INF/ │ │ ├── ErraiApp.properties │ │ └── beans.xml │ └── uberfire-message-console-client/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── messageconsole/ │ │ │ └── client/ │ │ │ └── console/ │ │ │ ├── AlertsEntryPoint.java │ │ │ ├── HyperLinkCell.java │ │ │ ├── MessageConsoleScreen.java │ │ │ ├── MessageConsoleService.java │ │ │ ├── MessageConsoleServiceRow.java │ │ │ ├── MessageConsoleView.java │ │ │ ├── MessageConsoleViewImpl.java │ │ │ ├── MessageConsoleViewImpl.ui.xml │ │ │ ├── resources/ │ │ │ │ ├── MessageConsoleResources.java │ │ │ │ └── i18n/ │ │ │ │ ├── AlertsConstants.java │ │ │ │ └── MessageConsoleConstants.java │ │ │ └── widget/ │ │ │ ├── MessageTableWidget.java │ │ │ └── button/ │ │ │ ├── AlertsButtonMenuItemBuilder.java │ │ │ ├── ViewHideAlertsButtonPresenter.java │ │ │ ├── ViewHideAlertsButtonView.css │ │ │ ├── ViewHideAlertsButtonView.html │ │ │ └── ViewHideAlertsButtonView.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── guvnor/ │ │ └── messageconsole/ │ │ ├── GuvnorMessageConsoleClient.gwt.xml │ │ └── client/ │ │ └── console/ │ │ └── resources/ │ │ └── i18n/ │ │ ├── AlertsConstants.properties │ │ ├── AlertsConstants_es.properties │ │ ├── AlertsConstants_fr.properties │ │ ├── AlertsConstants_it.properties │ │ ├── AlertsConstants_ja.properties │ │ ├── MessageConsoleConstants.properties │ │ ├── MessageConsoleConstants_de.properties │ │ ├── MessageConsoleConstants_es.properties │ │ ├── MessageConsoleConstants_fr.properties │ │ ├── MessageConsoleConstants_it.properties │ │ ├── MessageConsoleConstants_ja.properties │ │ ├── MessageConsoleConstants_pt_BR.properties │ │ └── MessageConsoleConstants_zh_CN.properties │ └── test/ │ └── java/ │ └── org/ │ └── guvnor/ │ └── messageconsole/ │ └── client/ │ └── console/ │ ├── MessageConsoleServiceRowTest.java │ ├── MessageConsoleServiceTest.java │ └── widget/ │ └── button/ │ └── ViewHideAlertsButtonPresenterTest.java ├── uberfire-nio2-backport/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-nio2-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── java/ │ │ │ └── nio/ │ │ │ └── file/ │ │ │ ├── FileSystems.java │ │ │ ├── FileTreeWalker.java │ │ │ ├── Files.java │ │ │ ├── Paths.java │ │ │ ├── SimpleFileVisitor.java │ │ │ ├── api/ │ │ │ │ ├── FileSystemProviders.java │ │ │ │ └── FileSystemUtils.java │ │ │ └── extensions/ │ │ │ ├── FileSystemHookExecutionContext.java │ │ │ ├── FileSystemHooks.java │ │ │ └── FileSystemHooksConstants.java │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── java/ │ │ │ └── nio/ │ │ │ └── file/ │ │ │ ├── AbstractBaseTest.java │ │ │ ├── FileSystemProvidersTest.java │ │ │ ├── FileSystemsTest.java │ │ │ ├── FileTreeWalkerTest.java │ │ │ ├── FileUtilityMethodsTest.java │ │ │ ├── FilesTest.java │ │ │ ├── FilesUnsupportedOpsTest.java │ │ │ ├── PathsTest.java │ │ │ └── SimpleFileVisitorTest.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ └── logback.xml │ ├── uberfire-nio2-impls/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ ├── uberfire-nio2-fs/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── java/ │ │ │ │ └── nio/ │ │ │ │ └── fs/ │ │ │ │ └── file/ │ │ │ │ ├── BaseSimpleFileStore.java │ │ │ │ ├── BaseSimpleFileSystem.java │ │ │ │ ├── SimpleBasicFileAttributeView.java │ │ │ │ ├── SimpleFileSystemProvider.java │ │ │ │ ├── SimpleUnixFileStore.java │ │ │ │ ├── SimpleUnixFileSystem.java │ │ │ │ ├── SimpleWindowsFileStore.java │ │ │ │ └── SimpleWindowsFileSystem.java │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── java/ │ │ │ │ └── nio/ │ │ │ │ └── fs/ │ │ │ │ └── file/ │ │ │ │ ├── SimpleFileSystemProviderAttrsRelatedTest.java │ │ │ │ ├── SimpleFileSystemProviderTest.java │ │ │ │ ├── SimpleFileSystemProviderWindowsTest.java │ │ │ │ ├── SimpleUnixFileStoreTest.java │ │ │ │ ├── SimpleUnixFileSystemTest.java │ │ │ │ ├── SimpleWindowsFileStoreTest.java │ │ │ │ └── SimpleWindowsFileSystemTest.java │ │ │ └── resources/ │ │ │ └── Folder/ │ │ │ └── something.txt │ │ ├── uberfire-nio2-jgit/ │ │ │ ├── .gitignore │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── java/ │ │ │ │ └── nio/ │ │ │ │ └── fs/ │ │ │ │ └── jgit/ │ │ │ │ ├── CommitTime.java │ │ │ │ ├── FileSystemLock.java │ │ │ │ ├── FileSystemLockManager.java │ │ │ │ ├── JGitBasicAttributeView.java │ │ │ │ ├── JGitFSPath.java │ │ │ │ ├── JGitFileStore.java │ │ │ │ ├── JGitFileSystem.java │ │ │ │ ├── JGitFileSystemImpl.java │ │ │ │ ├── JGitFileSystemLock.java │ │ │ │ ├── JGitFileSystemProvider.java │ │ │ │ ├── JGitFileSystemProviderConfiguration.java │ │ │ │ ├── JGitFileSystemProxy.java │ │ │ │ ├── JGitHiddenAttributeView.java │ │ │ │ ├── JGitPathImpl.java │ │ │ │ ├── JGitSSHConfigSessionFactory.java │ │ │ │ ├── JGitVersionAttributeView.java │ │ │ │ ├── NotificationModel.java │ │ │ │ ├── daemon/ │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── PortUtil.java │ │ │ │ │ ├── filters/ │ │ │ │ │ │ └── HiddenBranchRefFilter.java │ │ │ │ │ ├── git/ │ │ │ │ │ │ ├── Daemon.java │ │ │ │ │ │ ├── DaemonClient.java │ │ │ │ │ │ ├── DaemonService.java │ │ │ │ │ │ └── KetchCustomReceivePack.java │ │ │ │ │ ├── http/ │ │ │ │ │ │ └── HTTPSupport.java │ │ │ │ │ └── ssh/ │ │ │ │ │ ├── BaseGitCommand.java │ │ │ │ │ ├── GitReceiveCommand.java │ │ │ │ │ ├── GitSSHService.java │ │ │ │ │ └── GitUploadCommand.java │ │ │ │ ├── exceptions/ │ │ │ │ │ └── FileSystemLockException.java │ │ │ │ ├── manager/ │ │ │ │ │ ├── JGitFileSystemsCache.java │ │ │ │ │ ├── JGitFileSystemsCacheDataStructure.java │ │ │ │ │ ├── JGitFileSystemsManager.java │ │ │ │ │ └── MemoizedFileSystemsSupplier.java │ │ │ │ ├── util/ │ │ │ │ │ ├── Git.java │ │ │ │ │ ├── GitHookSupport.java │ │ │ │ │ ├── GitImpl.java │ │ │ │ │ ├── ProxyAuthenticator.java │ │ │ │ │ ├── ThrowableSupplier.java │ │ │ │ │ ├── commands/ │ │ │ │ │ │ ├── AddRemote.java │ │ │ │ │ │ ├── BaseCreateCommitTree.java │ │ │ │ │ │ ├── BlobAsInputStream.java │ │ │ │ │ │ ├── BranchUtil.java │ │ │ │ │ │ ├── CherryPick.java │ │ │ │ │ │ ├── Clone.java │ │ │ │ │ │ ├── Commit.java │ │ │ │ │ │ ├── ConflictBranchesChecker.java │ │ │ │ │ │ ├── ConvertRefTree.java │ │ │ │ │ │ ├── CreateBranch.java │ │ │ │ │ │ ├── CreateCopyCommitTree.java │ │ │ │ │ │ ├── CreateDefaultCommitTree.java │ │ │ │ │ │ ├── CreateMoveCommitTree.java │ │ │ │ │ │ ├── CreateRepository.java │ │ │ │ │ │ ├── CreateRevertCommitTree.java │ │ │ │ │ │ ├── CustomDiffCommand.java │ │ │ │ │ │ ├── DeleteBranch.java │ │ │ │ │ │ ├── DiffBranches.java │ │ │ │ │ │ ├── Fetch.java │ │ │ │ │ │ ├── Fork.java │ │ │ │ │ │ ├── GarbageCollector.java │ │ │ │ │ │ ├── GetCommit.java │ │ │ │ │ │ ├── GetCommonAncestorCommit.java │ │ │ │ │ │ ├── GetFirstCommit.java │ │ │ │ │ │ ├── GetLastCommit.java │ │ │ │ │ │ ├── GetPathInfo.java │ │ │ │ │ │ ├── GetRef.java │ │ │ │ │ │ ├── GetTreeFromRef.java │ │ │ │ │ │ ├── ListCommits.java │ │ │ │ │ │ ├── ListDiffs.java │ │ │ │ │ │ ├── ListPathContent.java │ │ │ │ │ │ ├── ListRefs.java │ │ │ │ │ │ ├── MapDiffContent.java │ │ │ │ │ │ ├── Merge.java │ │ │ │ │ │ ├── PathUtil.java │ │ │ │ │ │ ├── Push.java │ │ │ │ │ │ ├── RefTreeUpdateCommand.java │ │ │ │ │ │ ├── RemoveRemote.java │ │ │ │ │ │ ├── ResolveObjectIds.java │ │ │ │ │ │ ├── ResolveRevCommit.java │ │ │ │ │ │ ├── RevertMerge.java │ │ │ │ │ │ ├── SimpleRefUpdateCommand.java │ │ │ │ │ │ ├── Squash.java │ │ │ │ │ │ ├── SubdirectoryClone.java │ │ │ │ │ │ ├── SyncRemote.java │ │ │ │ │ │ ├── TextualDiffBranches.java │ │ │ │ │ │ ├── UpdateRemoteConfig.java │ │ │ │ │ │ └── WriteConfiguration.java │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── ConcurrentRefUpdateException.java │ │ │ │ │ │ └── GitException.java │ │ │ │ │ ├── extensions/ │ │ │ │ │ │ └── JGitFSHooks.java │ │ │ │ │ └── model/ │ │ │ │ │ ├── CommitContent.java │ │ │ │ │ ├── CommitHistory.java │ │ │ │ │ ├── CommitInfo.java │ │ │ │ │ ├── CopyCommitContent.java │ │ │ │ │ ├── DefaultCommitContent.java │ │ │ │ │ ├── MergeCommitContent.java │ │ │ │ │ ├── MessageCommitInfo.java │ │ │ │ │ ├── MoveCommitContent.java │ │ │ │ │ ├── PathInfo.java │ │ │ │ │ ├── PathType.java │ │ │ │ │ └── RevertCommitContent.java │ │ │ │ └── ws/ │ │ │ │ ├── JGitFileSystemWatchServices.java │ │ │ │ ├── JGitFileSystemsEventsManager.java │ │ │ │ ├── JGitWatchEvent.java │ │ │ │ ├── JGitWatchService.java │ │ │ │ └── cluster/ │ │ │ │ ├── JGitEventsBroadcast.java │ │ │ │ └── WatchEventsWrapper.java │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── java/ │ │ │ │ └── nio/ │ │ │ │ └── fs/ │ │ │ │ └── jgit/ │ │ │ │ ├── AbstractTestInfra.java │ │ │ │ ├── JGitAddRemoteTest.java │ │ │ │ ├── JGitCacheInvalidationTest.java │ │ │ │ ├── JGitCloneTest.java │ │ │ │ ├── JGitConflictBranchesCheckerTest.java │ │ │ │ ├── JGitDiffBranchesTest.java │ │ │ │ ├── JGitFileSystemImplProviderAsDefaultTest.java │ │ │ │ ├── JGitFileSystemImplProviderBytemanTest.java │ │ │ │ ├── JGitFileSystemImplProviderCpMvTest.java │ │ │ │ ├── JGitFileSystemImplProviderDiffTest.java │ │ │ │ ├── JGitFileSystemImplProviderEncodingTest.java │ │ │ │ ├── JGitFileSystemImplProviderGCTest.java │ │ │ │ ├── JGitFileSystemImplProviderHookTest.java │ │ │ │ ├── JGitFileSystemImplProviderHttpProxyTest.java │ │ │ │ ├── JGitFileSystemImplProviderMergeTest.java │ │ │ │ ├── JGitFileSystemImplProviderMigrationTest.java │ │ │ │ ├── JGitFileSystemImplProviderPostCommitHookTest.java │ │ │ │ ├── JGitFileSystemImplProviderSSHBadConfigTest.java │ │ │ │ ├── JGitFileSystemImplProviderSSHTest.java │ │ │ │ ├── JGitFileSystemImplProviderTest.java │ │ │ │ ├── JGitFileSystemImplProviderUnsupportedOpTest.java │ │ │ │ ├── JGitFileSystemImplProviderWithFoldersTest.java │ │ │ │ ├── JGitFileSystemImplTest.java │ │ │ │ ├── JGitFileSystemLockTest.java │ │ │ │ ├── JGitFileSystemProviderConcurrentOperationsTest.java │ │ │ │ ├── JGitFileSystemProxyTest.java │ │ │ │ ├── JGitForkTest.java │ │ │ │ ├── JGitGetCommitTest.java │ │ │ │ ├── JGitGetCommonAncestorCommitTest.java │ │ │ │ ├── JGitHistoryTest.java │ │ │ │ ├── JGitMapDiffContentTest.java │ │ │ │ ├── JGitMergeTest.java │ │ │ │ ├── JGitMirrorTest.java │ │ │ │ ├── JGitPathTest.java │ │ │ │ ├── JGitRevertMergeTest.java │ │ │ │ ├── JGitSSHConfigSessionFactoryTest.java │ │ │ │ ├── JGitSquashingTest.java │ │ │ │ ├── JGitSubdirectoryCloneTest.java │ │ │ │ ├── JGitTextualDiffBranchesTest.java │ │ │ │ ├── JGitUpdateFSCacheWithHostnameTest.java │ │ │ │ ├── JGitUtilTest.java │ │ │ │ ├── NewProviderDefineDirTest.java │ │ │ │ ├── URITest.java │ │ │ │ ├── UsernamePasswordCredentialsProvider.java │ │ │ │ ├── daemon/ │ │ │ │ │ ├── common/ │ │ │ │ │ │ └── PortUtilTest.java │ │ │ │ │ ├── filters/ │ │ │ │ │ │ └── HiddenBranchRefFilterTest.java │ │ │ │ │ ├── git/ │ │ │ │ │ │ └── DaemonTest.java │ │ │ │ │ ├── http/ │ │ │ │ │ │ ├── HTTPSOnlySupportTest.java │ │ │ │ │ │ ├── HTTPSupportDisableTest.java │ │ │ │ │ │ └── HTTPSupportTest.java │ │ │ │ │ └── ssh/ │ │ │ │ │ └── GitSSHServiceTest.java │ │ │ │ ├── manager/ │ │ │ │ │ ├── JGitFileSystemsCacheTest.java │ │ │ │ │ ├── JGitFileSystemsManagerTest.java │ │ │ │ │ └── MemoizedFileSystemsSupplierTest.java │ │ │ │ ├── util/ │ │ │ │ │ ├── ConcurrentJGitUtilTest.java │ │ │ │ │ ├── commands/ │ │ │ │ │ │ └── SyncRemoteTest.java │ │ │ │ │ └── extensions/ │ │ │ │ │ └── JGitFSHooksTest.java │ │ │ │ └── ws/ │ │ │ │ └── JGitFileSystemsEventsManagerTest.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── services/ │ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ │ ├── byteman/ │ │ │ │ ├── commit_exception.btm │ │ │ │ ├── retry/ │ │ │ │ │ ├── check_path.btm │ │ │ │ │ ├── get_commits.btm │ │ │ │ │ ├── get_last_commit.btm │ │ │ │ │ ├── list_path_content.btm │ │ │ │ │ ├── resolve_inputstream.btm │ │ │ │ │ └── resolve_path.btm │ │ │ │ ├── squash.btm │ │ │ │ ├── squash_exception.btm │ │ │ │ └── squash_lock.btm │ │ │ └── simplelogger.properties │ │ └── uberfire-nio2-k8s/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── java/ │ │ │ └── nio/ │ │ │ └── fs/ │ │ │ ├── cloud/ │ │ │ │ ├── CloudClientConstants.java │ │ │ │ └── CloudClientFactory.java │ │ │ └── k8s/ │ │ │ ├── K8SBasicFileAttributeView.java │ │ │ ├── K8SFileChannel.java │ │ │ ├── K8SFileStore.java │ │ │ ├── K8SFileSystem.java │ │ │ ├── K8SFileSystemConstants.java │ │ │ ├── K8SFileSystemObjectType.java │ │ │ ├── K8SFileSystemProvider.java │ │ │ ├── K8SFileSystemUtils.java │ │ │ ├── K8SWatchKey.java │ │ │ ├── K8SWatchService.java │ │ │ └── SeekableInMemoryByteChannel.java │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── java/ │ │ │ └── nio/ │ │ │ └── fs/ │ │ │ ├── cloud/ │ │ │ │ └── CloudClientFactoryTest.java │ │ │ └── k8s/ │ │ │ ├── FileSystemProvidersTest.java │ │ │ ├── K8SFileChannelTest.java │ │ │ ├── K8SFileSystemInitTest.java │ │ │ ├── K8SFileSystemTest.java │ │ │ ├── K8SWatchServiceTest.java │ │ │ ├── SeekableInMemoryByteChannelTestCase.java │ │ │ └── integrationtests/ │ │ │ └── K8SFileSystemProviderIntegrationTest.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ ├── logback-test.xml │ │ ├── test-k8sfs-dir-0-configmap.yml │ │ ├── test-k8sfs-dir-00-configmap.yml │ │ ├── test-k8sfs-dir-r-configmap.yml │ │ ├── test-k8sfs-dir-r-empty-configmap.yml │ │ ├── test-k8sfs-file-configmap.yml │ │ ├── test-k8sfs-file-dup-configmap.yml │ │ └── test-k8sfs-file-invalid-configmap.yml │ └── uberfire-nio2-model/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ ├── apache/ │ │ │ │ └── commons/ │ │ │ │ └── io/ │ │ │ │ ├── FilenameUtils.java │ │ │ │ └── IOCase.java │ │ │ └── java/ │ │ │ └── nio/ │ │ │ ├── Closeable.java │ │ │ ├── EncodingUtil.java │ │ │ ├── IOException.java │ │ │ ├── base/ │ │ │ │ ├── AbstractBasicFileAttributeView.java │ │ │ │ ├── AbstractPath.java │ │ │ │ ├── AttrHolder.java │ │ │ │ ├── AttrsStorage.java │ │ │ │ ├── AttrsStorageImpl.java │ │ │ │ ├── BasicFileAttributesImpl.java │ │ │ │ ├── BasicFileAttributesUtil.java │ │ │ │ ├── ExtendedAttributeView.java │ │ │ │ ├── FSPath.java │ │ │ │ ├── FileDiff.java │ │ │ │ ├── FileSystemId.java │ │ │ │ ├── FileSystemState.java │ │ │ │ ├── FileSystemStateAware.java │ │ │ │ ├── FileTimeImpl.java │ │ │ │ ├── GeneralPathImpl.java │ │ │ │ ├── LazyAttrLoader.java │ │ │ │ ├── NeedsPreloadedAttrs.java │ │ │ │ ├── NotImplementedException.java │ │ │ │ ├── Properties.java │ │ │ │ ├── SeekableByteChannelFileBasedImpl.java │ │ │ │ ├── SeekableByteChannelWrapperImpl.java │ │ │ │ ├── SegmentedPath.java │ │ │ │ ├── TextualDiff.java │ │ │ │ ├── WatchContext.java │ │ │ │ ├── attributes/ │ │ │ │ │ ├── HiddenAttributeView.java │ │ │ │ │ ├── HiddenAttributes.java │ │ │ │ │ └── HiddenAttributesImpl.java │ │ │ │ ├── dotfiles/ │ │ │ │ │ ├── DotFileOption.java │ │ │ │ │ └── DotFileUtils.java │ │ │ │ ├── options/ │ │ │ │ │ ├── CherryPickCopyOption.java │ │ │ │ │ ├── CommentedOption.java │ │ │ │ │ ├── MergeCopyOption.java │ │ │ │ │ └── SquashOption.java │ │ │ │ └── version/ │ │ │ │ ├── VersionAttributeView.java │ │ │ │ ├── VersionAttributes.java │ │ │ │ ├── VersionHistory.java │ │ │ │ └── VersionRecord.java │ │ │ ├── channels/ │ │ │ │ ├── AsynchronousChannel.java │ │ │ │ ├── AsynchronousFileChannel.java │ │ │ │ ├── CompletionHandler.java │ │ │ │ └── SeekableByteChannel.java │ │ │ ├── file/ │ │ │ │ ├── AccessDeniedException.java │ │ │ │ ├── AccessMode.java │ │ │ │ ├── AmbiguousFileSystemNameException.java │ │ │ │ ├── AtomicMoveNotSupportedException.java │ │ │ │ ├── ClosedWatchServiceException.java │ │ │ │ ├── CopyOption.java │ │ │ │ ├── DeleteOption.java │ │ │ │ ├── DirectoryNotEmptyException.java │ │ │ │ ├── DirectoryStream.java │ │ │ │ ├── FileAlreadyExistsException.java │ │ │ │ ├── FileStore.java │ │ │ │ ├── FileSystem.java │ │ │ │ ├── FileSystemAlreadyExistsException.java │ │ │ │ ├── FileSystemException.java │ │ │ │ ├── FileSystemMetadata.java │ │ │ │ ├── FileSystemNotFoundException.java │ │ │ │ ├── FileVisitOption.java │ │ │ │ ├── FileVisitResult.java │ │ │ │ ├── FileVisitor.java │ │ │ │ ├── InterruptedException.java │ │ │ │ ├── InvalidPathException.java │ │ │ │ ├── LinkOption.java │ │ │ │ ├── LockableFileSystem.java │ │ │ │ ├── NoSuchFileException.java │ │ │ │ ├── NotDirectoryException.java │ │ │ │ ├── NotLinkException.java │ │ │ │ ├── OpenOption.java │ │ │ │ ├── Option.java │ │ │ │ ├── Path.java │ │ │ │ ├── PathMatcher.java │ │ │ │ ├── PatternSyntaxException.java │ │ │ │ ├── ProviderNotFoundException.java │ │ │ │ ├── StandardCopyOption.java │ │ │ │ ├── StandardDeleteOption.java │ │ │ │ ├── StandardOpenOption.java │ │ │ │ ├── StandardWatchEventKind.java │ │ │ │ ├── WatchEvent.java │ │ │ │ ├── WatchKey.java │ │ │ │ ├── WatchService.java │ │ │ │ ├── Watchable.java │ │ │ │ ├── attribute/ │ │ │ │ │ ├── AttributeView.java │ │ │ │ │ ├── BasicFileAttributeView.java │ │ │ │ │ ├── BasicFileAttributes.java │ │ │ │ │ ├── FileAttribute.java │ │ │ │ │ ├── FileAttributeView.java │ │ │ │ │ ├── FileStoreAttributeView.java │ │ │ │ │ ├── FileTime.java │ │ │ │ │ ├── PosixFilePermission.java │ │ │ │ │ ├── UserPrincipal.java │ │ │ │ │ └── UserPrincipalLookupService.java │ │ │ │ └── spi/ │ │ │ │ └── FileSystemProvider.java │ │ │ └── security/ │ │ │ ├── FileSystemAuthorizer.java │ │ │ ├── SSHAuthenticator.java │ │ │ └── SecuredFileSystemProvider.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── ErraiApp.properties │ │ └── org/ │ │ └── uberfire/ │ │ └── java/ │ │ └── nio/ │ │ └── UberfireNIO2Model.gwt.xml │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── java/ │ └── nio/ │ └── base/ │ ├── GeneralPathEqualsTest.java │ ├── GeneralPathTest.java │ ├── GeneralPathUnsupportedOpsTest.java │ ├── GeneralPathValidationTest.java │ ├── PropertiesTest.java │ ├── SeekableByteChannelTest.java │ └── dotfiles/ │ └── DotFileUtilsTest.java ├── uberfire-packaging/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-all/ │ │ ├── .gitignore │ │ └── pom.xml │ ├── uberfire-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── ErraiApp.properties │ │ └── org/ │ │ └── uberfire/ │ │ └── UberfireClient.gwt.xml │ ├── uberfire-client-all/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── ErraiApp.properties │ │ └── org/ │ │ └── uberfire/ │ │ └── UberfireClientAll.gwt.xml │ ├── uberfire-client-backend/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── ErraiApp.properties │ │ └── org/ │ │ └── uberfire/ │ │ └── UberfireClientBackend.gwt.xml │ └── uberfire-server-all/ │ ├── .gitignore │ └── pom.xml ├── uberfire-preferences/ │ ├── pom.xml │ ├── uberfire-preferences-api/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── preferences/ │ │ │ │ └── shared/ │ │ │ │ ├── PreferenceScope.java │ │ │ │ ├── PreferenceScopeFactory.java │ │ │ │ ├── PreferenceScopeResolutionStrategy.java │ │ │ │ ├── PreferenceScopeResolver.java │ │ │ │ ├── PreferenceScopeTypes.java │ │ │ │ ├── PreferenceScopeValidator.java │ │ │ │ ├── PreferenceStorage.java │ │ │ │ ├── PreferenceStore.java │ │ │ │ ├── PropertyFormOptions.java │ │ │ │ ├── PropertyFormType.java │ │ │ │ ├── PropertyValidator.java │ │ │ │ ├── UsernameProvider.java │ │ │ │ ├── annotations/ │ │ │ │ │ ├── PortablePreference.java │ │ │ │ │ ├── Property.java │ │ │ │ │ ├── RootPreference.java │ │ │ │ │ └── WorkbenchPreference.java │ │ │ │ ├── bean/ │ │ │ │ │ ├── BasePreference.java │ │ │ │ │ ├── BasePreferenceBean.java │ │ │ │ │ ├── BasePreferencePortable.java │ │ │ │ │ ├── Preference.java │ │ │ │ │ ├── PreferenceBeanServerStore.java │ │ │ │ │ ├── PreferenceBeanStore.java │ │ │ │ │ ├── PreferenceHierarchyElement.java │ │ │ │ │ ├── PreferenceRootElement.java │ │ │ │ │ └── mock/ │ │ │ │ │ ├── PortablePreferenceMock.java │ │ │ │ │ ├── PortablePreferenceMockBeanGeneratedImpl.java │ │ │ │ │ └── PortablePreferenceMockPortableGeneratedImpl.java │ │ │ │ ├── event/ │ │ │ │ │ └── PreferenceUpdatedEvent.java │ │ │ │ └── impl/ │ │ │ │ ├── DefaultPreferenceScopeResolutionStrategy.java │ │ │ │ ├── DefaultPreferenceScopeResolver.java │ │ │ │ ├── DefaultPreferenceScopeTypes.java │ │ │ │ ├── DefaultScopes.java │ │ │ │ ├── PreferenceScopeFactoryImpl.java │ │ │ │ ├── PreferenceScopeImpl.java │ │ │ │ ├── PreferenceScopeResolutionStrategyInfo.java │ │ │ │ ├── PreferenceScopeTypesProducer.java │ │ │ │ ├── PreferenceScopeValidatorImpl.java │ │ │ │ ├── PreferenceScopedValue.java │ │ │ │ ├── exception/ │ │ │ │ │ └── InvalidPreferenceScopeException.java │ │ │ │ └── validation/ │ │ │ │ ├── ConstrainedValuesValidator.java │ │ │ │ ├── EnumValuePropertyValidator.java │ │ │ │ ├── NotEmptyValidator.java │ │ │ │ ├── NumberPropertyValidator.java │ │ │ │ ├── StringPropertyValidator.java │ │ │ │ └── ValidationResult.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── preferences/ │ │ │ └── UberfirePreferencesAPI.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── preferences/ │ │ └── shared/ │ │ ├── PropertyFormTypeTest.java │ │ └── impl/ │ │ ├── DefaultPreferenceScopeResolutionStrategyTest.java │ │ ├── DefaultPreferenceScopeResolverTest.java │ │ ├── DefaultPreferenceScopeTypesTest.java │ │ ├── DefaultPreferenceScopesForTests.java │ │ ├── PreferenceScopeFactoryImplTest.java │ │ ├── PreferenceScopeValidatorImplTest.java │ │ ├── UsernameProviderMock.java │ │ └── validation/ │ │ ├── ConstrainedValuesValidatorTest.java │ │ ├── EnumValuePropertyValidatorTest.java │ │ ├── NotEmptyValidatorTest.java │ │ └── NumberPropertyValidatorTest.java │ ├── uberfire-preferences-backend/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── preferences/ │ │ │ │ └── backend/ │ │ │ │ ├── PreferenceBeanStoreImpl.java │ │ │ │ ├── PreferenceScopeResolutionStrategyProducer.java │ │ │ │ ├── PreferenceStorageImpl.java │ │ │ │ ├── PreferenceStoreImpl.java │ │ │ │ ├── ServerUsernameProvider.java │ │ │ │ └── annotations/ │ │ │ │ └── ComponentKey.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── beans.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── preferences/ │ │ │ └── backend/ │ │ │ ├── CustomObject.java │ │ │ ├── InvalidDefaultPreference.java │ │ │ ├── MyInnerPreference.java │ │ │ ├── MyInnerPreference2.java │ │ │ ├── MyPreference.java │ │ │ ├── MySharedPreference.java │ │ │ ├── MySharedPreference2.java │ │ │ ├── PreferenceBeanStoreImplTest.java │ │ │ ├── PreferenceStorageImplTest.java │ │ │ ├── PreferenceStoreImplTest.java │ │ │ └── ServerUsernameProviderTest.java │ │ └── resources/ │ │ └── META-INF/ │ │ ├── ErraiApp.properties │ │ └── services/ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ ├── uberfire-preferences-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── preferences/ │ │ │ │ └── client/ │ │ │ │ ├── annotations/ │ │ │ │ │ └── ComponentKey.java │ │ │ │ ├── scope/ │ │ │ │ │ ├── ClientUsernameProvider.java │ │ │ │ │ └── PreferenceScopeResolutionStrategyIOCProvider.java │ │ │ │ ├── store/ │ │ │ │ │ ├── PreferenceBeanStoreClientImpl.java │ │ │ │ │ ├── PreferenceStore.java │ │ │ │ │ └── PreferenceStoreIOCProvider.java │ │ │ │ └── utils/ │ │ │ │ └── PreferenceQualifierUtils.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── preferences/ │ │ │ └── UberfirePreferencesClient.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ ├── ext/ │ │ │ └── preferences/ │ │ │ └── client/ │ │ │ └── scope/ │ │ │ └── ClientUsernameProviderTest.java │ │ └── preferences/ │ │ └── client/ │ │ └── store/ │ │ └── PreferenceBeanStoreClientImplTest.java │ ├── uberfire-preferences-client-backend/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── preferences/ │ │ │ │ └── client/ │ │ │ │ └── store/ │ │ │ │ └── PreferenceBeanStoreImpl.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── preferences/ │ │ │ └── UberfirePreferencesClientBackend.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── preferences/ │ │ └── client/ │ │ ├── scope/ │ │ │ └── ClientUsernameProviderTest.java │ │ └── store/ │ │ └── PreferenceBeanStoreImplTest.java │ └── uberfire-preferences-processors/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ext/ │ │ │ └── preferences/ │ │ │ └── processors/ │ │ │ ├── GeneratorContext.java │ │ │ ├── PropertyData.java │ │ │ ├── WorkbenchPreferenceGeneratedImplGenerator.java │ │ │ └── WorkbenchPreferenceProcessor.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── javax.annotation.processing.Processor │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── preferences/ │ │ └── processors/ │ │ └── templates/ │ │ ├── workbenchPreferenceBean.ftl │ │ └── workbenchPreferencePortable.ftl │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── ext/ │ │ └── preferences/ │ │ └── processors/ │ │ ├── AbstractProcessorTest.java │ │ ├── MyInnerPreference.java │ │ ├── MyInnerPreference2.java │ │ ├── MySharedPreference.java │ │ ├── MySharedPreference2.java │ │ └── WorkbenchPreferenceProcessorTest.java │ └── resources/ │ └── org/ │ └── uberfire/ │ └── ext/ │ └── preferences/ │ └── processors/ │ ├── MyPreference.java │ └── expected/ │ ├── MyPreferenceBeanGeneratedImpl.expected │ └── MyPreferencePortableGeneratedImpl.expected ├── uberfire-project/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-project-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── common/ │ │ │ │ └── services/ │ │ │ │ └── project/ │ │ │ │ ├── builder/ │ │ │ │ │ ├── events/ │ │ │ │ │ │ ├── InvalidateDMOModuleCacheEvent.java │ │ │ │ │ │ └── InvalidateDMOPackageCacheEvent.java │ │ │ │ │ ├── model/ │ │ │ │ │ │ ├── BuildMessage.java │ │ │ │ │ │ ├── BuildResults.java │ │ │ │ │ │ └── IncrementalBuildResults.java │ │ │ │ │ └── service/ │ │ │ │ │ ├── BuildService.java │ │ │ │ │ ├── BuildValidationHelper.java │ │ │ │ │ └── PostBuildHandler.java │ │ │ │ ├── categories/ │ │ │ │ │ ├── Decision.java │ │ │ │ │ ├── Form.java │ │ │ │ │ ├── Model.java │ │ │ │ │ ├── Optimization.java │ │ │ │ │ └── Process.java │ │ │ │ ├── context/ │ │ │ │ │ ├── ProjectContextChangeHandle.java │ │ │ │ │ ├── WorkspaceProjectContextChangeEvent.java │ │ │ │ │ └── WorkspaceProjectContextChangeHandler.java │ │ │ │ ├── editor/ │ │ │ │ │ └── type/ │ │ │ │ │ └── POMResourceTypeDefinition.java │ │ │ │ ├── events/ │ │ │ │ │ ├── DeleteModuleEvent.java │ │ │ │ │ ├── ModuleUpdatedEvent.java │ │ │ │ │ ├── NewModuleEvent.java │ │ │ │ │ ├── NewPackageEvent.java │ │ │ │ │ ├── NewProjectEvent.java │ │ │ │ │ └── RepositoryContributorsUpdatedEvent.java │ │ │ │ ├── model/ │ │ │ │ │ ├── Build.java │ │ │ │ │ ├── Dependencies.java │ │ │ │ │ ├── Dependency.java │ │ │ │ │ ├── GAV.java │ │ │ │ │ ├── HasListFormComboPanelProperties.java │ │ │ │ │ ├── MavenRepository.java │ │ │ │ │ ├── MavenRepositoryMetadata.java │ │ │ │ │ ├── MavenRepositorySource.java │ │ │ │ │ ├── Module.java │ │ │ │ │ ├── ModuleRepositories.java │ │ │ │ │ ├── POM.java │ │ │ │ │ ├── Package.java │ │ │ │ │ ├── Plugin.java │ │ │ │ │ ├── ProjectImports.java │ │ │ │ │ ├── WorkItemHandlerModel.java │ │ │ │ │ ├── WorkspaceProject.java │ │ │ │ │ └── WorkspaceProjectWizard.java │ │ │ │ ├── preferences/ │ │ │ │ │ ├── GAVPreferences.java │ │ │ │ │ └── GeneralPreferences.java │ │ │ │ ├── project/ │ │ │ │ │ ├── ModuleFactory.java │ │ │ │ │ └── WorkspaceProjectMigrationService.java │ │ │ │ ├── security/ │ │ │ │ │ ├── ProjectPermissionsService.java │ │ │ │ │ └── ProjectResourceType.java │ │ │ │ ├── service/ │ │ │ │ │ ├── BaseArchetypeService.java │ │ │ │ │ ├── DeploymentMode.java │ │ │ │ │ ├── GAVAlreadyExistsException.java │ │ │ │ │ ├── ModuleRepositoriesService.java │ │ │ │ │ ├── ModuleRepositoryResolver.java │ │ │ │ │ ├── ModuleResourceResolver.java │ │ │ │ │ ├── ModuleService.java │ │ │ │ │ ├── ModuleServiceCore.java │ │ │ │ │ ├── POMService.java │ │ │ │ │ ├── PackageAlreadyExistsException.java │ │ │ │ │ ├── WorkspaceProjectSearchService.java │ │ │ │ │ └── WorkspaceProjectService.java │ │ │ │ └── utils/ │ │ │ │ ├── ModuleResourcePaths.java │ │ │ │ └── NewWorkspaceProjectUtils.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── common/ │ │ │ └── services/ │ │ │ └── project/ │ │ │ └── GuvnorProjectAPI.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── common/ │ │ └── services/ │ │ └── project/ │ │ ├── model/ │ │ │ ├── DependenciesTest.java │ │ │ ├── GAVTest.java │ │ │ ├── ModuleTest.java │ │ │ ├── POMTest.java │ │ │ └── WorkspaceProjectTest.java │ │ ├── preferences/ │ │ │ └── GAVPreferencesTest.java │ │ └── utils/ │ │ └── NewWorkspaceProjectUtilsTest.java │ ├── uberfire-project-backend/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── common/ │ │ │ │ └── services/ │ │ │ │ └── project/ │ │ │ │ └── backend/ │ │ │ │ ├── security/ │ │ │ │ │ └── ProjectPermissionsServiceImpl.java │ │ │ │ └── server/ │ │ │ │ ├── AbstractDeleteModuleObserverBridge.java │ │ │ │ ├── AbstractModuleRepositoriesServiceImpl.java │ │ │ │ ├── AbstractModuleService.java │ │ │ │ ├── BaseArchetypeServiceImpl.java │ │ │ │ ├── DefaultModuleResourcePathResolver.java │ │ │ │ ├── DefaultPomEnhancer.java │ │ │ │ ├── MavenLocalRepositoryManagerWrapper.java │ │ │ │ ├── MavenLocalRepositoryUtils.java │ │ │ │ ├── MavenRepositorySystemSessionWrapper.java │ │ │ │ ├── ModuleFinder.java │ │ │ │ ├── ModuleRepositoriesContentHandler.java │ │ │ │ ├── ModuleRepositoryResolverImpl.java │ │ │ │ ├── ModuleResourcePathResolver.java │ │ │ │ ├── POMServiceImpl.java │ │ │ │ ├── PomEnhancer.java │ │ │ │ ├── PomEnhancerProvider.java │ │ │ │ ├── ProjectConfigurationContentHandler.java │ │ │ │ ├── ResourceResolver.java │ │ │ │ ├── WorkspaceProjectMigrationServiceImpl.java │ │ │ │ ├── WorkspaceProjectSearchServiceImpl.java │ │ │ │ ├── WorkspaceProjectServiceImpl.java │ │ │ │ └── utils/ │ │ │ │ ├── BaseArchetypeServiceProducer.java │ │ │ │ ├── BuildContentHandler.java │ │ │ │ ├── DependencyContentHandler.java │ │ │ │ ├── DependencyUpdater.java │ │ │ │ ├── IdentifierUtils.java │ │ │ │ ├── MavenPluginUpdater.java │ │ │ │ ├── NullSafeEquals.java │ │ │ │ ├── POMContentHandler.java │ │ │ │ ├── PathUtil.java │ │ │ │ └── configuration/ │ │ │ │ ├── ConfigurationKey.java │ │ │ │ ├── ConfigurationStrategy.java │ │ │ │ ├── Order.java │ │ │ │ └── Valid.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── common/ │ │ │ └── services/ │ │ │ └── project/ │ │ │ └── backend/ │ │ │ └── server/ │ │ │ ├── AbstractDeleteModuleObserverBridgeTest.java │ │ │ ├── AbstractModuleRepositoriesServiceImplTest.java │ │ │ ├── AbstractModuleServiceTest.java │ │ │ ├── AbstractResourceResolverTest.java │ │ │ ├── DefaultModuleResourcePathResolverTest.java │ │ │ ├── MockModule.java │ │ │ ├── ModuleConfigurationContentHandlerTest.java │ │ │ ├── ModuleFinderTest.java │ │ │ ├── ModuleMavenRepositoryResolverImplTest.java │ │ │ ├── ModuleRepositoriesContentHandlerTest.java │ │ │ ├── ModuleServiceMock.java │ │ │ ├── POMServiceImplCreateTest.java │ │ │ ├── POMServiceImplLoadTest.java │ │ │ ├── POMServiceImplSaveTest.java │ │ │ ├── POMServiceImplSaveWithSubModulesTest.java │ │ │ ├── RepositoryResolverTestUtils.java │ │ │ ├── ResourceResolverResolvePackagesTest.java │ │ │ ├── TestAppSetup.java │ │ │ ├── TestProjectService.java │ │ │ ├── WorkspaceProjectMigrationServiceImplTest.java │ │ │ ├── WorkspaceProjectServiceImplNewWorkspaceWorkspaceProjectTest.java │ │ │ ├── WorkspaceProjectServiceImplResolveWorkspaceWorkspaceProjectTest.java │ │ │ ├── WorkspaceProjectServiceImplTest.java │ │ │ ├── WorkspaceWorkspaceProjectSearchServiceTest.java │ │ │ └── utils/ │ │ │ ├── BuildContentHandlerTest.java │ │ │ ├── DependencyUpdaterTest.java │ │ │ ├── MavenPluginUpdaterTest.java │ │ │ ├── POMContentHandlerOneToOneTest.java │ │ │ ├── POMContentHandlerTest.java │ │ │ ├── PathUtilTest.java │ │ │ └── TestUtils.java │ │ └── resources/ │ │ ├── LegacyRepositoryStructure/ │ │ │ ├── Project1/ │ │ │ │ └── pom.xml │ │ │ └── Project2/ │ │ │ └── pom.xml │ │ ├── META-INF/ │ │ │ ├── beans.xml │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ ├── TestProject/ │ │ │ └── pom.xml │ │ ├── logback-test.xml │ │ └── org/ │ │ └── guvnor/ │ │ └── common/ │ │ └── services/ │ │ └── project/ │ │ └── backend/ │ │ └── server/ │ │ └── utils/ │ │ ├── pom1.xml │ │ ├── pom2.xml │ │ └── pom3.xml │ ├── uberfire-project-builder/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── common/ │ │ │ │ └── services/ │ │ │ │ └── builder/ │ │ │ │ ├── AsyncIncrementalBuilder.java │ │ │ │ ├── IncrementalBuilderExecutorManager.java │ │ │ │ ├── IncrementalBuilderExecutorManagerFactory.java │ │ │ │ ├── IncrementalBuilderExecutorManagerFactoryImpl.java │ │ │ │ ├── ObservableClassFile.java │ │ │ │ ├── ObservableJavaFile.java │ │ │ │ ├── ObservablePOMFile.java │ │ │ │ ├── ResourceChangeIncrementalBuilder.java │ │ │ │ ├── ResourceChangeObservableFile.java │ │ │ │ └── ResourceChangeObserver.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── beans.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── common/ │ │ └── services/ │ │ └── builder/ │ │ ├── IncrementalBuilderExecutorManagerFactoryImplTest.java │ │ ├── ObservableClassFileTest.java │ │ ├── ObservableJavaFileTest.java │ │ └── ObservablePOMFileTest.java │ └── uberfire-project-client/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── common/ │ │ │ └── services/ │ │ │ └── project/ │ │ │ └── client/ │ │ │ ├── ArtifactIdChangeHandler.java │ │ │ ├── GAVEditor.java │ │ │ ├── GAVEditorView.java │ │ │ ├── GAVEditorViewImpl.java │ │ │ ├── GAVEditorViewImpl.ui.xml │ │ │ ├── GroupIdChangeHandler.java │ │ │ ├── NameChangeHandler.java │ │ │ ├── POMEditorPanel.java │ │ │ ├── POMEditorPanelView.java │ │ │ ├── POMEditorPanelViewImpl.java │ │ │ ├── POMEditorPanelViewImpl.ui.xml │ │ │ ├── ProjectEntryPoint.java │ │ │ ├── VersionChangeHandler.java │ │ │ ├── context/ │ │ │ │ └── WorkspaceProjectContext.java │ │ │ ├── preferences/ │ │ │ │ ├── ProjectScopedResolutionStrategySupplier.java │ │ │ │ └── SpaceScopedResolutionStrategySupplier.java │ │ │ ├── repositories/ │ │ │ │ ├── ConflictingRepositoriesPopup.java │ │ │ │ ├── ConflictingRepositoriesPopupView.java │ │ │ │ ├── ConflictingRepositoriesPopupViewImpl.java │ │ │ │ └── ConflictingRepositoriesPopupViewImpl.ui.xml │ │ │ ├── resources/ │ │ │ │ ├── ProjectResources.java │ │ │ │ └── i18n/ │ │ │ │ └── ProjectConstants.java │ │ │ ├── security/ │ │ │ │ └── ProjectController.java │ │ │ ├── type/ │ │ │ │ └── POMResourceType.java │ │ │ └── util/ │ │ │ └── POMDefaultOptions.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── guvnor/ │ │ └── common/ │ │ └── services/ │ │ └── project/ │ │ ├── GuvnorProjectClient.gwt.xml │ │ └── client/ │ │ ├── preferences/ │ │ │ └── resources/ │ │ │ └── i18n/ │ │ │ ├── ProjectPreferencesConstants.properties │ │ │ ├── ProjectPreferencesConstants_es.properties │ │ │ ├── ProjectPreferencesConstants_fr.properties │ │ │ ├── ProjectPreferencesConstants_it.properties │ │ │ └── ProjectPreferencesConstants_ja.properties │ │ └── resources/ │ │ └── i18n/ │ │ ├── ProjectConstants.properties │ │ ├── ProjectConstants_de.properties │ │ ├── ProjectConstants_es.properties │ │ ├── ProjectConstants_fr.properties │ │ ├── ProjectConstants_it.properties │ │ ├── ProjectConstants_ja.properties │ │ ├── ProjectConstants_pt_BR.properties │ │ └── ProjectConstants_zh_CN.properties │ └── test/ │ └── java/ │ └── org/ │ └── guvnor/ │ └── common/ │ └── services/ │ └── project/ │ └── client/ │ ├── GAVEditorTest.java │ ├── GAVEditorViewImplTest.java │ ├── POMEditorPanelTest.java │ ├── POMEditorPanelViewImplTest.java │ ├── context/ │ │ └── WorkspaceProjectContextTest.java │ ├── preferences/ │ │ ├── ModuleScopedResolutionStrategySupplierTest.java │ │ └── SpaceScopedResolutionStrategySupplierTest.java │ ├── repositories/ │ │ └── ConflictingRepositoriesPopupTest.java │ └── security/ │ └── ProjectControllerTest.java ├── uberfire-rest/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-rest-backend/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── build/ │ │ │ └── revapi-config.json │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── rest/ │ │ │ │ └── backend/ │ │ │ │ ├── JobRequestHelper.java │ │ │ │ ├── JobRequestScheduler.java │ │ │ │ ├── JobResultManager.java │ │ │ │ ├── PermissionAction.java │ │ │ │ ├── PermissionConstants.java │ │ │ │ ├── ProjectResource.java │ │ │ │ ├── ResourceTypePermissionValidator.java │ │ │ │ ├── UserManagementResource.java │ │ │ │ ├── UserManagementResourceHelper.java │ │ │ │ └── cmd/ │ │ │ │ ├── AbstractJobCommand.java │ │ │ │ ├── AddBranchCmd.java │ │ │ │ ├── AddProjectToSpaceCmd.java │ │ │ │ ├── CloneRepositoryCmd.java │ │ │ │ ├── CompileProjectCmd.java │ │ │ │ ├── CreateProjectCmd.java │ │ │ │ ├── CreateSpaceCmd.java │ │ │ │ ├── DeleteProjectCmd.java │ │ │ │ ├── DeployProjectCmd.java │ │ │ │ ├── InstallProjectCmd.java │ │ │ │ ├── RemoveBranchCmd.java │ │ │ │ ├── RemoveSpaceCmd.java │ │ │ │ ├── TestProjectCmd.java │ │ │ │ └── UpdateSpaceCmd.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ ├── m2repo/ │ │ │ │ └── preferences/ │ │ │ │ └── ArtifactRepositoryPreferenceTest.java │ │ │ └── rest/ │ │ │ └── backend/ │ │ │ ├── JobRequestHelperCreateModuleTest.java │ │ │ ├── JobRequestHelperTest.java │ │ │ ├── PermissionsTest.java │ │ │ ├── ProjectResourceJobTest.java │ │ │ ├── ResourceTypePermissionValidatorTest.java │ │ │ ├── UserManagementHelperTest.java │ │ │ ├── UserManagementResourceJobTest.java │ │ │ └── package-info.java │ │ └── resources/ │ │ └── META-INF/ │ │ ├── beans.xml │ │ └── services/ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ └── uberfire-rest-client/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── org/ │ └── guvnor/ │ └── rest/ │ └── client/ │ ├── AddBranchJobRequest.java │ ├── AddBranchRequest.java │ ├── AddProjectToSpaceRequest.java │ ├── BranchResponse.java │ ├── CloneProjectJobRequest.java │ ├── CloneProjectRequest.java │ ├── CompileProjectRequest.java │ ├── CreateProjectJobRequest.java │ ├── CreateProjectRequest.java │ ├── DeleteProjectRequest.java │ ├── DeployProjectRequest.java │ ├── Entity.java │ ├── InstallProjectRequest.java │ ├── JobRequest.java │ ├── JobResult.java │ ├── JobStatus.java │ ├── NewGroup.java │ ├── NewUser.java │ ├── Permission.java │ ├── PermissionException.java │ ├── PermissionResponse.java │ ├── PermissionType.java │ ├── ProjectResponse.java │ ├── PublicURI.java │ ├── RemoveBranchJobRequest.java │ ├── RemoveBranchRequest.java │ ├── RemoveSpaceRequest.java │ ├── ResourcePermission.java │ ├── Space.java │ ├── SpaceRequest.java │ ├── TestProjectRequest.java │ ├── UberfireRestResponse.java │ ├── UpdateSettingRequest.java │ └── WorkbenchPermission.java ├── uberfire-security/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-security-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── security/ │ │ │ │ ├── annotations/ │ │ │ │ │ ├── PermissionCheck.java │ │ │ │ │ └── ResourceCheck.java │ │ │ │ ├── authz/ │ │ │ │ │ ├── AuthorizationCheck.java │ │ │ │ │ ├── AuthorizationManager.java │ │ │ │ │ ├── AuthorizationPolicy.java │ │ │ │ │ ├── AuthorizationResult.java │ │ │ │ │ ├── Permission.java │ │ │ │ │ ├── PermissionCheck.java │ │ │ │ │ ├── PermissionCollection.java │ │ │ │ │ ├── PermissionManager.java │ │ │ │ │ ├── PermissionType.java │ │ │ │ │ ├── PermissionTypeRegistry.java │ │ │ │ │ ├── ResourceCheck.java │ │ │ │ │ ├── VotingAlgorithm.java │ │ │ │ │ └── adapter/ │ │ │ │ │ └── GroupsAdapter.java │ │ │ │ ├── crypt/ │ │ │ │ │ └── CryptProvider.java │ │ │ │ └── impl/ │ │ │ │ └── authz/ │ │ │ │ ├── AffirmativeBasedVoter.java │ │ │ │ ├── AuthorizationPolicyBuilder.java │ │ │ │ ├── ConsensusBasedVoter.java │ │ │ │ ├── DefaultAuthorizationEntry.java │ │ │ │ ├── DefaultAuthorizationManager.java │ │ │ │ ├── DefaultAuthorizationPolicy.java │ │ │ │ ├── DefaultAuthzResultCache.java │ │ │ │ ├── DefaultPermissionCollection.java │ │ │ │ ├── DefaultPermissionManager.java │ │ │ │ ├── DefaultPermissionTypeRegistry.java │ │ │ │ ├── DefaultResourceAction.java │ │ │ │ ├── DefaultResourceType.java │ │ │ │ ├── DotNamedPermission.java │ │ │ │ ├── DotNamedPermissionType.java │ │ │ │ ├── PermissionCheckImpl.java │ │ │ │ ├── ResourceCheckImpl.java │ │ │ │ └── UnanimousBasedVoter.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── security/ │ │ │ └── UberfireSecurityAPI.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── security/ │ │ └── impl/ │ │ └── authz/ │ │ ├── AuthorizationManagerTest.java │ │ ├── DefaultAuthzResultCacheTest.java │ │ ├── DefaultPermissionManagerTest.java │ │ ├── HomePerspectiveTest.java │ │ ├── PermissionCollectionTest.java │ │ ├── PermissionManagerTest.java │ │ └── PermissionTest.java │ ├── uberfire-security-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── security/ │ │ │ │ └── client/ │ │ │ │ └── authz/ │ │ │ │ ├── AuthorizationManagerHelper.java │ │ │ │ └── tree/ │ │ │ │ ├── HasResources.java │ │ │ │ ├── LoadCallback.java │ │ │ │ ├── LoadOptions.java │ │ │ │ ├── PermissionNode.java │ │ │ │ ├── PermissionTree.java │ │ │ │ ├── PermissionTreeFactory.java │ │ │ │ ├── PermissionTreeProvider.java │ │ │ │ ├── PermissionTreeVisitor.java │ │ │ │ └── impl/ │ │ │ │ ├── AbstractPermissionNode.java │ │ │ │ ├── DefaultLoadOptions.java │ │ │ │ ├── DefaultPermissionTree.java │ │ │ │ ├── DefaultPermissionTreeFactory.java │ │ │ │ ├── PermissionGroupNode.java │ │ │ │ ├── PermissionLeafNode.java │ │ │ │ └── PermissionResourceNode.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── security/ │ │ │ └── UberfireSecurityClient.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── security/ │ │ └── client/ │ │ └── authz/ │ │ ├── GeneralTreeProvider.java │ │ ├── PermissionTreeTest.java │ │ └── ProjectTreeProvider.java │ ├── uberfire-security-client-backend/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── security/ │ │ │ │ └── client/ │ │ │ │ └── SecurityEntryPoint.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── security/ │ │ │ └── UberfireSecurityClientBackend.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── security/ │ │ └── client/ │ │ └── SecurityEntryPointTest.java │ └── uberfire-security-codegen/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── security/ │ │ │ └── processors/ │ │ │ ├── PermissionCheckProcessor.java │ │ │ └── ResourceCheckProcessor.java │ │ └── resources/ │ │ └── META-INF/ │ │ ├── ErraiApp.properties │ │ └── beans.xml │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── security/ │ └── client/ │ └── authz/ │ ├── PermissionCheckProcessorTest.java │ └── ResourceCheckProcessorTest.java ├── uberfire-server/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── server/ │ │ │ ├── BaseFilteredServlet.java │ │ │ ├── BaseUploadServlet.java │ │ │ ├── FileDownloadServlet.java │ │ │ ├── FileUploadServlet.java │ │ │ ├── MimeType.java │ │ │ ├── UploadUriProvider.java │ │ │ ├── cdi/ │ │ │ │ └── UberFireGeneralFactory.java │ │ │ ├── locale/ │ │ │ │ └── GWTLocaleHeaderFilter.java │ │ │ └── util/ │ │ │ └── FileServletUtil.java │ │ └── resources/ │ │ └── META-INF/ │ │ └── beans.xml │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── server/ │ │ ├── FileDownloadServletTest.java │ │ ├── FileUploadServletTest.java │ │ ├── UberFireGeneralFactoryTest.java │ │ ├── UploadUriProviderTest.java │ │ └── locale/ │ │ └── GWTLocaleHeaderFilterTest.java │ └── resources/ │ ├── expected-2-sample.html │ ├── expected-3-sample.html │ ├── expected-4-sample.html │ ├── expected-sample.html │ └── sample.html ├── uberfire-services/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-services-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── common/ │ │ │ │ └── services/ │ │ │ │ ├── backend/ │ │ │ │ │ ├── cache/ │ │ │ │ │ │ ├── Cache.java │ │ │ │ │ │ └── LRUCache.java │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ └── ExceptionUtilities.java │ │ │ │ │ ├── metadata/ │ │ │ │ │ │ └── MetadataServerSideService.java │ │ │ │ │ ├── preferences/ │ │ │ │ │ │ ├── ApplicationPreferencesLoader.java │ │ │ │ │ │ └── SystemPropertiesInitializer.java │ │ │ │ │ ├── util/ │ │ │ │ │ │ └── CommentedOptionFactory.java │ │ │ │ │ └── validation/ │ │ │ │ │ └── GenericValidator.java │ │ │ │ └── shared/ │ │ │ │ ├── config/ │ │ │ │ │ ├── AppConfigService.java │ │ │ │ │ └── ResourceConfigService.java │ │ │ │ ├── exceptions/ │ │ │ │ │ └── GenericPortableException.java │ │ │ │ ├── file/ │ │ │ │ │ ├── SupportsUpdate.java │ │ │ │ │ └── upload/ │ │ │ │ │ ├── FileManagerFields.java │ │ │ │ │ └── FileOperation.java │ │ │ │ ├── message/ │ │ │ │ │ └── Level.java │ │ │ │ ├── metadata/ │ │ │ │ │ ├── MetadataService.java │ │ │ │ │ └── model/ │ │ │ │ │ ├── DiscussionRecord.java │ │ │ │ │ ├── Metadata.java │ │ │ │ │ └── Overview.java │ │ │ │ ├── preferences/ │ │ │ │ │ ├── DefaultWorkbenchPreferenceScopeResolutionStrategies.java │ │ │ │ │ ├── GuvnorPreferenceScopes.java │ │ │ │ │ └── WorkbenchPreferenceScopeResolutionStrategies.java │ │ │ │ ├── security/ │ │ │ │ │ └── AppRoles.java │ │ │ │ ├── test/ │ │ │ │ │ ├── Failure.java │ │ │ │ │ ├── TestResultMessage.java │ │ │ │ │ ├── TestRunnerService.java │ │ │ │ │ └── TestService.java │ │ │ │ └── validation/ │ │ │ │ ├── ValidationService.java │ │ │ │ └── model/ │ │ │ │ └── ValidationMessage.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── common/ │ │ │ └── services/ │ │ │ └── GuvnorServicesAPI.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── common/ │ │ └── services/ │ │ └── shared/ │ │ ├── metadata/ │ │ │ └── model/ │ │ │ └── MetadataTest.java │ │ └── preferences/ │ │ └── DefaultWorkbenchPreferenceScopeResolutionStrategiesTest.java │ └── uberfire-services-backend/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── common/ │ │ │ └── services/ │ │ │ └── backend/ │ │ │ ├── archive/ │ │ │ │ ├── ArchiveServlet.java │ │ │ │ ├── Archiver.java │ │ │ │ └── ZipWriter.java │ │ │ ├── config/ │ │ │ │ ├── AppConfigServiceImpl.java │ │ │ │ ├── DefaultApplicationPreferencesLoader.java │ │ │ │ ├── ResourceConfigServiceImpl.java │ │ │ │ ├── SafeSessionInfo.java │ │ │ │ └── attribute/ │ │ │ │ ├── ConfigAttributes.java │ │ │ │ ├── ConfigAttributesUtil.java │ │ │ │ └── ConfigView.java │ │ │ ├── file/ │ │ │ │ ├── DotFileFilter.java │ │ │ │ ├── FileDiscoveryService.java │ │ │ │ ├── FileDiscoveryServiceImpl.java │ │ │ │ ├── FileExtensionFilter.java │ │ │ │ ├── FileExtensionsFilter.java │ │ │ │ ├── JavaFileFilter.java │ │ │ │ ├── LinkedDirectoryFilter.java │ │ │ │ ├── LinkedDotFileFilter.java │ │ │ │ ├── LinkedFilter.java │ │ │ │ ├── LinkedMetaInfFolderFilter.java │ │ │ │ ├── LinkedRegularFileFilter.java │ │ │ │ ├── PomFileFilter.java │ │ │ │ └── upload/ │ │ │ │ ├── AbstractFileServlet.java │ │ │ │ └── FormData.java │ │ │ ├── metadata/ │ │ │ │ ├── DiscussionAttributesMock.java │ │ │ │ ├── DublinCoreAttributesMock.java │ │ │ │ ├── MetadataBuilder.java │ │ │ │ ├── MetadataCreator.java │ │ │ │ ├── MetadataServiceImpl.java │ │ │ │ ├── OtherMetaAttributesMock.java │ │ │ │ ├── VersionAttributesMock.java │ │ │ │ └── attribute/ │ │ │ │ ├── DiscussionAttributes.java │ │ │ │ ├── DiscussionAttributesUtil.java │ │ │ │ ├── DiscussionView.java │ │ │ │ ├── GeneratedAttributesUtil.java │ │ │ │ ├── GeneratedAttributesView.java │ │ │ │ ├── GeneratedFileAttributes.java │ │ │ │ ├── OtherMetaAttributes.java │ │ │ │ ├── OtherMetaAttributesUtil.java │ │ │ │ └── OtherMetaView.java │ │ │ ├── migration/ │ │ │ │ └── ACLMigrationTool.java │ │ │ ├── preferences/ │ │ │ │ └── WorkbenchPreferenceScopeResolutionStrategiesProducer.java │ │ │ ├── test/ │ │ │ │ ├── TestResultMessageAggregator.java │ │ │ │ └── TestRunnerServiceImpl.java │ │ │ └── util/ │ │ │ └── CommentedOptionFactoryImpl.java │ │ └── resources/ │ │ └── META-INF/ │ │ ├── ErraiApp.properties │ │ └── beans.xml │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── common/ │ │ └── services/ │ │ └── backend/ │ │ ├── MockIOService.java │ │ ├── archive/ │ │ │ ├── ArchiverTest.java │ │ │ └── FileNameResolverTest.java │ │ ├── config/ │ │ │ └── AppConfigServiceImplTest.java │ │ ├── file/ │ │ │ └── upload/ │ │ │ └── AbstractFileServletTest.java │ │ ├── metadata/ │ │ │ ├── MetadataCreatorTest.java │ │ │ ├── MetadataServiceImplTest.java │ │ │ └── attribute/ │ │ │ ├── GeneratedAttributesUtilTest.java │ │ │ └── GeneratedFileAttributesViewTest.java │ │ ├── migration/ │ │ │ └── ACLMigrationToolTest.java │ │ └── test/ │ │ ├── TestResultMessageAggregatorTest.java │ │ └── TestRunnerServiceImplTest.java │ └── resources/ │ ├── META-INF/ │ │ └── services/ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ └── org/ │ └── guvnor/ │ └── common/ │ └── services/ │ └── backend/ │ ├── archive/ │ │ └── testRepository/ │ │ ├── project1/ │ │ │ └── file1.txt │ │ └── project2/ │ │ └── file2.txt │ └── metadata/ │ └── myfile.file ├── uberfire-showcase/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-client-webapp/ │ │ └── pom.xml │ └── uberfire-webapp/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ ├── filtered-webapp/ │ │ └── AboutInfo.html │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ ├── backend/ │ │ │ └── server/ │ │ │ └── impl/ │ │ │ ├── AppSetup.java │ │ │ ├── ApplicationScopedProducer.java │ │ │ ├── ExperimentalEditorServiceImpl.java │ │ │ ├── PicketLinkDefaultUsers.java │ │ │ └── ResourceUpdateDebugger.java │ │ ├── client/ │ │ │ ├── ShowcaseEntryPoint.java │ │ │ ├── events/ │ │ │ │ └── YouTubeVideo.java │ │ │ ├── experimental/ │ │ │ │ ├── editor/ │ │ │ │ │ ├── AssetEditor.java │ │ │ │ │ ├── AssetEditorView.java │ │ │ │ │ ├── AssetEditorViewImpl.html │ │ │ │ │ ├── AssetEditorViewImpl.java │ │ │ │ │ ├── ExperimentalAssetAction.java │ │ │ │ │ ├── ExperimentalAssetAction2.java │ │ │ │ │ ├── ExperimentalAssetEditor.java │ │ │ │ │ └── ExperimentalAssetResourceType.java │ │ │ │ ├── examples/ │ │ │ │ │ ├── global/ │ │ │ │ │ │ ├── GlobalExperimentalFeature1.java │ │ │ │ │ │ ├── GlobalExperimentalFeature2.java │ │ │ │ │ │ └── GlobalExperimentalFeature3.java │ │ │ │ │ ├── group1/ │ │ │ │ │ │ ├── Group1ExperimentalFeature1.java │ │ │ │ │ │ └── Group1ExperimentalFeature2.java │ │ │ │ │ ├── group2/ │ │ │ │ │ │ └── Group2ExperimentalFeature1.java │ │ │ │ │ └── group3/ │ │ │ │ │ ├── Group3ExperimentalFeature1.java │ │ │ │ │ ├── Group3ExperimentalFeature2.java │ │ │ │ │ └── Group3ExperimentalFeature3.java │ │ │ │ ├── perspectives/ │ │ │ │ │ └── ExperimentalPerspective.java │ │ │ │ └── screens/ │ │ │ │ ├── ExperimentalPerspectiveHeader.java │ │ │ │ └── explorer/ │ │ │ │ ├── ExperimentalExplorer.java │ │ │ │ ├── ExperimentalExplorerScreen.java │ │ │ │ ├── ExperimentalExplorerView.java │ │ │ │ ├── ExperimentalExplorerViewImpl.html │ │ │ │ ├── ExperimentalExplorerViewImpl.java │ │ │ │ ├── NewAssetPopup.java │ │ │ │ └── asset/ │ │ │ │ ├── AssetDisplayer.java │ │ │ │ ├── AssetDisplayerView.java │ │ │ │ ├── AssetDisplayerViewImpl.html │ │ │ │ └── AssetDisplayerViewImpl.java │ │ │ ├── navbar/ │ │ │ │ ├── AppNavBar.html │ │ │ │ ├── AppNavBar.java │ │ │ │ └── SearchMenuBuilder.java │ │ │ ├── perspectives/ │ │ │ │ ├── MultiScreenPerspective.java │ │ │ │ ├── SimplePerspective.java │ │ │ │ └── SimplePerspectiveNoContext.java │ │ │ ├── resources/ │ │ │ │ ├── AppImages.java │ │ │ │ ├── AppResource.java │ │ │ │ └── i18n/ │ │ │ │ ├── Constants.java │ │ │ │ ├── Constants.properties │ │ │ │ ├── Constants_es.properties │ │ │ │ ├── Constants_es_ES.properties │ │ │ │ ├── Constants_fr.properties │ │ │ │ ├── Constants_fr_FR.properties │ │ │ │ ├── Constants_it.properties │ │ │ │ ├── Constants_ja.properties │ │ │ │ ├── Constants_ja_JP.properties │ │ │ │ ├── Constants_pt_BR.properties │ │ │ │ └── Constants_zh_CN.properties │ │ │ └── screens/ │ │ │ ├── MultiScreen.html │ │ │ ├── MultiScreen.java │ │ │ ├── MultiScreenSidePanel.java │ │ │ ├── OwnedScreen.java │ │ │ ├── SampleWorkbenchEditor.java │ │ │ ├── TextResourceType.java │ │ │ ├── gadgets/ │ │ │ │ ├── AbstractGitHubStatsScreen.java │ │ │ │ ├── GitHubCodeFrequencyStatsScreen.java │ │ │ │ ├── GitHubCommitActivityStatsScreen.java │ │ │ │ ├── GitHubPunchCardStatsScreen.java │ │ │ │ ├── TwitterGadgetScreen.html │ │ │ │ └── TwitterGadgetScreen.java │ │ │ ├── miscfeatures/ │ │ │ │ ├── MiscFeaturesPresenter.java │ │ │ │ ├── MiscFeaturesView.java │ │ │ │ └── MiscFeaturesView.ui.xml │ │ │ ├── popup/ │ │ │ │ └── SimplePopUp.java │ │ │ ├── splash/ │ │ │ │ ├── FileExplorerSplashScreen.java │ │ │ │ └── NoSplashQueryParamActivator.java │ │ │ ├── todo/ │ │ │ │ ├── AbstractMarkdownScreen.java │ │ │ │ ├── ReadmeScreen.java │ │ │ │ └── TodoListScreen.java │ │ │ ├── videos/ │ │ │ │ └── VideoListScreen.java │ │ │ ├── welcome/ │ │ │ │ ├── WelcomeScreen.java │ │ │ │ ├── WelcomeScreen.ui.xml │ │ │ │ ├── WelcomeTabScreen.html │ │ │ │ └── WelcomeTabScreen.java │ │ │ ├── widgets/ │ │ │ │ ├── WidgetsShowcasePresenter.java │ │ │ │ ├── WidgetsShowcaseView.html │ │ │ │ └── WidgetsShowcaseView.java │ │ │ └── youtube/ │ │ │ ├── YouTubeScreen.html │ │ │ └── YouTubeScreen.java │ │ └── shared/ │ │ └── experimental/ │ │ ├── ExperimentalAssetRemoved.java │ │ └── ExperimentalEditorService.java │ ├── resources/ │ │ ├── ErraiService.properties │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ ├── logback.xml │ │ ├── org/ │ │ │ └── uberfire/ │ │ │ ├── FastCompiledUberfireShowcase.gwt.xml │ │ │ ├── UberfireShowcase.gwt.xml │ │ │ ├── jsbridge/ │ │ │ │ └── public/ │ │ │ │ └── AppFormerComponentsRegistry.js │ │ │ └── public/ │ │ │ ├── css/ │ │ │ │ ├── ruleflow.css │ │ │ │ ├── uberfire-loading.css │ │ │ │ └── uberfire-showcase.css │ │ │ └── js/ │ │ │ └── marked.js │ │ └── security-policy.properties │ └── webapp/ │ ├── WEB-INF/ │ │ ├── beans.xml │ │ └── web.xml │ ├── frameworks/ │ │ └── knockout-3.4.0.js │ ├── index.html │ ├── login.jsp │ └── plugins/ │ ├── angular.sample.html │ ├── angular.sample.js │ ├── dashboard.perspective.js │ ├── editor-sample.js │ ├── editor.html │ ├── home.perspective.js │ ├── home.splash.html │ ├── sample_resource_type.js │ └── splash.sample.js ├── uberfire-ssh/ │ ├── pom.xml │ ├── uberfire-ssh-api/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ssh/ │ │ │ └── service/ │ │ │ ├── backend/ │ │ │ │ ├── auth/ │ │ │ │ │ └── SSHKeyAuthenticator.java │ │ │ │ └── keystore/ │ │ │ │ ├── SSHKeyStore.java │ │ │ │ ├── SSHKeyStoreService.java │ │ │ │ ├── model/ │ │ │ │ │ ├── KeyMetaData.java │ │ │ │ │ └── SSHPublicKey.java │ │ │ │ └── util/ │ │ │ │ └── PublicKeyConverter.java │ │ │ └── shared/ │ │ │ └── editor/ │ │ │ ├── PortableSSHPublicKey.java │ │ │ └── SSHKeyEditorService.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── ssh/ │ │ ├── UberfireSSHAPI.gwt.xml │ │ └── service/ │ │ └── UberfireSSHSharedServiceAPI.gwt.xml │ ├── uberfire-ssh-backend/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── ssh/ │ │ │ │ └── service/ │ │ │ │ └── backend/ │ │ │ │ ├── auth/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── SSHKeyAuthenticatorImpl.java │ │ │ │ │ └── SSHUser.java │ │ │ │ ├── editor/ │ │ │ │ │ └── SSHKeyEditorServiceImpl.java │ │ │ │ └── keystore/ │ │ │ │ └── impl/ │ │ │ │ ├── SSHKeyStoreServiceImpl.java │ │ │ │ ├── storage/ │ │ │ │ │ ├── DefaultSSHKeyStore.java │ │ │ │ │ └── UserSSHKeyStore.java │ │ │ │ └── util/ │ │ │ │ └── SerializingUtils.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ssh/ │ │ │ └── service/ │ │ │ └── backend/ │ │ │ ├── auth/ │ │ │ │ └── impl/ │ │ │ │ └── SSHKeyAuthenticatorImplTest.java │ │ │ ├── editor/ │ │ │ │ └── SSHKeyEditorServiceImplTest.java │ │ │ ├── keystore/ │ │ │ │ └── impl/ │ │ │ │ ├── SSHKeyStoreServiceImplTest.java │ │ │ │ └── storage/ │ │ │ │ └── DefaultSSHKeyStoreTest.java │ │ │ └── test/ │ │ │ ├── AbstractSSHKeyStoreServiceImplTest.java │ │ │ ├── SSHKeyStoreTestUtils.java │ │ │ └── TestSSHKeyStore.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── beans.xml │ │ ├── custom_security/ │ │ │ └── pkeys/ │ │ │ ├── john/ │ │ │ │ ├── john-key.pub │ │ │ │ └── not_a_pkey.properties │ │ │ └── katy/ │ │ │ ├── folder/ │ │ │ │ └── blank.properties │ │ │ ├── katy-key-one.pub │ │ │ ├── katy-key-two.pub │ │ │ ├── not_a_pkey.properties │ │ │ └── wrong_content.pkey │ │ └── pkeys/ │ │ ├── key.txt │ │ └── meta.txt │ └── uberfire-ssh-client/ │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── ssh/ │ │ │ └── client/ │ │ │ ├── SSHClientEntryPoint.java │ │ │ ├── editor/ │ │ │ │ ├── SSHKeysEditorPerspective.java │ │ │ │ ├── SSHKeysEditorScreen.java │ │ │ │ └── component/ │ │ │ │ ├── SSHKeysEditor.java │ │ │ │ ├── SSHKeysEditorView.java │ │ │ │ ├── SSHKeysEditorViewImpl.css │ │ │ │ ├── SSHKeysEditorViewImpl.html │ │ │ │ ├── SSHKeysEditorViewImpl.java │ │ │ │ ├── creation/ │ │ │ │ │ ├── NewSSHKeyModal.java │ │ │ │ │ ├── NewSSHKeyModalHandler.java │ │ │ │ │ ├── NewSSHKeyModalView.java │ │ │ │ │ ├── NewSSHKeyModalViewImpl.css │ │ │ │ │ ├── NewSSHKeyModalViewImpl.html │ │ │ │ │ └── NewSSHKeyModalViewImpl.java │ │ │ │ ├── empty/ │ │ │ │ │ ├── SSHKeysEditorEmptyStateDisplayer.java │ │ │ │ │ ├── SSHKeysEditorEmptyStateDisplayerView.java │ │ │ │ │ ├── SSHKeysEditorEmptyStateDisplayerViewImpl.css │ │ │ │ │ ├── SSHKeysEditorEmptyStateDisplayerViewImpl.html │ │ │ │ │ └── SSHKeysEditorEmptyStateDisplayerViewImpl.java │ │ │ │ └── keys/ │ │ │ │ ├── SSHKeysDisplayer.java │ │ │ │ ├── SSHKeysDisplayerView.java │ │ │ │ ├── SSHKeysDisplayerViewImpl.css │ │ │ │ ├── SSHKeysDisplayerViewImpl.html │ │ │ │ ├── SSHKeysDisplayerViewImpl.java │ │ │ │ └── key/ │ │ │ │ ├── SSHKeyEditor.java │ │ │ │ ├── SSHKeyEditorView.java │ │ │ │ ├── SSHKeyEditorViewImpl.html │ │ │ │ └── SSHKeyEditorViewImpl.java │ │ │ └── resources/ │ │ │ └── i18n/ │ │ │ └── AppformerSSHConstants.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── uberfire/ │ │ └── ssh/ │ │ ├── UberfireSSHClient.gwt.xml │ │ └── client/ │ │ └── resources/ │ │ └── i18n/ │ │ ├── AppformerSSHConstants.properties │ │ ├── AppformerSSHConstants_es.properties │ │ ├── AppformerSSHConstants_fr.properties │ │ ├── AppformerSSHConstants_it.properties │ │ └── AppformerSSHConstants_ja.properties │ └── test/ │ └── java/ │ └── org/ │ └── uberfire/ │ └── ssh/ │ └── client/ │ └── editor/ │ ├── SSHKeysEditorScreenTest.java │ └── component/ │ ├── SSHKeysEditorTest.java │ ├── creation/ │ │ └── NewSSHKeyModalTest.java │ ├── empty/ │ │ └── SSHKeysEditorEmptyStateDisplayerTest.java │ └── keys/ │ ├── SSHKeysDisplayerTest.java │ └── key/ │ └── SSHKeyEditorTest.java ├── uberfire-structure/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-structure-api/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── structure/ │ │ │ │ ├── config/ │ │ │ │ │ └── SystemRepositoryChangedEvent.java │ │ │ │ ├── contributors/ │ │ │ │ │ └── SpaceContributorsUpdatedEvent.java │ │ │ │ ├── deployment/ │ │ │ │ │ ├── DeploymentConfig.java │ │ │ │ │ └── DeploymentConfigService.java │ │ │ │ ├── events/ │ │ │ │ │ ├── AfterCreateOrganizationalUnitEvent.java │ │ │ │ │ └── AfterEditOrganizationalUnitEvent.java │ │ │ │ ├── navigator/ │ │ │ │ │ ├── DataContent.java │ │ │ │ │ ├── FileNavigatorService.java │ │ │ │ │ └── NavigatorContent.java │ │ │ │ ├── organizationalunit/ │ │ │ │ │ ├── NewOrganizationalUnitEvent.java │ │ │ │ │ ├── OrganizationalUnit.java │ │ │ │ │ ├── OrganizationalUnitEventBase.java │ │ │ │ │ ├── OrganizationalUnitSearchService.java │ │ │ │ │ ├── OrganizationalUnitService.java │ │ │ │ │ ├── RemoveOrganizationalUnitEvent.java │ │ │ │ │ ├── RepoAddedToOrganizationalUnitEvent.java │ │ │ │ │ ├── RepoRemovedFromOrganizationalUnitEvent.java │ │ │ │ │ ├── UpdatedOrganizationalUnitEvent.java │ │ │ │ │ ├── config/ │ │ │ │ │ │ ├── BranchPermissions.java │ │ │ │ │ │ ├── RepositoryConfiguration.java │ │ │ │ │ │ ├── RepositoryInfo.java │ │ │ │ │ │ ├── RolePermissions.java │ │ │ │ │ │ ├── SpaceConfigStorage.java │ │ │ │ │ │ ├── SpaceConfigStorageBatch.java │ │ │ │ │ │ ├── SpaceConfigStorageRegistry.java │ │ │ │ │ │ ├── SpaceInfo.java │ │ │ │ │ │ └── SpaceState.java │ │ │ │ │ └── impl/ │ │ │ │ │ └── OrganizationalUnitImpl.java │ │ │ │ ├── pom/ │ │ │ │ │ ├── AddPomDependencyEvent.java │ │ │ │ │ ├── DependencyType.java │ │ │ │ │ └── DynamicPomDependency.java │ │ │ │ ├── repositories/ │ │ │ │ │ ├── Branch.java │ │ │ │ │ ├── EnvironmentParameters.java │ │ │ │ │ ├── GitMetadata.java │ │ │ │ │ ├── GitMetadataStore.java │ │ │ │ │ ├── NewBranchEvent.java │ │ │ │ │ ├── NewRepositoryEvent.java │ │ │ │ │ ├── PublicURI.java │ │ │ │ │ ├── Repository.java │ │ │ │ │ ├── RepositoryAlreadyExistsException.java │ │ │ │ │ ├── RepositoryCopier.java │ │ │ │ │ ├── RepositoryEnvironmentConfiguration.java │ │ │ │ │ ├── RepositoryEnvironmentConfigurations.java │ │ │ │ │ ├── RepositoryEnvironmentUpdatedEvent.java │ │ │ │ │ ├── RepositoryExternalUpdateEvent.java │ │ │ │ │ ├── RepositoryInfo.java │ │ │ │ │ ├── RepositoryNotFoundException.java │ │ │ │ │ ├── RepositoryRemovedEvent.java │ │ │ │ │ ├── RepositorySearchService.java │ │ │ │ │ ├── RepositoryService.java │ │ │ │ │ ├── RepositoryServiceEditor.java │ │ │ │ │ ├── RepositoryUpdatedEvent.java │ │ │ │ │ ├── RepositoryUtils.java │ │ │ │ │ ├── changerequest/ │ │ │ │ │ │ ├── ChangeRequestPredicates.java │ │ │ │ │ │ ├── ChangeRequestService.java │ │ │ │ │ │ └── portable/ │ │ │ │ │ │ ├── ChangeRequest.java │ │ │ │ │ │ ├── ChangeRequestAlreadyOpenException.java │ │ │ │ │ │ ├── ChangeRequestComment.java │ │ │ │ │ │ ├── ChangeRequestCommit.java │ │ │ │ │ │ ├── ChangeRequestCountSummary.java │ │ │ │ │ │ ├── ChangeRequestDiff.java │ │ │ │ │ │ ├── ChangeRequestListUpdatedEvent.java │ │ │ │ │ │ ├── ChangeRequestStatus.java │ │ │ │ │ │ ├── ChangeRequestStatusUpdatedEvent.java │ │ │ │ │ │ ├── ChangeRequestUpdatedEvent.java │ │ │ │ │ │ ├── ChangeType.java │ │ │ │ │ │ ├── NothingToMergeException.java │ │ │ │ │ │ ├── PaginatedChangeRequestCommentList.java │ │ │ │ │ │ └── PaginatedChangeRequestList.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── DefaultPublicURI.java │ │ │ │ │ ├── GitMetadataImpl.java │ │ │ │ │ └── git/ │ │ │ │ │ ├── GitRepository.java │ │ │ │ │ └── event/ │ │ │ │ │ ├── FileSystemHookNotificationEvent.java │ │ │ │ │ ├── NotificationType.java │ │ │ │ │ └── PostCommitNotificationEvent.java │ │ │ │ ├── security/ │ │ │ │ │ ├── OrgUnitResourceType.java │ │ │ │ │ ├── OrganizationalUnitAction.java │ │ │ │ │ ├── RepositoryAction.java │ │ │ │ │ └── RepositoryResourceType.java │ │ │ │ └── server/ │ │ │ │ ├── config/ │ │ │ │ │ ├── ConfigGroup.java │ │ │ │ │ ├── ConfigItem.java │ │ │ │ │ ├── ConfigType.java │ │ │ │ │ ├── ConfigurationFactory.java │ │ │ │ │ ├── ConfigurationService.java │ │ │ │ │ ├── PasswordService.java │ │ │ │ │ └── SecureConfigItem.java │ │ │ │ ├── deployment/ │ │ │ │ │ └── DeploymentConfigFactory.java │ │ │ │ ├── organizationalunit/ │ │ │ │ │ └── OrganizationalUnitFactory.java │ │ │ │ └── repositories/ │ │ │ │ ├── RepositoryFactory.java │ │ │ │ └── RepositoryFactoryHelper.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ └── ErraiApp.properties │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── structure/ │ │ │ └── GuvnorStructureAPI.gwt.xml │ │ └── test/ │ │ └── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── structure/ │ │ └── repositories/ │ │ ├── RepositoryUtilsTest.java │ │ ├── changerequest/ │ │ │ └── ChangeRequestPredicatesTest.java │ │ └── impl/ │ │ └── git/ │ │ └── event/ │ │ └── NotificationTypeTest.java │ ├── uberfire-structure-backend/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── guvnor/ │ │ │ │ └── structure/ │ │ │ │ └── backend/ │ │ │ │ ├── FileNavigatorServiceImpl.java │ │ │ │ ├── FileSystemDeleteWorker.java │ │ │ │ ├── InputEscapeUtils.java │ │ │ │ ├── LocaleContext.java │ │ │ │ ├── backcompat/ │ │ │ │ │ └── BackwardCompatibleUtil.java │ │ │ │ ├── config/ │ │ │ │ │ ├── Added.java │ │ │ │ │ ├── ConfigGroupMarshaller.java │ │ │ │ │ ├── ConfigurationFactoryImpl.java │ │ │ │ │ ├── ConfigurationServiceImpl.java │ │ │ │ │ ├── DefaultPasswordServiceImpl.java │ │ │ │ │ ├── OrgUnit.java │ │ │ │ │ ├── Removed.java │ │ │ │ │ ├── Repository.java │ │ │ │ │ └── watch/ │ │ │ │ │ ├── AsyncConfigWatchService.java │ │ │ │ │ ├── AsyncWatchServiceCallback.java │ │ │ │ │ ├── ConfigServiceWatchServiceExecutor.java │ │ │ │ │ └── ConfigServiceWatchServiceExecutorImpl.java │ │ │ │ ├── deployment/ │ │ │ │ │ ├── DeploymentConfigChangedEvent.java │ │ │ │ │ ├── DeploymentConfigFactoryImpl.java │ │ │ │ │ ├── DeploymentConfigImpl.java │ │ │ │ │ └── DeploymentConfigServiceImpl.java │ │ │ │ ├── organizationalunit/ │ │ │ │ │ ├── OrganizationalUnitFactoryImpl.java │ │ │ │ │ ├── OrganizationalUnitSearchServiceImpl.java │ │ │ │ │ ├── OrganizationalUnitServiceImpl.java │ │ │ │ │ └── config/ │ │ │ │ │ ├── ActiveSpaceConfigStorageBatchContextRegistry.java │ │ │ │ │ ├── SpaceConfigCleanUp.java │ │ │ │ │ ├── SpaceConfigStorageImpl.java │ │ │ │ │ └── SpaceConfigStorageRegistryImpl.java │ │ │ │ ├── pom/ │ │ │ │ │ ├── DependencyTypesMapper.java │ │ │ │ │ ├── PomEditor.java │ │ │ │ │ ├── PomEditorDefault.java │ │ │ │ │ ├── PomJsonReader.java │ │ │ │ │ ├── PomJsonReaderDefault.java │ │ │ │ │ └── PomStructureEditor.java │ │ │ │ └── repositories/ │ │ │ │ ├── BranchAccessAuthorizer.java │ │ │ │ ├── ChangeRequestServiceImpl.java │ │ │ │ ├── ConfiguredRepositories.java │ │ │ │ ├── ConfiguredRepositoriesBySpace.java │ │ │ │ ├── ConfiguredRepositoriesImpl.java │ │ │ │ ├── LoadReposOnAppInit.java │ │ │ │ ├── RepositoryCopierImpl.java │ │ │ │ ├── RepositoryFactoryImpl.java │ │ │ │ ├── RepositorySearchServiceImpl.java │ │ │ │ ├── RepositoryServiceEditorImpl.java │ │ │ │ ├── RepositoryServiceImpl.java │ │ │ │ ├── SystemRepository.java │ │ │ │ └── git/ │ │ │ │ ├── GitMetadataStoreImpl.java │ │ │ │ ├── GitPathUtil.java │ │ │ │ ├── GitRepositoryBuilder.java │ │ │ │ ├── GitRepositoryFactoryHelper.java │ │ │ │ └── hooks/ │ │ │ │ ├── PostCommitNotificationService.java │ │ │ │ ├── exception/ │ │ │ │ │ └── BranchOperationNotAllowedException.java │ │ │ │ └── impl/ │ │ │ │ ├── MessageReader.java │ │ │ │ └── PostCommitNotificationServiceImpl.java │ │ │ └── resources/ │ │ │ ├── DependencyTypesMapper.json │ │ │ └── META-INF/ │ │ │ └── beans.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── structure/ │ │ │ └── backend/ │ │ │ ├── FileSystemDeleteWorkerTest.java │ │ │ ├── InputEscapeUtilsTest.java │ │ │ ├── backcompat/ │ │ │ │ └── BackwardCompatibleUtilTest.java │ │ │ ├── config/ │ │ │ │ ├── ConfigurationFactoryImplTest.java │ │ │ │ └── ConfigurationServiceImplTest.java │ │ │ ├── organizationalunit/ │ │ │ │ ├── OrganizationalUnitFactoryImplTest.java │ │ │ │ ├── OrganizationalUnitSearchServiceTest.java │ │ │ │ ├── OrganizationalUnitServiceTest.java │ │ │ │ └── config/ │ │ │ │ ├── SpaceConfigCleanUpTest.java │ │ │ │ ├── SpaceConfigStorageImplTest.java │ │ │ │ └── SpaceConfigStorageRegistryImplTest.java │ │ │ ├── pom/ │ │ │ │ ├── DependencyTypesMapperTest.java │ │ │ │ ├── PomEditorDefaultTest.java │ │ │ │ ├── PomJsonReaderTest.java │ │ │ │ ├── PomStructureEditorTest.java │ │ │ │ └── TestUtil.java │ │ │ └── repositories/ │ │ │ ├── BranchAccessAuthorizerTest.java │ │ │ ├── ChangeRequestServiceTest.java │ │ │ ├── ConfiguredRepositoriesTest.java │ │ │ ├── LoadReposOnAppInitTest.java │ │ │ ├── RepositoryCopierImplTest.java │ │ │ ├── RepositorySearchServiceTest.java │ │ │ ├── RepositoryServiceImplTest.java │ │ │ └── git/ │ │ │ ├── GitMetadataImplStoreTest.java │ │ │ ├── GitPathUtilTest.java │ │ │ ├── GitRepositoryFactoryHelperBaseTest.java │ │ │ ├── GitRepositoryFactoryHelperNoIndexTest.java │ │ │ ├── GitRepositoryFactoryHelperTest.java │ │ │ └── hooks/ │ │ │ └── impl/ │ │ │ └── PostCommitNotificationServiceImplTest.java │ │ └── resources/ │ │ ├── DependencyTypesMapper.json │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ │ ├── bundles/ │ │ │ ├── Messages.properties │ │ │ ├── Messages_ca.properties │ │ │ └── Messages_en.properties │ │ ├── dummy/ │ │ │ └── pom.xml │ │ ├── dummyOverride/ │ │ │ ├── FixedSpaceInfo.json │ │ │ └── pom.xml │ │ ├── dummy_empty_deps/ │ │ │ └── pom.xml │ │ ├── logback.xml │ │ └── niogit/ │ │ ├── space1/ │ │ │ └── .gitignore │ │ ├── space2/ │ │ │ └── .gitignore │ │ └── system/ │ │ └── .gitignore │ └── uberfire-structure-client/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── structure/ │ │ │ └── client/ │ │ │ ├── StructureEntryPoint.java │ │ │ ├── advnavigator/ │ │ │ │ ├── Navigator.java │ │ │ │ ├── NavigatorOptions.java │ │ │ │ └── TreeNavigator.java │ │ │ ├── editors/ │ │ │ │ ├── context/ │ │ │ │ │ ├── GuvnorStructureContext.java │ │ │ │ │ ├── GuvnorStructureContextBranchChangeHandler.java │ │ │ │ │ └── GuvnorStructureContextChangeHandler.java │ │ │ │ ├── fileexplorer/ │ │ │ │ │ ├── FileExplorerItem.java │ │ │ │ │ ├── FileExplorerPresenter.java │ │ │ │ │ ├── FileExplorerView.java │ │ │ │ │ ├── FileExplorerViewImpl.java │ │ │ │ │ └── PathSelectedEvent.java │ │ │ │ └── repository/ │ │ │ │ ├── RepositoryPreferences.java │ │ │ │ ├── clone/ │ │ │ │ │ ├── CloneRepositoryPresenter.java │ │ │ │ │ ├── CloneRepositoryView.java │ │ │ │ │ ├── CloneRepositoryViewImpl.java │ │ │ │ │ └── CloneRepositoryViewImpl.ui.xml │ │ │ │ ├── common/ │ │ │ │ │ └── CopyRepositoryUrlBtn.java │ │ │ │ ├── edit/ │ │ │ │ │ ├── RepositoryEditorPresenter.java │ │ │ │ │ ├── RepositoryEditorView.java │ │ │ │ │ └── RepositoryEditorView.ui.xml │ │ │ │ └── list/ │ │ │ │ ├── ProtocolButton.java │ │ │ │ ├── PublicURIButton.java │ │ │ │ ├── RepositoriesPresenter.java │ │ │ │ ├── RepositoriesView.java │ │ │ │ ├── RepositoriesViewImpl.java │ │ │ │ ├── RepositoriesViewImpl.ui.xml │ │ │ │ ├── RepositoryItemPresenter.java │ │ │ │ ├── RepositoryItemView.java │ │ │ │ ├── RepositoryItemViewImpl.java │ │ │ │ └── RepositoryItemViewImpl.ui.xml │ │ │ ├── navigator/ │ │ │ │ ├── CommitNavigatorEntry.java │ │ │ │ └── CommitNavigatorEntry.ui.xml │ │ │ ├── repositories/ │ │ │ │ └── git/ │ │ │ │ └── FileSystemHookNotifier.java │ │ │ ├── resources/ │ │ │ │ ├── NavigatorResources.java │ │ │ │ └── i18n/ │ │ │ │ └── CommonConstants.java │ │ │ └── security/ │ │ │ ├── OrganizationalUnitController.java │ │ │ ├── OrganizationalUnitTreeProvider.java │ │ │ ├── RepositoryController.java │ │ │ └── RepositoryTreeProvider.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ ├── ErraiApp.properties │ │ │ └── beans.xml │ │ └── org/ │ │ └── guvnor/ │ │ └── structure/ │ │ ├── GuvnorStructureClient.gwt.xml │ │ ├── client/ │ │ │ └── resources/ │ │ │ ├── css/ │ │ │ │ └── Navigator.css │ │ │ └── i18n/ │ │ │ ├── CommonConstants.properties │ │ │ ├── CommonConstants_de.properties │ │ │ ├── CommonConstants_es.properties │ │ │ ├── CommonConstants_fr.properties │ │ │ ├── CommonConstants_it.properties │ │ │ ├── CommonConstants_ja.properties │ │ │ ├── CommonConstants_pt_BR.properties │ │ │ └── CommonConstants_zh_CN.properties │ │ └── public/ │ │ └── zeroclipboard/ │ │ ├── ZeroClipboard.swf │ │ └── ZeroClipboardLoader.js │ └── test/ │ └── java/ │ └── org/ │ └── guvnor/ │ └── structure/ │ ├── client/ │ │ ├── editors/ │ │ │ ├── TestUtil.java │ │ │ ├── context/ │ │ │ │ ├── GuvnorStructureContextHandlersTest.java │ │ │ │ └── GuvnorStructureContextTest.java │ │ │ ├── fileexplorer/ │ │ │ │ ├── FileExplorerPresenterTest.java │ │ │ │ └── FileExplorerViewImplTest.java │ │ │ └── repository/ │ │ │ ├── clone/ │ │ │ │ ├── CloneMavenRepositoryPresenterTest.java │ │ │ │ └── answer/ │ │ │ │ ├── OuServiceAnswer.java │ │ │ │ ├── RsCreateRepositoryAnswer.java │ │ │ │ ├── RsCreateRepositoryFailAnswer.java │ │ │ │ └── RsNormalizedNameAnswer.java │ │ │ ├── common/ │ │ │ │ └── CopyMavenRepositoryUrlBtnTest.java │ │ │ ├── edit/ │ │ │ │ └── MavenRepositoryEditorPresenterTest.java │ │ │ └── list/ │ │ │ ├── MavenRepositoryItemPresenterTest.java │ │ │ └── RepositoriesPresenterTest.java │ │ └── security/ │ │ └── OrganizationalUnitControllerTest.java │ ├── organizationalunit/ │ │ ├── OrganizationalUnitServiceCallerMock.java │ │ └── OrganizationalUnitTreeProviderTest.java │ └── repositories/ │ ├── RepositoryServiceCallerMock.java │ ├── RepositoryTreeProviderTest.java │ └── git/ │ └── FileSystemHookNotifierTest.java ├── uberfire-test-utils/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── guvnor/ │ │ │ └── test/ │ │ │ ├── CDITestSetup.java │ │ │ ├── GuvnorTestAppSetup.java │ │ │ ├── TempFiles.java │ │ │ ├── TestFileSystem.java │ │ │ ├── TestIdentityFactory.java │ │ │ ├── TestTempFileSystem.java │ │ │ └── WeldJUnitRunner.java │ │ └── resources/ │ │ └── META-INF/ │ │ ├── beans.xml │ │ └── services/ │ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── test/ │ │ ├── TempFilesTest.java │ │ └── WeldJUnitRunnerTest.java │ └── resources/ │ ├── META-INF/ │ │ └── beans.xml │ └── logback-test.xml ├── uberfire-testing-utils/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ ├── mocks/ │ │ │ ├── CallerMock.java │ │ │ ├── CallerProxy.java │ │ │ ├── ConstantsAnswerMock.java │ │ │ ├── EventSourceMock.java │ │ │ ├── FileSystemTestingUtils.java │ │ │ ├── IocTestingUtils.java │ │ │ ├── MockInstanceImpl.java │ │ │ ├── ParametrizedCommandMock.java │ │ │ └── SessionInfoMock.java │ │ └── promise/ │ │ └── SyncPromises.java │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ ├── mocks/ │ │ │ ├── CallerMockTest.java │ │ │ ├── ConstantsAnswerMockTest.java │ │ │ ├── EventSourceMockTest.java │ │ │ ├── FileSystemTestingUtilsTest.java │ │ │ ├── IocTestingUtilsTest.java │ │ │ └── ParametrizedCommandMockTest.java │ │ └── promise/ │ │ └── SyncPromisesTest.java │ └── resources/ │ └── META-INF/ │ └── services/ │ └── org.uberfire.java.nio.file.spi.FileSystemProvider ├── uberfire-workbench/ │ ├── .gitignore │ ├── pom.xml │ ├── uberfire-workbench-client/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── client/ │ │ │ │ ├── authz/ │ │ │ │ │ ├── ActivityAction.java │ │ │ │ │ ├── ActivityCheck.java │ │ │ │ │ ├── DefaultWorkbenchController.java │ │ │ │ │ ├── EditorTreeProvider.java │ │ │ │ │ ├── PerspectiveAction.java │ │ │ │ │ ├── PerspectiveCheck.java │ │ │ │ │ ├── PerspectiveTreeProvider.java │ │ │ │ │ ├── WorkbenchController.java │ │ │ │ │ └── WorkbenchControllerHelper.java │ │ │ │ ├── menu/ │ │ │ │ │ ├── AuthFilterMenuVisitor.java │ │ │ │ │ ├── CustomSplashHelp.java │ │ │ │ │ ├── SplashScreenMenuPresenter.java │ │ │ │ │ ├── WorkbenchViewModeSwitcherMenuBuilder.java │ │ │ │ │ └── WorkbenchViewModeSwitcherPresenter.java │ │ │ │ ├── mvp/ │ │ │ │ │ ├── AbstractActivity.java │ │ │ │ │ ├── AbstractPopupActivity.java │ │ │ │ │ ├── AbstractSplashScreenActivity.java │ │ │ │ │ ├── AbstractWorkbenchActivity.java │ │ │ │ │ ├── AbstractWorkbenchClientEditorActivity.java │ │ │ │ │ ├── AbstractWorkbenchContextActivity.java │ │ │ │ │ ├── AbstractWorkbenchEditorActivity.java │ │ │ │ │ ├── AbstractWorkbenchPerspectiveActivity.java │ │ │ │ │ ├── AbstractWorkbenchScreenActivity.java │ │ │ │ │ ├── AcceptItem.java │ │ │ │ │ ├── Activity.java │ │ │ │ │ ├── ActivityAndMetaInfo.java │ │ │ │ │ ├── ActivityBeansCache.java │ │ │ │ │ ├── ActivityBeansInfo.java │ │ │ │ │ ├── ActivityLifecycleError.java │ │ │ │ │ ├── ActivityLifecycleErrorHandler.java │ │ │ │ │ ├── ActivityManager.java │ │ │ │ │ ├── ActivityManagerImpl.java │ │ │ │ │ ├── ActivityMetaInfo.java │ │ │ │ │ ├── BookmarkableUrlHelper.java │ │ │ │ │ ├── CategoriesManagerCache.java │ │ │ │ │ ├── ContextActivity.java │ │ │ │ │ ├── ContextSensitiveActivity.java │ │ │ │ │ ├── ForceUnlockEventObserver.java │ │ │ │ │ ├── IsClientEditor.java │ │ │ │ │ ├── IsSplashScreen.java │ │ │ │ │ ├── IsTemplatePerspective.java │ │ │ │ │ ├── LockDemandDetector.java │ │ │ │ │ ├── LockManager.java │ │ │ │ │ ├── LockManagerImpl.java │ │ │ │ │ ├── LockTitleWidgetEvent.java │ │ │ │ │ ├── PerspectiveActivity.java │ │ │ │ │ ├── PerspectiveManager.java │ │ │ │ │ ├── PerspectiveManagerImpl.java │ │ │ │ │ ├── PlaceHistoryHandler.java │ │ │ │ │ ├── PlaceManager.java │ │ │ │ │ ├── PlaceManagerImpl.java │ │ │ │ │ ├── PlaceRequestHistoryMapper.java │ │ │ │ │ ├── PlaceRequestHistoryMapperImpl.java │ │ │ │ │ ├── PlaceStatus.java │ │ │ │ │ ├── PluginActivityManagerImpl.java │ │ │ │ │ ├── PluginPlaceManagerImpl.java │ │ │ │ │ ├── PopupActivity.java │ │ │ │ │ ├── ResourceTypeManagerCache.java │ │ │ │ │ ├── SplashScreenActivity.java │ │ │ │ │ ├── TemplatedActivity.java │ │ │ │ │ ├── UIPart.java │ │ │ │ │ ├── WorkbenchActivity.java │ │ │ │ │ ├── WorkbenchClientEditorActivity.java │ │ │ │ │ ├── WorkbenchEditorActivity.java │ │ │ │ │ ├── WorkbenchScreenActivity.java │ │ │ │ │ └── jsbridge/ │ │ │ │ │ ├── JsWorkbenchLazyActivity.java │ │ │ │ │ └── JsWorkbenchLazyPerspective.java │ │ │ │ ├── resources/ │ │ │ │ │ ├── WorkbenchCss.java │ │ │ │ │ ├── WorkbenchImages.java │ │ │ │ │ ├── WorkbenchResources.java │ │ │ │ │ └── i18n/ │ │ │ │ │ ├── PermissionTreeConstants.java │ │ │ │ │ ├── PermissionTreeI18NImpl.java │ │ │ │ │ ├── PermissionTreeI18n.java │ │ │ │ │ └── WorkbenchConstants.java │ │ │ │ ├── util/ │ │ │ │ │ ├── CSSLocatorsUtils.java │ │ │ │ │ ├── GWTEditorNativeRegister.java │ │ │ │ │ ├── Layouts.java │ │ │ │ │ └── UserAgent.java │ │ │ │ └── workbench/ │ │ │ │ ├── AlternativeLayout.java │ │ │ │ ├── BeanFactory.java │ │ │ │ ├── DefaultBeanFactory.java │ │ │ │ ├── Footer.java │ │ │ │ ├── Header.java │ │ │ │ ├── LayoutSelection.java │ │ │ │ ├── Orderable.java │ │ │ │ ├── PanelManager.java │ │ │ │ ├── PanelManagerImpl.java │ │ │ │ ├── PluginEntryPoint.java │ │ │ │ ├── StandaloneEditorPerspective.java │ │ │ │ ├── VFSLockServiceProxy.java │ │ │ │ ├── VFSLockServiceProxyClientImpl.java │ │ │ │ ├── VFSServiceProxy.java │ │ │ │ ├── VFSServiceProxyClientImpl.java │ │ │ │ ├── Workbench.java │ │ │ │ ├── WorkbenchCloseHandler.java │ │ │ │ ├── WorkbenchCloseHandlerImpl.java │ │ │ │ ├── WorkbenchCloseHandlerImplFallback.java │ │ │ │ ├── WorkbenchCustomStandalonePerspectiveDefinition.java │ │ │ │ ├── WorkbenchLayout.java │ │ │ │ ├── WorkbenchLayoutImpl.java │ │ │ │ ├── WorkbenchLayoutInfo.java │ │ │ │ ├── WorkbenchLayoutInfoImpl.java │ │ │ │ ├── WorkbenchServicesProxy.java │ │ │ │ ├── WorkbenchServicesProxyClientImpl.java │ │ │ │ ├── annotations/ │ │ │ │ │ ├── AssociatedResources.java │ │ │ │ │ └── Priority.java │ │ │ │ ├── docks/ │ │ │ │ │ ├── UberfireDock.java │ │ │ │ │ ├── UberfireDockContainerReadyEvent.java │ │ │ │ │ ├── UberfireDockPosition.java │ │ │ │ │ ├── UberfireDockReadyEvent.java │ │ │ │ │ ├── UberfireDocks.java │ │ │ │ │ ├── UberfireDocksContainer.java │ │ │ │ │ └── UberfireDocksInteractionEvent.java │ │ │ │ ├── events/ │ │ │ │ │ ├── AbstractPlaceEvent.java │ │ │ │ │ ├── ApplicationReadyEvent.java │ │ │ │ │ ├── BeforeClosePlaceEvent.java │ │ │ │ │ ├── ClosePlaceEvent.java │ │ │ │ │ ├── DropPlaceEvent.java │ │ │ │ │ ├── NewPerspectiveEvent.java │ │ │ │ │ ├── NewWorkbenchScreenEvent.java │ │ │ │ │ ├── PanelFocusEvent.java │ │ │ │ │ ├── PerspectiveChange.java │ │ │ │ │ ├── PlaceGainFocusEvent.java │ │ │ │ │ ├── PlaceHiddenEvent.java │ │ │ │ │ ├── PlaceLostFocusEvent.java │ │ │ │ │ ├── PlaceMaximizedEvent.java │ │ │ │ │ ├── PlaceMinimizedEvent.java │ │ │ │ │ ├── SelectPlaceEvent.java │ │ │ │ │ └── WorkbenchProfileCssClass.java │ │ │ │ ├── panels/ │ │ │ │ │ ├── DockingWorkbenchPanelPresenter.java │ │ │ │ │ ├── DockingWorkbenchPanelView.java │ │ │ │ │ ├── MaximizeToggleButtonPresenter.java │ │ │ │ │ ├── MultiPartWidget.java │ │ │ │ │ ├── SplitPanel.java │ │ │ │ │ ├── UFFlowPanel.java │ │ │ │ │ ├── WorkbenchPanelPresenter.java │ │ │ │ │ ├── WorkbenchPanelView.java │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── AbstractDockingWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── AbstractDockingWorkbenchPanelView.java │ │ │ │ │ │ ├── AbstractMultiPartWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── AbstractMultiPartWorkbenchPanelView.java │ │ │ │ │ │ ├── AbstractSimpleWorkbenchPanelView.java │ │ │ │ │ │ ├── AbstractWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── AbstractWorkbenchPanelView.java │ │ │ │ │ │ ├── AdaptiveWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── AdaptiveWorkbenchPanelView.java │ │ │ │ │ │ ├── ClosableSimpleWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── ClosableSimpleWorkbenchPanelView.java │ │ │ │ │ │ ├── ImmutableWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── ImmutableWorkbenchPanelView.java │ │ │ │ │ │ ├── LayoutPanelPresenter.java │ │ │ │ │ │ ├── LayoutPanelView.java │ │ │ │ │ │ ├── MultiListWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── MultiListWorkbenchPanelView.java │ │ │ │ │ │ ├── MultiScreenWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── MultiScreenWorkbenchPanelView.java │ │ │ │ │ │ ├── MultiTabWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── SimpleDnDWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── SimpleDnDWorkbenchPanelView.java │ │ │ │ │ │ ├── SimpleNoExpandWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── SimpleNoExpandWorkbenchPanelView.java │ │ │ │ │ │ ├── SimpleWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── SimpleWorkbenchPanelView.java │ │ │ │ │ │ ├── SinglePartPanelHelper.java │ │ │ │ │ │ ├── SplitLayoutPanelPresenter.java │ │ │ │ │ │ ├── SplitLayoutPanelView.java │ │ │ │ │ │ ├── StaticWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── StaticWorkbenchPanelView.java │ │ │ │ │ │ ├── TemplatedWorkbenchPanelPresenter.java │ │ │ │ │ │ ├── TemplatedWorkbenchPanelView.java │ │ │ │ │ │ ├── UnanchoredStaticWorkbenchPanelPresenter.java │ │ │ │ │ │ └── UnanchoredStaticWorkbenchPanelView.java │ │ │ │ │ └── support/ │ │ │ │ │ └── PartManager.java │ │ │ │ ├── part/ │ │ │ │ │ ├── AbstractWorkbenchPartPresenter.java │ │ │ │ │ └── WorkbenchPartPresenter.java │ │ │ │ ├── pmgr/ │ │ │ │ │ ├── nswe/ │ │ │ │ │ │ └── part/ │ │ │ │ │ │ ├── WorkbenchPartPresenterDefault.java │ │ │ │ │ │ └── WorkbenchPartView.java │ │ │ │ │ └── unanchored/ │ │ │ │ │ └── part/ │ │ │ │ │ ├── UnanchoredWorkbenchPartPresenter.java │ │ │ │ │ └── UnanchoredWorkbenchPartView.java │ │ │ │ └── widgets/ │ │ │ │ ├── animations/ │ │ │ │ │ ├── LinearFadeInAnimation.java │ │ │ │ │ ├── LinearFadeOutAnimation.java │ │ │ │ │ ├── Pause.java │ │ │ │ │ ├── SequencedAnimation.java │ │ │ │ │ └── Sequencer.java │ │ │ │ ├── common/ │ │ │ │ │ └── ErrorPopupPresenter.java │ │ │ │ ├── dnd/ │ │ │ │ │ ├── CompassDropController.java │ │ │ │ │ ├── CompassWidget.java │ │ │ │ │ ├── DragArea.java │ │ │ │ │ ├── WorkbenchDragAndDropManager.java │ │ │ │ │ ├── WorkbenchDragContext.java │ │ │ │ │ └── WorkbenchPickupDragController.java │ │ │ │ ├── listbar/ │ │ │ │ │ ├── ListBarWidget.java │ │ │ │ │ ├── ListbarPreferences.java │ │ │ │ │ ├── ResizeFlowPanel.java │ │ │ │ │ └── ResizeFocusPanel.java │ │ │ │ ├── menu/ │ │ │ │ │ ├── AbstractWorkbenchMenuProducer.java │ │ │ │ │ ├── HasMenus.java │ │ │ │ │ ├── MenuItemVisibilityHandler.java │ │ │ │ │ ├── PartContextMenusPresenter.java │ │ │ │ │ ├── UtilityMenuBar.java │ │ │ │ │ ├── UtilityMenuBarPresenter.java │ │ │ │ │ ├── WorkbenchMenuBar.java │ │ │ │ │ ├── WorkbenchMenuBarPresenter.java │ │ │ │ │ ├── WorkbenchMenuBarProducer.java │ │ │ │ │ ├── WorkbenchMenuBarStandalonePresenter.java │ │ │ │ │ ├── base/ │ │ │ │ │ │ ├── WorkbenchBaseMenuPresenter.java │ │ │ │ │ │ ├── WorkbenchBaseMenuUtils.java │ │ │ │ │ │ └── WorkbenchBaseMenuView.java │ │ │ │ │ ├── events/ │ │ │ │ │ │ └── PerspectiveVisibiltiyChangeEvent.java │ │ │ │ │ └── megamenu/ │ │ │ │ │ ├── WorkbenchMegaMenuPresenter.java │ │ │ │ │ ├── WorkbenchMegaMenuProducer.java │ │ │ │ │ ├── WorkbenchMegaMenuStandalonePresenter.java │ │ │ │ │ ├── base/ │ │ │ │ │ │ ├── BaseMenuItemPresenter.java │ │ │ │ │ │ ├── CanBeDisabled.java │ │ │ │ │ │ ├── CanHide.java │ │ │ │ │ │ ├── HasChildren.java │ │ │ │ │ │ └── Selectable.java │ │ │ │ │ ├── brand/ │ │ │ │ │ │ └── MegaMenuBrand.java │ │ │ │ │ ├── contextmenuitem/ │ │ │ │ │ │ ├── ChildContextMenuItemPresenter.java │ │ │ │ │ │ └── GroupContextMenuItemPresenter.java │ │ │ │ │ ├── menuitem/ │ │ │ │ │ │ ├── ChildMenuItemPresenter.java │ │ │ │ │ │ ├── GroupMenuItemPresenter.java │ │ │ │ │ │ └── IconMenuItemPresenter.java │ │ │ │ │ └── visitor/ │ │ │ │ │ ├── WorkbenchMegaMenuContextMenuVisitor.java │ │ │ │ │ └── WorkbenchMegaMenuVisitor.java │ │ │ │ ├── multipage/ │ │ │ │ │ ├── MultiPageEditor.java │ │ │ │ │ ├── MultiPageEditorView.java │ │ │ │ │ ├── Multiple.java │ │ │ │ │ ├── Page.java │ │ │ │ │ └── PageView.java │ │ │ │ ├── notfound/ │ │ │ │ │ └── ActivityNotFoundPresenter.java │ │ │ │ ├── notifications/ │ │ │ │ │ └── NotificationManager.java │ │ │ │ ├── panel/ │ │ │ │ │ ├── ContextPanel.java │ │ │ │ │ ├── RequiresResizeFlowPanel.java │ │ │ │ │ ├── RequiresResizeFocusPanel.java │ │ │ │ │ └── StaticFocusedResizePanel.java │ │ │ │ ├── popup/ │ │ │ │ │ └── PopupView.java │ │ │ │ ├── splash/ │ │ │ │ │ └── SplashView.java │ │ │ │ ├── split/ │ │ │ │ │ └── WorkbenchSplitLayoutPanel.java │ │ │ │ └── toolbar/ │ │ │ │ └── WorkbenchToolBarPresenter.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ ├── UberfireWorkbench.gwt.xml │ │ │ └── client/ │ │ │ └── resources/ │ │ │ ├── css/ │ │ │ │ └── workbench.css │ │ │ └── i18n/ │ │ │ ├── PermissionTreeConstants.properties │ │ │ ├── PermissionTreeConstants_es.properties │ │ │ ├── PermissionTreeConstants_fr.properties │ │ │ ├── PermissionTreeConstants_it.properties │ │ │ ├── PermissionTreeConstants_ja.properties │ │ │ ├── WorkbenchConstants.properties │ │ │ ├── WorkbenchConstants_de.properties │ │ │ ├── WorkbenchConstants_es.properties │ │ │ ├── WorkbenchConstants_fr.properties │ │ │ ├── WorkbenchConstants_it.properties │ │ │ ├── WorkbenchConstants_ja.properties │ │ │ ├── WorkbenchConstants_pt_BR.properties │ │ │ └── WorkbenchConstants_zh_CN.properties │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── client/ │ │ │ ├── authz/ │ │ │ │ ├── EditorTreeProviderTest.java │ │ │ │ ├── MenuBuilderAuthzTest.java │ │ │ │ ├── PerspectivePermissionTest.java │ │ │ │ ├── PerspectiveTreeProviderTest.java │ │ │ │ └── WorkbenchControllerTest.java │ │ │ ├── mvp/ │ │ │ │ ├── AbstractActivityTest.java │ │ │ │ ├── AbstractPerspectiveActivityTest.java │ │ │ │ ├── AbstractPopupActivityTest.java │ │ │ │ ├── ActivityBeansCacheActivatedByTest.java │ │ │ │ ├── ActivityBeansCacheTest.java │ │ │ │ ├── ActivityBeansCacheUnitTestWrapper.java │ │ │ │ ├── ActivityBeansInfoTest.java │ │ │ │ ├── ActivityManagerActivatedByTest.java │ │ │ │ ├── ActivityManagerLifecycleTest.java │ │ │ │ ├── ActivityMetaInfoTest.java │ │ │ │ ├── BookmarkableUrlHelperTest.java │ │ │ │ ├── CategoriesManagerCacheTest.java │ │ │ │ ├── LockManagerTest.java │ │ │ │ ├── PerspectiveManagerTest.java │ │ │ │ ├── PlaceHistoryHandlerTest.java │ │ │ │ ├── PlaceRequestHistoryMapperImplTest.java │ │ │ │ ├── ResourceTypeManagerCacheTest.java │ │ │ │ └── WorkbenchEditorActivityTest.java │ │ │ ├── util/ │ │ │ │ ├── CSSLocatorsUtilsTest.java │ │ │ │ ├── LayoutsTest.java │ │ │ │ └── MockIOCBeanDef.java │ │ │ └── workbench/ │ │ │ ├── DefaultBeanFactoryTest.java │ │ │ ├── PanelManagerTest.java │ │ │ ├── WorkbenchCloseHandlerImplTest.java │ │ │ ├── WorkbenchLayoutImplTest.java │ │ │ ├── WorkbenchLayoutInfoImplTest.java │ │ │ ├── WorkbenchStandaloneModeTest.java │ │ │ ├── WorkbenchStartupTest.java │ │ │ ├── docks/ │ │ │ │ └── UberfireDockTest.java │ │ │ ├── panels/ │ │ │ │ ├── impl/ │ │ │ │ │ ├── AbstractDockingWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── AbstractDockingWorkbenchPanelViewTest.java │ │ │ │ │ ├── AbstractMultiPartWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── AbstractSimpleWorkbenchPanelViewTest.java │ │ │ │ │ ├── AbstractWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── AdaptiveWorkbenchPanelViewTest.java │ │ │ │ │ ├── ClosableSimpleWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── ClosableSimpleWorkbenchPanelViewTest.java │ │ │ │ │ ├── MultiListWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── MultiListWorkbenchPanelViewTest.java │ │ │ │ │ ├── MultiTabWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── PlaceManagerTest.java │ │ │ │ │ ├── SimpleDnDWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── SimpleNoExpandWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── SimpleWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── SimpleWorkbenchPanelViewTest.java │ │ │ │ │ ├── SimpleWorkbenchPanelViewUnitTestWrapper.java │ │ │ │ │ ├── SinglePartPanelHelperTest.java │ │ │ │ │ ├── StaticWorkbenchPanelPresenterTest.java │ │ │ │ │ ├── StaticWorkbenchPanelViewTest.java │ │ │ │ │ ├── UnanchoredStaticWorkbenchPanelPresenterTest.java │ │ │ │ │ └── UnanchoredStaticWorkbenchPanelViewTest.java │ │ │ │ └── support/ │ │ │ │ └── PartManagerTest.java │ │ │ └── widgets/ │ │ │ ├── dnd/ │ │ │ │ ├── CompassDropControllerTest.java │ │ │ │ ├── CompassDropControllerUnitTestWrapper.java │ │ │ │ ├── WorkbenchDragAndDropManagerTest.java │ │ │ │ └── WorkbenchDragAndDropManagerUnitTestWrapper.java │ │ │ └── menu/ │ │ │ ├── WorkbenchMenuBarPresenterTest.java │ │ │ ├── WorkbenchMenuBarProducerTest.java │ │ │ ├── WorkbenchMenuBarStandalonePresenterTest.java │ │ │ └── megamenu/ │ │ │ ├── WorkbenchMegaMenuPresenterTest.java │ │ │ ├── WorkbenchMegaMenuProducerTest.java │ │ │ ├── WorkbenchMegaMenuStandalonePresenterTest.java │ │ │ ├── contextmenuitem/ │ │ │ │ ├── ChildContextMenuItemPresenterTest.java │ │ │ │ └── GroupContextMenuItemPresenterTest.java │ │ │ └── menuitem/ │ │ │ ├── ChildMenuItemPresenterTest.java │ │ │ ├── GroupMenuItemPresenterTest.java │ │ │ └── IconMenuItemPresenterTest.java │ │ └── resources/ │ │ └── logback-test.xml │ ├── uberfire-workbench-client-backend/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── client/ │ │ │ │ ├── RuntimePluginsServiceProxyBackendImpl.java │ │ │ │ ├── VFSLockServiceProxyBackendImpl.java │ │ │ │ ├── VFSServiceProxyBackendImpl.java │ │ │ │ ├── WorkbenchBackendEntryPoint.java │ │ │ │ └── WorkbenchServicesProxyBackendImpl.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── UberfireWorkbenchBackend.gwt.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── client/ │ │ │ └── WorkbenchBackendEntryPointTest.java │ │ └── resources/ │ │ └── logback-test.xml │ ├── uberfire-workbench-client-views-patternfly/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── uberfire/ │ │ │ │ └── client/ │ │ │ │ └── views/ │ │ │ │ └── pfly/ │ │ │ │ ├── HTML5DndSeleniumSupport.java │ │ │ │ ├── PatternFlyEntryPoint.java │ │ │ │ ├── dnd/ │ │ │ │ │ ├── CompassWidgetImpl.java │ │ │ │ │ └── CompassWidgetImpl.ui.xml │ │ │ │ ├── dropdown/ │ │ │ │ │ └── ListDropdown.java │ │ │ │ ├── icon/ │ │ │ │ │ └── PatternFlyIconType.java │ │ │ │ ├── listbar/ │ │ │ │ │ ├── ListBarWidgetImpl.java │ │ │ │ │ ├── ListBarWidgetImpl.ui.xml │ │ │ │ │ └── PartListDropdown.java │ │ │ │ ├── maximize/ │ │ │ │ │ └── MaximizeToggleButton.java │ │ │ │ ├── menu/ │ │ │ │ │ ├── DropdownMenuVisitor.java │ │ │ │ │ ├── HasMenuItems.java │ │ │ │ │ ├── MainBrand.java │ │ │ │ │ ├── PartContextMenusView.java │ │ │ │ │ ├── SplashScreenMenuView.java │ │ │ │ │ ├── UserMenu.java │ │ │ │ │ ├── UserMenuViewImpl.java │ │ │ │ │ ├── UtilityMenuBarView.java │ │ │ │ │ ├── WorkbenchMenuBarView.java │ │ │ │ │ ├── WorkbenchMenuCompactNavBarView.java │ │ │ │ │ ├── WorkbenchMenuNavBarView.java │ │ │ │ │ ├── WorkbenchMenuStandardNavBarView.java │ │ │ │ │ ├── WorkbenchViewModeSwitcherView.java │ │ │ │ │ └── megamenu/ │ │ │ │ │ ├── WorkbenchMegaMenuView.html │ │ │ │ │ ├── WorkbenchMegaMenuView.java │ │ │ │ │ ├── WorkbenchMegaMenuView.less │ │ │ │ │ ├── contextmenuitem/ │ │ │ │ │ │ ├── ChildContextMenuItemView.html │ │ │ │ │ │ ├── ChildContextMenuItemView.java │ │ │ │ │ │ ├── GroupContextMenuItemView.html │ │ │ │ │ │ └── GroupContextMenuItemView.java │ │ │ │ │ └── menuitem/ │ │ │ │ │ ├── ChildMenuItemView.html │ │ │ │ │ ├── ChildMenuItemView.java │ │ │ │ │ ├── GroupMenuItemView.html │ │ │ │ │ ├── GroupMenuItemView.java │ │ │ │ │ ├── IconMenuItemView.html │ │ │ │ │ └── IconMenuItemView.java │ │ │ │ ├── modal/ │ │ │ │ │ ├── Bs3Modal.java │ │ │ │ │ └── ErrorPopupView.java │ │ │ │ ├── monaco/ │ │ │ │ │ └── jsinterop/ │ │ │ │ │ ├── ITextModel.java │ │ │ │ │ ├── MonacoEditor.java │ │ │ │ │ ├── MonacoLanguages.java │ │ │ │ │ ├── MonacoStandaloneCodeEditor.java │ │ │ │ │ ├── MonacoStandaloneCodeEditorHelper.java │ │ │ │ │ └── Position.java │ │ │ │ ├── multipage/ │ │ │ │ │ ├── MultiPageEditorImpl.java │ │ │ │ │ ├── MultiPageEditorSelectedPageEvent.java │ │ │ │ │ ├── MultiPageEditorViewImpl.java │ │ │ │ │ ├── PageImpl.java │ │ │ │ │ └── PageViewImpl.java │ │ │ │ ├── multiscreen/ │ │ │ │ │ ├── MultiScreenMenuBuilder.java │ │ │ │ │ ├── MultiScreenPartWidget.html │ │ │ │ │ ├── MultiScreenPartWidget.java │ │ │ │ │ ├── MultiScreenView.html │ │ │ │ │ ├── MultiScreenView.java │ │ │ │ │ └── MultiScreenView.less │ │ │ │ ├── notfound/ │ │ │ │ │ ├── ActivityNotFoundView.html │ │ │ │ │ └── ActivityNotFoundView.java │ │ │ │ ├── notifications/ │ │ │ │ │ ├── NotificationPopupView.java │ │ │ │ │ └── NotificationPopupsManagerView.java │ │ │ │ ├── popup/ │ │ │ │ │ └── PopupViewImpl.java │ │ │ │ ├── resources/ │ │ │ │ │ └── i18n/ │ │ │ │ │ └── Constants.java │ │ │ │ ├── selectpicker/ │ │ │ │ │ ├── ElementHelper.java │ │ │ │ │ ├── JQuery.java │ │ │ │ │ ├── JQueryElementOffset.java │ │ │ │ │ ├── JQueryEvent.java │ │ │ │ │ ├── JQueryList.java │ │ │ │ │ ├── JQuerySelectPicker.java │ │ │ │ │ ├── JQuerySelectPickerEvent.java │ │ │ │ │ └── JQuerySelectPickerTarget.java │ │ │ │ ├── splash/ │ │ │ │ │ ├── SplashModalFooter.html │ │ │ │ │ ├── SplashModalFooter.java │ │ │ │ │ └── SplashViewImpl.java │ │ │ │ ├── style/ │ │ │ │ │ └── PatternFlyStyles.java │ │ │ │ ├── sys/ │ │ │ │ │ ├── MomentUtils.java │ │ │ │ │ ├── PatternFlyBootstrapper.java │ │ │ │ │ └── PatternFlyClientBundle.java │ │ │ │ ├── tab/ │ │ │ │ │ ├── MultiTabWorkbenchPanelView.java │ │ │ │ │ ├── Resize.java │ │ │ │ │ ├── ResizeTabPanel.java │ │ │ │ │ ├── TabPanelEntry.java │ │ │ │ │ ├── TabPanelWithDropdowns.java │ │ │ │ │ ├── TabPanelWithDropdowns.ui.xml │ │ │ │ │ └── UberTabPanel.java │ │ │ │ ├── toolbar/ │ │ │ │ │ ├── WorkbenchToolBarView.java │ │ │ │ │ └── WorkbenchToolBarView.ui.xml │ │ │ │ └── widgets/ │ │ │ │ ├── Button.java │ │ │ │ ├── ConfirmPopup.html │ │ │ │ ├── ConfirmPopup.java │ │ │ │ ├── D3.java │ │ │ │ ├── DateRangePicker.java │ │ │ │ ├── DateRangePickerOptions.java │ │ │ │ ├── DropdownMenu.html │ │ │ │ ├── DropdownMenu.java │ │ │ │ ├── DropdownMenuItem.html │ │ │ │ ├── DropdownMenuItem.java │ │ │ │ ├── Duration.java │ │ │ │ ├── Elemental2Producer.java │ │ │ │ ├── ErrorPopup.java │ │ │ │ ├── ErrorPopupView.html │ │ │ │ ├── ErrorPopupView.java │ │ │ │ ├── FormGroup.java │ │ │ │ ├── FormLabel.java │ │ │ │ ├── FormLabelHelp.java │ │ │ │ ├── HelpIcon.java │ │ │ │ ├── InlineNotification.css │ │ │ │ ├── InlineNotification.html │ │ │ │ ├── InlineNotification.java │ │ │ │ ├── InputAutocomplete.html │ │ │ │ ├── InputAutocomplete.java │ │ │ │ ├── InputAutocompleteOptions.java │ │ │ │ ├── JQueryElementalProducer.java │ │ │ │ ├── JQueryProducer.java │ │ │ │ ├── KebabMenu.html │ │ │ │ ├── KebabMenu.java │ │ │ │ ├── KebabMenuItem.html │ │ │ │ ├── KebabMenuItem.java │ │ │ │ ├── Modal.java │ │ │ │ ├── Moment.java │ │ │ │ ├── MomentDuration.java │ │ │ │ ├── MomentDurationObject.java │ │ │ │ ├── MomentTimeZone.java │ │ │ │ ├── Popover.java │ │ │ │ ├── PopoverOptions.java │ │ │ │ ├── SanitizedNumberInput.java │ │ │ │ ├── Select.java │ │ │ │ └── ValidationState.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── ErraiApp.properties │ │ │ │ └── beans.xml │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── client/ │ │ │ └── views/ │ │ │ ├── PatternFly.gwt.xml │ │ │ ├── PatternFlyTheme.gwt.xml │ │ │ ├── pfly/ │ │ │ │ └── resources/ │ │ │ │ └── i18n/ │ │ │ │ ├── Constants.properties │ │ │ │ ├── Constants_de.properties │ │ │ │ ├── Constants_es.properties │ │ │ │ ├── Constants_fr.properties │ │ │ │ ├── Constants_it.properties │ │ │ │ ├── Constants_ja.properties │ │ │ │ ├── Constants_pt_BR.properties │ │ │ │ └── Constants_zh_CN.properties │ │ │ └── static/ │ │ │ ├── uberfire-patternfly.css │ │ │ └── uberfire-variables.less │ │ └── test/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── client/ │ │ │ └── views/ │ │ │ └── pfly/ │ │ │ ├── PatternFlyTabTests.gwt.xml │ │ │ ├── listbar/ │ │ │ │ ├── ListBarWidgetImplTest.java │ │ │ │ └── PartListDropdownTest.java │ │ │ ├── menu/ │ │ │ │ ├── UserMenuTest.java │ │ │ │ ├── WorkbenchMenuBarViewTest.java │ │ │ │ ├── WorkbenchMenuCompactNavBarViewTest.java │ │ │ │ └── WorkbenchMenuStandardNavBarViewTest.java │ │ │ ├── mock/ │ │ │ │ ├── CountingTabShowHandler.java │ │ │ │ ├── CountingTabShownHandler.java │ │ │ │ ├── MockPartView.java │ │ │ │ └── MockPlaceManager.java │ │ │ ├── modal/ │ │ │ │ └── Bs3ModalTest.java │ │ │ ├── multipage/ │ │ │ │ ├── MultiPageEditorImplTest.java │ │ │ │ └── MultiPageEditorViewImplTest.java │ │ │ ├── multiscreen/ │ │ │ │ ├── MultiScreenMenuBuilderTest.java │ │ │ │ ├── MultiScreenPartWidgetTest.java │ │ │ │ └── MultiScreenViewTest.java │ │ │ ├── selectpicker/ │ │ │ │ └── ElementHelperTest.java │ │ │ ├── sys/ │ │ │ │ └── MomentUtilsTest.java │ │ │ ├── tab/ │ │ │ │ ├── MultiTabWorkbenchPanelViewTest.java │ │ │ │ ├── TabPanelEntryTest.java │ │ │ │ ├── TabPanelWithDropdownsTest.java │ │ │ │ └── UberTabPanelTest.java │ │ │ └── widgets/ │ │ │ ├── ConfirmPopupTest.java │ │ │ ├── ErrorPopupTest.java │ │ │ ├── FormGroupTest.java │ │ │ ├── FormLabelHelpTest.java │ │ │ ├── HelpIconTest.java │ │ │ ├── InlineNotificationTest.java │ │ │ ├── KebabMenuTest.java │ │ │ ├── ModalTest.java │ │ │ ├── SanitizedNumberInputTest.java │ │ │ └── SelectTest.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── ErraiApp.properties │ │ └── log4j.properties │ ├── uberfire-workbench-processors/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── uberfire/ │ │ │ └── annotations/ │ │ │ └── processors/ │ │ │ ├── AbstractErrorAbsorbingProcessor.java │ │ │ ├── AbstractGenerator.java │ │ │ ├── ClientEditorActivityGenerator.java │ │ │ ├── ContextActivityGenerator.java │ │ │ ├── EclipseWorkaroundProcessingEnvironment.java │ │ │ ├── EclipseWorkaroundTypeUtils.java │ │ │ ├── EditorActivityGenerator.java │ │ │ ├── ExperimentalActivityGenerator.java │ │ │ ├── ExperimentalFeatureDefinitionProviderGenerator.java │ │ │ ├── ExperimentalFeatureProcessor.java │ │ │ ├── GenerationCompleteCallback.java │ │ │ ├── GeneratorUtils.java │ │ │ ├── MultiTemplateLoader.java │ │ │ ├── PartInformation.java │ │ │ ├── PerspectiveActivityGenerator.java │ │ │ ├── PerspectiveProcessor.java │ │ │ ├── PopupActivityGenerator.java │ │ │ ├── ScreenActivityGenerator.java │ │ │ ├── SplashScreenActivityGenerator.java │ │ │ ├── TemplateInformation.java │ │ │ ├── TemplateInformationHelper.java │ │ │ ├── WorkbenchClientEditorProcessor.java │ │ │ ├── WorkbenchContextProcessor.java │ │ │ ├── WorkbenchEditorProcessor.java │ │ │ ├── WorkbenchPanelInformation.java │ │ │ ├── WorkbenchPopupProcessor.java │ │ │ ├── WorkbenchScreenProcessor.java │ │ │ ├── WorkbenchSplashScreenProcessor.java │ │ │ ├── exceptions/ │ │ │ │ └── GenerationException.java │ │ │ └── facades/ │ │ │ ├── APIModule.java │ │ │ ├── BackendModule.java │ │ │ └── ClientAPIModule.java │ │ └── resources/ │ │ ├── META-INF/ │ │ │ └── services/ │ │ │ └── javax.annotation.processing.Processor │ │ └── org/ │ │ └── uberfire/ │ │ └── annotations/ │ │ └── processors/ │ │ └── templates/ │ │ ├── activityClientEditor.ftl │ │ ├── activityContext.ftl │ │ ├── activityEditor.ftl │ │ ├── activityScreen.ftl │ │ ├── experimentalFeatureActivity.ftl │ │ ├── experimentalFeatureDefinitionProvider.ftl │ │ ├── perspective.ftl │ │ ├── popupScreen.ftl │ │ └── splashScreen.ftl │ └── uberfire-workbench-processors-tests/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── org/ │ │ └── uberfire/ │ │ └── annotations/ │ │ └── processors/ │ │ └── AbstractProcessorTest.java │ └── test/ │ ├── java/ │ │ └── org/ │ │ └── uberfire/ │ │ ├── annotations/ │ │ │ └── processors/ │ │ │ ├── ExperimentalFeatureProcessorTest.java │ │ │ ├── GeneratorUtilsTest.java │ │ │ ├── PartInformationTest.java │ │ │ ├── PerspectiveProcessorTest.java │ │ │ ├── WorkbenchClientEditorProcessorTest.java │ │ │ ├── WorkbenchEditorProcessorTest.java │ │ │ ├── WorkbenchPopupProcessorTest.java │ │ │ ├── WorkbenchScreenProcessorTest.java │ │ │ └── WorkbenchSplashScreenProcessorTest.java │ │ └── client/ │ │ └── mvp/ │ │ ├── MyTestType.java │ │ ├── QualifierAnnotation.java │ │ └── RegularAnnotation.java │ └── resources/ │ ├── logback-test.xml │ └── org/ │ └── uberfire/ │ └── annotations/ │ └── processors/ │ ├── AnnotatedWithEverything.java │ ├── ExperimentalFeatureTest1.java │ ├── ExperimentalFeatureTest2.java │ ├── ExperimentalFeatureTest3.java │ ├── ExperimentalFeatureTest4.java │ ├── ExperimentalFeatureTest5.java │ ├── PerspectiveTest1.java │ ├── PerspectiveTest10.java │ ├── PerspectiveTest11.java │ ├── PerspectiveTest12.java │ ├── PerspectiveTest13.java │ ├── PerspectiveTest14.java │ ├── PerspectiveTest15.java │ ├── PerspectiveTest16.java │ ├── PerspectiveTest17.java │ ├── PerspectiveTest18.java │ ├── PerspectiveTest19.java │ ├── PerspectiveTest2.java │ ├── PerspectiveTest20.java │ ├── PerspectiveTest21.java │ ├── PerspectiveTest22.java │ ├── PerspectiveTest23.java │ ├── PerspectiveTest24.java │ ├── PerspectiveTest25.java │ ├── PerspectiveTest3.java │ ├── PerspectiveTest4.java │ ├── PerspectiveTest5.java │ ├── PerspectiveTest6.java │ ├── PerspectiveTest7.java │ ├── PerspectiveTest8.java │ ├── PerspectiveTest9.java │ ├── TestBeanActivator.java │ ├── WorkbenchClientEditorTest1.java │ ├── WorkbenchClientEditorTest2.java │ ├── WorkbenchClientEditorTest3.java │ ├── WorkbenchClientEditorTest4.java │ ├── WorkbenchClientEditorTest5.java │ ├── WorkbenchClientEditorTest6.java │ ├── WorkbenchClientEditorTest7.java │ ├── WorkbenchClientEditorTest8.java │ ├── WorkbenchEditorTest1.java │ ├── WorkbenchEditorTest10.java │ ├── WorkbenchEditorTest11.java │ ├── WorkbenchEditorTest12.java │ ├── WorkbenchEditorTest13.java │ ├── WorkbenchEditorTest14.java │ ├── WorkbenchEditorTest15.java │ ├── WorkbenchEditorTest16.java │ ├── WorkbenchEditorTest17.java │ ├── WorkbenchEditorTest18.java │ ├── WorkbenchEditorTest19.java │ ├── WorkbenchEditorTest2.java │ ├── WorkbenchEditorTest20.java │ ├── WorkbenchEditorTest21.java │ ├── WorkbenchEditorTest22.java │ ├── WorkbenchEditorTest23.java │ ├── WorkbenchEditorTest24.java │ ├── WorkbenchEditorTest25.java │ ├── WorkbenchEditorTest26.java │ ├── WorkbenchEditorTest27.java │ ├── WorkbenchEditorTest28.java │ ├── WorkbenchEditorTest29.java │ ├── WorkbenchEditorTest3.java │ ├── WorkbenchEditorTest4.java │ ├── WorkbenchEditorTest5.java │ ├── WorkbenchEditorTest6.java │ ├── WorkbenchEditorTest7.java │ ├── WorkbenchEditorTest8.java │ ├── WorkbenchEditorTest9.java │ ├── WorkbenchPopupTest1.java │ ├── WorkbenchPopupTest10.java │ ├── WorkbenchPopupTest11.java │ ├── WorkbenchPopupTest12.java │ ├── WorkbenchPopupTest13.java │ ├── WorkbenchPopupTest14.java │ ├── WorkbenchPopupTest2.java │ ├── WorkbenchPopupTest3.java │ ├── WorkbenchPopupTest4.java │ ├── WorkbenchPopupTest5.java │ ├── WorkbenchPopupTest6.java │ ├── WorkbenchPopupTest7.java │ ├── WorkbenchPopupTest8.java │ ├── WorkbenchPopupTest9.java │ ├── WorkbenchScreenTest1.java │ ├── WorkbenchScreenTest10.java │ ├── WorkbenchScreenTest11.java │ ├── WorkbenchScreenTest12.java │ ├── WorkbenchScreenTest13.java │ ├── WorkbenchScreenTest14.java │ ├── WorkbenchScreenTest15.java │ ├── WorkbenchScreenTest16.java │ ├── WorkbenchScreenTest17.java │ ├── WorkbenchScreenTest18.java │ ├── WorkbenchScreenTest18Super.java │ ├── WorkbenchScreenTest19.java │ ├── WorkbenchScreenTest2.java │ ├── WorkbenchScreenTest20.java │ ├── WorkbenchScreenTest21.java │ ├── WorkbenchScreenTest22.java │ ├── WorkbenchScreenTest23.java │ ├── WorkbenchScreenTest24.java │ ├── WorkbenchScreenTest25.java │ ├── WorkbenchScreenTest26.java │ ├── WorkbenchScreenTest27.java │ ├── WorkbenchScreenTest28.java │ ├── WorkbenchScreenTest29.java │ ├── WorkbenchScreenTest3.java │ ├── WorkbenchScreenTest30.java │ ├── WorkbenchScreenTest31.java │ ├── WorkbenchScreenTest32.java │ ├── WorkbenchScreenTest33.java │ ├── WorkbenchScreenTest34.java │ ├── WorkbenchScreenTest4.java │ ├── WorkbenchScreenTest5.java │ ├── WorkbenchScreenTest6.java │ ├── WorkbenchScreenTest7.java │ ├── WorkbenchScreenTest8.java │ ├── WorkbenchScreenTest9.java │ ├── WorkbenchSplashScreenTest1.java │ ├── WorkbenchSplashScreenTest10.java │ ├── WorkbenchSplashScreenTest2.java │ ├── WorkbenchSplashScreenTest3.java │ ├── WorkbenchSplashScreenTest4.java │ ├── WorkbenchSplashScreenTest5.java │ ├── WorkbenchSplashScreenTest6.java │ ├── WorkbenchSplashScreenTest7.java │ ├── WorkbenchSplashScreenTest8.java │ ├── WorkbenchSplashScreenTest9.java │ └── expected/ │ ├── ExperimentalFeatureTest1.expected │ ├── ExperimentalFeatureTest2.expected │ ├── ExperimentalFeatureTest3Provider.expected │ ├── ExperimentalFeatureTest3Reference.expected │ ├── ExperimentalFeatureTest4Provider.expected │ ├── ExperimentalFeatureTest4Reference.expected │ ├── ExperimentalFeatureTest5Provider.expected │ ├── ExperimentalFeatureTest5Reference.expected │ ├── PerspectiveTest10.expected │ ├── PerspectiveTest11.expected │ ├── PerspectiveTest12.expected │ ├── PerspectiveTest13.expected │ ├── PerspectiveTest16.expected │ ├── PerspectiveTest17.expected │ ├── PerspectiveTest18.expected │ ├── PerspectiveTest19.expected │ ├── PerspectiveTest20.expected │ ├── PerspectiveTest21.expected │ ├── PerspectiveTest24.expected │ ├── PerspectiveTest25.expected │ ├── PerspectiveTest4.expected │ ├── PerspectiveTest5.expected │ ├── PerspectiveTest6.expected │ ├── PerspectiveTest7.expected │ ├── PerspectiveTest8.expected │ ├── PerspectiveTest9.expected │ ├── WorkbenchClientEditorTest6.expected │ ├── WorkbenchClientEditorTest7.expected │ ├── WorkbenchClientEditorTest8.expected │ ├── WorkbenchEditorTest10.expected │ ├── WorkbenchEditorTest11.expected │ ├── WorkbenchEditorTest12.expected │ ├── WorkbenchEditorTest13.expected │ ├── WorkbenchEditorTest14.expected │ ├── WorkbenchEditorTest15.expected │ ├── WorkbenchEditorTest16.expected │ ├── WorkbenchEditorTest17.expected │ ├── WorkbenchEditorTest18.expected │ ├── WorkbenchEditorTest19.expected │ ├── WorkbenchEditorTest21.expected │ ├── WorkbenchEditorTest22.expected │ ├── WorkbenchEditorTest23.expected │ ├── WorkbenchEditorTest24.expected │ ├── WorkbenchEditorTest25.expected │ ├── WorkbenchEditorTest26.expected │ ├── WorkbenchEditorTest27.expected │ ├── WorkbenchEditorTest28.expected │ ├── WorkbenchEditorTest29.expected │ ├── WorkbenchEditorTest5.expected │ ├── WorkbenchEditorTest6.expected │ ├── WorkbenchEditorTest7.expected │ ├── WorkbenchEditorTest8.expected │ ├── WorkbenchEditorTest9.expected │ ├── WorkbenchPopupTest11.expected │ ├── WorkbenchPopupTest12.expected │ ├── WorkbenchPopupTest13.expected │ ├── WorkbenchPopupTest14.expected │ ├── WorkbenchPopupTest3.expected │ ├── WorkbenchPopupTest4.expected │ ├── WorkbenchPopupTest5.expected │ ├── WorkbenchPopupTest6.expected │ ├── WorkbenchPopupTest7.expected │ ├── WorkbenchPopupTest8.expected │ ├── WorkbenchScreenTest10.expected │ ├── WorkbenchScreenTest11.expected │ ├── WorkbenchScreenTest12.expected │ ├── WorkbenchScreenTest14.expected │ ├── WorkbenchScreenTest15.expected │ ├── WorkbenchScreenTest17.expected │ ├── WorkbenchScreenTest18.expected │ ├── WorkbenchScreenTest19.expected │ ├── WorkbenchScreenTest21.expected │ ├── WorkbenchScreenTest23.expected │ ├── WorkbenchScreenTest24.expected │ ├── WorkbenchScreenTest25.expected │ ├── WorkbenchScreenTest26.expected │ ├── WorkbenchScreenTest27.expected │ ├── WorkbenchScreenTest28.expected │ ├── WorkbenchScreenTest29.expected │ ├── WorkbenchScreenTest30.expected │ ├── WorkbenchScreenTest31.expected │ ├── WorkbenchScreenTest32.expected │ ├── WorkbenchScreenTest33.expected │ ├── WorkbenchScreenTest34.expected │ ├── WorkbenchScreenTest5.expected │ ├── WorkbenchScreenTest6.expected │ ├── WorkbenchScreenTest7.expected │ ├── WorkbenchScreenTest8.expected │ ├── WorkbenchScreenTest9.expected │ ├── WorkbenchSplashScreenTest10.expected │ ├── WorkbenchSplashScreenTest6.expected │ ├── WorkbenchSplashScreenTest7.expected │ └── WorkbenchSplashScreenTest9.expected └── uberfire-workingset/ ├── .gitignore ├── pom.xml ├── uberfire-workingset-api/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── guvnor/ │ │ └── common/ │ │ └── services/ │ │ └── workingset/ │ │ └── client/ │ │ ├── events/ │ │ │ ├── OnWorkingSetApplied.java │ │ │ └── OnWorkingSetDisabled.java │ │ ├── factconstraints/ │ │ │ ├── ArgumentNotSetException.java │ │ │ ├── ConstraintConfiguration.java │ │ │ ├── ValidationResult.java │ │ │ ├── config/ │ │ │ │ └── SimpleConstraintConfigurationImpl.java │ │ │ ├── customform/ │ │ │ │ ├── CustomFormConfiguration.java │ │ │ │ └── predefined/ │ │ │ │ └── DefaultCustomFormImplementation.java │ │ │ ├── dataprovider/ │ │ │ │ └── FieldDataProvider.java │ │ │ └── helper/ │ │ │ ├── ConstraintsContainer.java │ │ │ └── CustomFormsContainer.java │ │ └── model/ │ │ ├── WorkingSetConfigData.java │ │ └── WorkingSetSettings.java │ └── resources/ │ └── org/ │ └── guvnor/ │ └── common/ │ └── services/ │ └── workingset/ │ └── GuvnorWorkingsetAPI.gwt.xml └── uberfire-workingset-client/ ├── .gitignore ├── pom.xml └── src/ └── main/ ├── java/ │ └── org/ │ └── guvnor/ │ └── common/ │ └── services/ │ └── workingset/ │ └── client/ │ └── WorkingSetManager.java └── resources/ ├── META-INF/ │ ├── ErraiApp.properties │ └── beans.xml └── org/ └── guvnor/ └── common/ └── services/ └── workingset/ └── GuvnorWorkingsetClient.gwt.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ /target /local target/ # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject *.ipr *.iws *.iml # Repository wide ignore mac DS_Store files .DS_Store # Created by Zanata /org.uberfire /org.dashbuilder # Live editing asciidoc leaves .html files behind in the source dir uberfire-docs/src/main/asciidoc/*.html **/dependency-reduced-pom.xml **/node_modules **/package-lock.json **/dist ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ [![Uberfire](http://uberfireframework.org/upload/images/uberfire-logo.png)](http://uberfireframework.org/) [![Build Status](http://ci.kiegroup.org/buildStatus/icon?job=uberfire)](http://ci.kiegroup.org/job/uberfire) Uberfire is a web framework for a superior experience in building extensible workbenches and console type applications. It provides an Eclipse like workbench experience for the web, helping you to make maintainable, customizable workbench-style apps in no time flat. Our ultimate goal in Uberfire is to provide a strong ecosystem around it, based on a rich set of pluggable components and a strong infrastructure, allowing different type of users easily build Rich Web Apps on top of it. Uberfire is the technology behind of Drools and jBPM web tooling, and is based on challenges and lessons learned during the workbench development of these projects. ## Learning about Uberfire For those who prefer hands-on learning, checkout the [Uberfire Tutorial](http://www.uberfireframework.org/docs/tutorial/tutorial.html) to create a working Uberfire application, or learn how to start your own project with our [Getting Started Guide](http://www.uberfireframework.org/docs/gettingStarted/gettingStarted.html). And for those who prefer the top-down approach, you can find a detailed descriptions of how to use Uberfire in our [documentation](http://www.uberfireframework.org/docs/index.html). ## Uberfire Community Support Visit our IRC channel (#appformer on freenode) to hang out and share solutions with the Uberfire community. ## Contributing to Uberfire Report bugs or request features through our [issue tracker](https://issues.jboss.org/projects/UF). Contribute code through pull requests to this repository. See our [contributing guidelines](https://github.com/droolsjbpm/droolsjbpm-build-bootstrap/blob/main/README.md) for more details. ## Building and contributing to our documentation In order to build and contribute to our documentation, follow this steps - Fork the repository https://github.com/kiegroup/appformer then clone the fork locally - Get gitbook editor from https://github.com/GitbookIO/editor-legacy - Get gitbook builder from https://github.com/GitbookIO/gitbook (you may need to install npm first) - Edit the docs in your forked repository ../appformer/uberfire-docs in gitbook editor - When you've finished editing, build the docs by running uberfire-docs/buildHtml.sh and uberfire-docs/buildPdf.sh - View the built docs in uberfire-docs/docs/_book/index.html and uberfire-docs/uberfire-docs.pdf - Submit a pull request to get your changes accepted ## License Uberfire Framework is released under Apache 2 License. Check [LICENSE](LICENSE-ASL-2.0.txt) file for more information. ================================================ FILE: appformer-client-api/README.md ================================================ Appformer Client API ==================== Introduction ------------ This module contains basic Appformer client APIs such as: - State Control API: API used on _command-based_ editors to keep track of the state of the editor. It provides an injectable `Registry` to keep track of the commands executed on the editor. ================================================ FILE: appformer-client-api/pom.xml ================================================ uberfire-parent org.uberfire 7.75.0-SNAPSHOT 4.0.0 appformer-client-api AppFormer Client API AppFormer Client API jakarta.enterprise jakarta.enterprise.cdi-api com.google.gwt gwt-user ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/context/Channel.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.context; import java.util.stream.Stream; public enum Channel { DEFAULT("DEFAULT"), ONLINE("ONLINE"), VSCODE("VSCODE"), GITHUB("GITHUB"), DESKTOP("DESKTOP"), EMBEDDED("EMBEDDED"); private final String name; Channel(String name) { this.name = name; } public String getName() { return name; } public static Channel withName(String name) { return Stream.of(Channel.values()) .filter(channel -> channel.getName().equalsIgnoreCase(name)) .findFirst().orElseThrow(() -> new IllegalArgumentException("Name not recognized: " + name)); } } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/context/DefaultEditorContextProviderImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.context; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class DefaultEditorContextProviderImpl implements EditorContextProvider { @Override public Channel getChannel() { return Channel.DEFAULT; } @Override public Optional getOperatingSystem() { return Optional.empty(); } @Override public boolean isReadOnly() { return false; } } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/context/EditorContextProvider.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.context; import java.util.Optional; /** * Provide access to EditorContext properties */ public interface EditorContextProvider { /** * Access the channel where the editor is running (e.g. ONLINE, GITHUB or VSCODE). * @return The channel where the editor is running or DEFAULT if no channel is available. */ Channel getChannel(); /** * Access the operating system where the editor is running (e.g. MACOS, WINDOWS or LINUX). * @return The operating system where the editor is running or Optional.empty() if no information is available. */ Optional getOperatingSystem(); /** * Checks if the editor is in read only mode. * @return If the editor is in read only mode or if is not. */ boolean isReadOnly(); } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/context/OperatingSystem.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.context; import java.util.stream.Stream; public enum OperatingSystem { DEFAULT("DEFAULT"), MACOS("MACOS"), LINUX("LINUX"), WINDOWS("WINDOWS"); private final String name; OperatingSystem(final String name) { this.name = name; } public String getName() { return name; } public static OperatingSystem withName(final String name) { return Stream.of(OperatingSystem.values()) .filter(os -> os.getName().equalsIgnoreCase(name)) .findFirst().orElseThrow(() -> new IllegalArgumentException("Name not recognized: " + name)); } } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/keyboardShortcuts/KeyboardShortcutsApiOpts.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.keyboardShortcuts; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType public class KeyboardShortcutsApiOpts { public static final KeyboardShortcutsApiOpts DEFAULT = new KeyboardShortcutsApiOpts(Repeat.NO_REPEAT); private final Repeat repeat; public KeyboardShortcutsApiOpts(final Repeat repeat) { this.repeat = repeat; } @JsProperty public boolean getRepeat() { return Repeat.REPEAT.equals(repeat); } /** * Repetition mode for Keyboard Shortcuts. *

* REPEAT - When pressing and holding a key, the same action will be fired multiple times. * NO_REPEAT - When pressing and holding a key, the action will be only fired once. */ public enum Repeat { REPEAT, NO_REPEAT } } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/stateControl/registry/DefaultRegistry.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.stateControl.registry; public interface DefaultRegistry extends Registry { } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/stateControl/registry/Registry.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.stateControl.registry; import java.util.List; /** * Represents a basic items registry. * * @param anything that can be registered. */ public interface Registry { /** * Registers an item into the registry * * @param item An item to register */ void register(final C item); /** * Peeks the last added item. Doesn't remove it. * * @return The last added item */ C peek(); /** * Pops the last added item and removes it. * * @return The last added item */ C pop(); /** * Sets the max number of items that can be stored on the registry. * * @param size A positive integer */ void setMaxSize(final int size); /** * Clears the registry */ void clear(); /** * Determines if the registry is empty or not * * @return true if empty, false if not. */ boolean isEmpty(); /** * Returns a {@link List} containing all the items in the registry * * @return A {@link List} of containing the registered items */ List getHistory(); /** * Sets a {@link RegistryChangeListener} to be called when the registry changes. * * @param registryChangeListener A {@link RegistryChangeListener} */ void setRegistryChangeListener(RegistryChangeListener registryChangeListener); } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/stateControl/registry/RegistryChangeListener.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.stateControl.registry; /** * This functional interface represents the code that will be executed every time there's a change on a {@link Registry} */ @FunctionalInterface public interface RegistryChangeListener { /** * Method that will be executed when a change on the registry happens */ void notifyRegistryChange(); } ================================================ FILE: appformer-client-api/src/main/java/org/appformer/client/stateControl/registry/impl/DefaultRegistryImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.stateControl.registry.impl; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; import org.appformer.client.stateControl.registry.DefaultRegistry; import org.appformer.client.stateControl.registry.Registry; import org.appformer.client.stateControl.registry.RegistryChangeListener; /** * The default generic implementation for the {@link Registry} type. * It's implemented for achieving an in-memory and lightweight registry approach, don't do an overuse of it. * Note: The Stack class behavior when using the iterator is not the expected one, so used * ArrayDeque instead of an Stack to provide right iteration order. */ public class DefaultRegistryImpl implements DefaultRegistry { private final Deque items = new ArrayDeque<>(); private int maxStackSize = 200; private RegistryChangeListener registryChangeListener; @Override public void setMaxSize(final int size) { if (size < 0) { throw new IllegalArgumentException("The registry size should be a positive number"); } this.maxStackSize = size; } @Override public void register(final C item) { addIntoStack(item); notifyRegistryChange(); } @Override public void clear() { items.clear(); notifyRegistryChange(); } @Override public List getHistory() { return new ArrayList<>(items); } @Override public void setRegistryChangeListener(final RegistryChangeListener registryChangeListener) { this.registryChangeListener = registryChangeListener; } @Override public C peek() { return items.peek(); } @Override public C pop() { C item = items.pop(); notifyRegistryChange(); return item; } @Override public boolean isEmpty() { return items.isEmpty(); } private void notifyRegistryChange() { if (registryChangeListener != null) { registryChangeListener.notifyRegistryChange(); } } private void addIntoStack(final C item) { if (null != item) { if ((items.size() + 1) > maxStackSize) { items.removeLast(); } items.push(item); } } } ================================================ FILE: appformer-client-api/src/main/resources/META-INF/ErraiApp.properties ================================================ # # Copyright 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: appformer-client-api/src/main/resources/org/appformer/AppformerClientAPI.gwt.xml ================================================ ================================================ FILE: appformer-client-api/src/test/java/org/appformer/client/stateControl/registry/impl/DefaultRegistryImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.appformer.client.stateControl.registry.impl; import org.appformer.client.stateControl.registry.RegistryChangeListener; import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class DefaultRegistryImplTest { private static final Command COMMAND1 = new Command(1); private static final Command COMMAND2 = new Command(2); private static final Command COMMAND3 = new Command(3); private static final Command COMMAND4 = new Command(4); @Mock private RegistryChangeListener changeListener; private DefaultRegistryImpl registry; @Before public void init() { registry = new DefaultRegistryImpl<>(); registry.setRegistryChangeListener(changeListener); } @Test public void basicTest() { registry.register(COMMAND1); registry.register(COMMAND2); registry.register(COMMAND3); registry.register(COMMAND4); verify(changeListener, times(4)).notifyRegistryChange(); assertFalse(registry.isEmpty()); Assertions.assertThat(registry.getHistory()) .hasSize(4) .containsExactly(COMMAND4, COMMAND3, COMMAND2, COMMAND1); Assertions.assertThat(registry.peek()) .isSameAs(COMMAND4); Assertions.assertThat(registry.getHistory()) .hasSize(4) .containsExactly(COMMAND4, COMMAND3, COMMAND2, COMMAND1); Assertions.assertThat(registry.pop()) .isSameAs(COMMAND4); verify(changeListener, times(5)).notifyRegistryChange(); Assertions.assertThat(registry.getHistory()) .hasSize(3) .containsExactly(COMMAND3, COMMAND2, COMMAND1); assertFalse(registry.isEmpty()); Assertions.assertThat(registry.pop()) .isSameAs(COMMAND3); verify(changeListener, times(6)).notifyRegistryChange(); assertFalse(registry.isEmpty()); Assertions.assertThat(registry.getHistory()) .hasSize(2) .containsExactly(COMMAND2, COMMAND1); registry.clear(); verify(changeListener, times(7)).notifyRegistryChange(); assertTrue(registry.isEmpty()); Assertions.assertThat(registry.getHistory()) .isEmpty(); } @Test public void testAddReachingMax() { registry.setMaxSize(2); registry.register(COMMAND1); registry.register(COMMAND2); verify(changeListener, times(2)).notifyRegistryChange(); assertFalse(registry.isEmpty()); Assertions.assertThat(registry.getHistory()) .hasSize(2) .containsExactly(COMMAND2, COMMAND1); registry.register(COMMAND3); verify(changeListener, times(3)).notifyRegistryChange(); assertFalse(registry.isEmpty()); Assertions.assertThat(registry.getHistory()) .hasSize(2) .containsExactly(COMMAND3, COMMAND2); registry.register(COMMAND4); verify(changeListener, times(4)).notifyRegistryChange(); assertFalse(registry.isEmpty()); Assertions.assertThat(registry.getHistory()) .hasSize(2) .containsExactly(COMMAND4, COMMAND3); } @Test public void testSettingWrongMax() { Assertions.assertThatThrownBy(() -> registry.setMaxSize(-1)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("The registry size should be a positive number"); } public static class Command { private Integer id; public Command(Integer id) { this.id = id; } public Integer getId() { return id; } } } ================================================ FILE: appformer-js/.gitignore ================================================ node_modules/ dist/ coverage/ target/ ================================================ FILE: appformer-js/README.md ================================================ Core == This package provides the public AppFormer.js API alongside with its Marshalling capabilities. Usage -- Imagine you have a ReactComponent ```typescript jsx import * as React from "react"; class MyReactComponent extends React.Component<{ exposing: (self: MyReactComponent) => void }, {}> { public fetchDataAndUpdate() { //fetches some data and updates state } public render() { return

...
; } } ``` Turning it into an `AppFormer.Screen` or `AppFormer.Perspective` is simple: ```typescript jsx import * as React from "react"; import * as AppFormer from "appformer-js"; export class MyScreen extends AppFormer.Screen { private screen: MyReactComponent; constructor() { super("my-screen"); this.af_isReact = true; this.af_componentTitle = "MyScreen title"; } af_onOpen(): void { this.screen.fetchDataAndUpdate(); } af_componentRoot(children?: any): AppFormer.Element { return (this.screen = self)} />; } } AppFormer.registerScreen(new MyScreen()); ``` ```typescript jsx import * as React from "react"; import * as AppFormer from "appformer-js"; export class MyPerspective extends AppFormer.Perspective { private perspective: MyReactComponent; constructor() { super("my-screen"); this.af_isReact = true; } af_onOpen(): void { this.perspective.fetchDataAndUpdate(); } af_componentRoot(children?: any): AppFormer.Element { return (this.perspective = self)} />; } } AppFormer.registerPerspective(new MyPerspective()); ``` Note how AppFormer's lifecycle integrates with React's. ================================================ FILE: appformer-js/jest.config.js ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: [ "default", [ "jest-junit", { /* * Removes spaces from test titles and makes first * letter of each word capitalized. * * unit test -> UnitTest * * See junit.xml report for resulting look. */ titleTemplate: (vars) => { var str = vars.title.toLowerCase(); str = str.split(' '); for (var i = 0; i < str.length; i++) { str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1); } var result = str.join(''); return result.replace(','); } } ] ], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" } }; ================================================ FILE: appformer-js/package.json ================================================ { "name": "appformer-js", "version": "0.0.0", "description": "", "license": "Apache-2.0", "main": "./dist/appformer.js", "types": "./dist/index.d.ts", "repository": { "type": "git", "url": "https://github.com/kiegroup/appformer-js.git" }, "dependencies": { "@types/react": "16.14.5", "@types/react-dom": "16.9.12", "bignumber.js": "7.2.1", "react": "16.14.0", "react-dom": "16.14.0" }, "scripts": { "lint": "tslint -c tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest", "init": "yarn install --force", "build": "yarn run lint && yarn test && webpack --mode production" }, "babel": { "presets": [ "env", "react" ] }, "jest-junit": { "outputDirectory": "./target", "suiteName": "org.appformer.js.tests", "suiteNameTemplate": "{filename}", "classNameTemplate": "org.appformer.js.tests.{filename}.{classname}" }, "devDependencies": { "@types/jest": "23.3.1", "babel-core": "6.26.3", "babel-jest": "23.0.0", "babel-loader": "7.1.5", "babel-preset-env": "1.7.0", "babel-preset-react": "6.24.1", "circular-dependency-plugin": "5.0.2", "clean-webpack-plugin": "0.1.19", "jest": "23.5.0", "jest-junit": "6.3.0", "prettier": "1.14.2", "ts-jest": "23.1.3", "ts-loader": "4.4.2", "tslint": "5.11.0", "tslint-config-prettier": "1.15.0", "tslint-react": "3.6.0", "typescript": "2.9.2", "watch": "1.0.2", "webpack": "4.15.1", "webpack-cli": "3.0.8", "write-file-atomic": "2.4.1" }, "resolutions": { "write-file-atomic": "2.4.1" } } ================================================ FILE: appformer-js/pom.xml ================================================ 4.0.0 org.uberfire uberfire-parent 7.75.0-SNAPSHOT ../pom.xml jar appformer-js 7.75.0-SNAPSHOT AppFormer.js :: Core AppFormer.js Core com.github.eirslett frontend-maven-plugin ${project.build.directory} install yarn install-node-and-yarn install node and npm initialize install-node-and-npm lock-treatment-tool execution initialize npm exec @kie/lock-treatment-tool@${version.lock-treatment-tool} -- yarn run init yarn run init yarn run build yarn run build maven-resources-plugin 3.1.0 copy-resources prepare-package copy-resources ${project.build.outputDirectory}/META-INF/resources/webjars/${project.artifactId}/${project.version}/ dist/ false . package.json ================================================ FILE: appformer-js/prettier.config.js ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { printWidth: 120 }; ================================================ FILE: appformer-js/src/appformer/AppFormer.tsx ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { Element } from "../core"; import { Screen } from "./Screen"; import { Perspective } from "./Perspective"; import { Portable } from "../marshalling"; /** * AppFormer.js public API. * */ export class AppFormer { /** * Starts an AppFormer instance. * @param container * The DOM element on which AppFormer will start into * @param callback * Function to be executed after AppFormer init is complete */ public init(container: HTMLElement, callback: () => void): AppFormer { return this; } /** * Registers a Screen component. * @param screen */ // tslint:disable-next-line public registerScreen(screen: Screen): void {} /** * Registers a Perspective component * @param perspective */ // tslint:disable-next-line public registerPerspective(perspective: Perspective): void {} /** * Renders the component with the corresponding id. * @param af_componentId * The component id * @param args * Arbitrary arguments to be used by the component */ // tslint:disable-next-line public goTo(af_componentId: string, args?: Map): void {} /** * Translates a bundle key * @param tkey * The bundle key * @param args * The arguments to this bundle */ // tslint:disable-next-line public translate(tkey: string, args: string[]): string { throw new Error("Not implemented"); } /** * Renders a component. * @param element * The component to be rendered * @param container * The DOM element on which the component will be rendered. * @param callback * Function to be executed after the component is done rendering. */ // tslint:disable-next-line public render(element: Element, container: HTMLElement, callback: () => void): void {} /** * Fires an event using Errai bus. * @param obj * The event object. */ // tslint:disable-next-line public fireEvent(obj: Portable): void {} /** * Executes an RPC call to an Errai Remote. * @param path * The Errai bus RPC path * @param args * The arguments to this RPC */ public rpc(path: string, args: Array>): Promise { throw new Error("Not implemented"); } /** * Unrenders a component * @param af_componentId * The component id. */ // tslint:disable-next-line public close(af_componentId: string): void {} } ================================================ FILE: appformer-js/src/appformer/CompassLayoutPerspective.tsx ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { Perspective } from "./Perspective"; import { Menu, Toolbar } from "./Components"; import { Panel, PanelType } from "./Panel"; import { DisplayInfo } from "./DisplayInfo"; import { Part } from "./Part"; import { Element } from "../core"; /** * Special type of Perspective. It allows its UI to be defined by parts and panels. */ export class CompassLayoutPerspective extends Perspective { private _af_menus?: Menu[] = undefined; private _af_toolbar?: Toolbar = undefined; private _af_defaultPanelType: PanelType = PanelType.MULTI_LIST; private _af_displayInfo: DisplayInfo = new DisplayInfo(); private _af_parts: Part[] = []; private _af_panels: Panel[] = []; protected constructor(componentId: string) { super(componentId); this.af_isTemplated = false; } public af_componentRoot(children?: any): Element { // TODO: translate compass layout to a templated component return
; } get af_menus(): Menu[] | undefined { return this._af_menus; } set af_menus(value: Menu[] | undefined) { this._af_menus = value; } get af_toolbar(): Toolbar | undefined { return this._af_toolbar; } set af_toolbar(value: Toolbar | undefined) { this._af_toolbar = value; } get af_defaultPanelType(): PanelType { return this._af_defaultPanelType; } set af_defaultPanelType(value: PanelType) { this._af_defaultPanelType = value; } get af_displayInfo(): DisplayInfo { return this._af_displayInfo; } set af_displayInfo(value: DisplayInfo) { this._af_displayInfo = value; } get af_parts(): Part[] { return this._af_parts; } set af_parts(value: Part[]) { this._af_parts = value; } get af_panels(): Panel[] { return this._af_panels; } set af_panels(value: Panel[]) { this._af_panels = value; } } ================================================ FILE: appformer-js/src/appformer/Component.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Component as CoreComponent } from "../core"; import { Element } from "../core"; /** * Base AppFormer.js component. It contains the default life-cycle methods that are common to all components. * */ export abstract class Component extends CoreComponent { public readonly af_componentId: string; public af_subscriptions: Map void)> = new Map(); protected constructor(args: { type: string; af_componentId: string }) { super({ type: args.type, core_componentId: args.af_componentId }); this.af_componentId = args.af_componentId; } public af_onStartup(): void { // } public af_onOpen(): void { // } public af_onFocus(): void { // } public af_onLostFocus(): void { // } public af_onMayClose(): boolean { return true; } public af_onClose(): void { // } public af_onShutdown(): void { // } public core_componentRoot(children?: any): Element { return this.af_componentRoot(children); } public abstract af_componentRoot(children?: any): Element; } ================================================ FILE: appformer-js/src/appformer/ComponentTypes.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export enum ComponentTypes { SCREEN = "screen", PERSPECTIVE = "perspective", APPFORMER = "appformer", EDITOR = "editor" } ================================================ FILE: appformer-js/src/appformer/Components.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export const DefaultComponentContainerId = "af-js-default-screen-container"; export class Menu { // TODO } export class Toolbar { // TODO } ================================================ FILE: appformer-js/src/appformer/DisplayInfo.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export class DisplayInfo { private _contextId?: string = undefined; private _contextDisplayMode: ContextDisplayMode = ContextDisplayMode.SHOW; get contextId(): string | undefined { return this._contextId; } set contextId(value: string | undefined) { this._contextId = value; } get contextDisplayMode(): ContextDisplayMode { return this._contextDisplayMode; } set contextDisplayMode(value: ContextDisplayMode) { this._contextDisplayMode = value; } } export enum ContextDisplayMode { SHOW = "SHOW", HIDE = "HIDE" } ================================================ FILE: appformer-js/src/appformer/Panel.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Part } from "./Part"; import { DisplayInfo } from "./DisplayInfo"; export enum PanelType { MULTI_LIST = "org.uberfire.client.workbench.panels.impl.MultiListWorkbenchPanelPresenter", STATIC = "org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter" } export enum CompassPosition { NONE = "NONE", NORTH = "NORTH", SOUTH = "SOUTH", EAST = "EAST", WEST = "WEST", SELF = "SELF", ROOT = "ROOT", CENTER = "CENTER" } /** * Panel of a CompassLayoutPerspective */ export class Panel { private _position: CompassPosition; private _width: number = -1; private _minWidth: number = -1; private _height: number = -1; private _minHeight: number = -1; private _children: Panel[] = []; private _parts: Part[] = []; private _panelType: PanelType = PanelType.MULTI_LIST; private _displayInfo: DisplayInfo = new DisplayInfo(); constructor(position: CompassPosition) { this._position = position; } get position(): CompassPosition { return this._position; } set position(value: CompassPosition) { this._position = value; } get width(): number { return this._width; } set width(value: number) { this._width = value; } get minWidth(): number { return this._minWidth; } set minWidth(value: number) { this._minWidth = value; } get height(): number { return this._height; } set height(value: number) { this._height = value; } get minHeight(): number { return this._minHeight; } set minHeight(value: number) { this._minHeight = value; } get children(): Panel[] { return this._children; } set children(value: Panel[]) { this._children = value; } get parts(): Part[] { return this._parts; } set parts(value: Part[]) { this._parts = value; } get panelType(): PanelType { return this._panelType; } set panelType(value: PanelType) { this._panelType = value; } get displayInfo(): DisplayInfo { return this._displayInfo; } set displayInfo(value: DisplayInfo) { this._displayInfo = value; } } ================================================ FILE: appformer-js/src/appformer/Part.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { DisplayInfo } from "./DisplayInfo"; /** * Part of a CompassLayoutPerspective */ export class Part { private _placeName: string; private _displayInfo: DisplayInfo = new DisplayInfo(); private _parameters: {} = {}; constructor(placeName: string) { this._placeName = placeName; } get placeName(): string { return this._placeName; } set placeName(value: string) { this._placeName = value; } get displayInfo(): DisplayInfo { return this._displayInfo; } set displayInfo(value: DisplayInfo) { this._displayInfo = value; } get parameters(): {} { return this._parameters; } set parameters(value: {}) { this._parameters = value; } } ================================================ FILE: appformer-js/src/appformer/Perspective.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Component } from "./Component"; /** * Perspective component API. Implement this class to create a Perspective. */ export abstract class Perspective extends Component { public af_name: string; public af_perspectiveScreens: string[] = []; public af_isDefault: boolean = false; public af_isTransient: boolean = true; public af_isTemplated: boolean = true; protected constructor(componentId: string) { super({ type: "perspective", af_componentId: componentId }); } public af_onStartup(): void { // } public af_onOpen(): void { // } public af_onClose(): void { // } public af_onShutdown(): void { // } } ================================================ FILE: appformer-js/src/appformer/Screen.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Component } from "./Component"; /** * Screen component API. Implement this class to create a Screen. */ export abstract class Screen extends Component { public af_componentTitle?: string = undefined; public af_subscriptions: Map void)> = new Map(); protected constructor(componentId: string) { super({ type: "screen", af_componentId: componentId }); } public af_onStartup(): void { // } public af_onOpen(): void { // } public af_onFocus(): void { // } public af_onLostFocus(): void { // } public af_onMayClose(): boolean { return true; } public af_onClose(): void { // } public af_onShutdown(): void { // } } ================================================ FILE: appformer-js/src/appformer/index.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { AppFormer } from "./AppFormer"; import { Element } from "../core"; import { findChildContainers } from "../util"; import { Component } from "./Component"; import { Perspective } from "./Perspective"; import { Screen } from "./Screen"; import {marshall, Portable} from "../marshalling"; export * from "./AppFormer"; export * from "./Components"; export * from "./Screen"; export * from "./ComponentTypes"; export * from "./Perspective"; export * from "./CompassLayoutPerspective"; export * from "./DisplayInfo"; export * from "./Panel"; export * from "./Part"; let singleton: AppFormer | undefined; export function initSingleton() { const $wnd = window as any; if ($wnd.AppFormerMode !== "instance") { singleton = $wnd.appformerGwtBridge || new AppFormer().init((document.body.children[0] as HTMLElement) || document.createElement("div"), () => { // creating div element is used in test environment, when test runner do not have a page body to access console.info("AppFormer _standalone_ instance initialized."); }); $wnd.AppFormerInstance = singleton; } } // //Singleton API export function register(component: Component) { if (component.type === "screen") { singleton!.registerScreen(component as Screen); } else if (component.type === "perspective") { singleton!.registerPerspective(component as Perspective); } } export function goTo(af_componentId: string) { singleton!.goTo(af_componentId); } export function close(af_componentId: string) { singleton!.close(af_componentId); } export function translate(key: string, args: string[]) { return singleton!.translate(key, args); } export function render(element: Element, container: HTMLElement, callback = (): void => undefined) { singleton!.render(element, container, callback); } export function fireEvent(obj: Portable) { singleton!.fireEvent(marshall(obj) as any); } export function rpc(path: string, args: Array>) { return singleton!.rpc(path, args); } (window as any)._AppFormerUtils = { findChildContainers }; ================================================ FILE: appformer-js/src/core/Component.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; /** * Core component. Provides basic low-level lifecycle methods for AppFormer components. */ export abstract class Component { public readonly core_componentId: string; public readonly type: string; public readonly _container: HTMLElement; public readonly _components: string[] = []; public af_isReact: boolean = false; public af_hasContext: boolean = false; protected constructor(args: { type: string; core_componentId: string }) { this.core_componentId = args.core_componentId; this.type = args.type; } public abstract core_componentRoot(children?: any): Element; public core_onReady() { console.info(`core: ${this.core_componentId} is ready.`); } public core_onVanished() { console.info(`core: ${this.core_componentId} was removed.`); } } export type Element = React.ReactPortal | React.ReactElement | HTMLElement | string; ================================================ FILE: appformer-js/src/core/index.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export { Component, Element } from "./Component"; ================================================ FILE: appformer-js/src/index.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { initSingleton } from "./appformer"; export * from "./appformer"; export * from "./marshalling"; export * from "./core"; export * from "./java-wrappers"; export * from "./util"; // Exposes this module as a global variable (window as any).AppFormer = this; initSingleton(); ================================================ FILE: appformer-js/src/java-wrappers/BigNumberWrapper.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BigNumber } from "bignumber.js"; import { JavaWrapper } from "./JavaWrapper"; export abstract class BigNumberWrapper extends JavaWrapper { private _value: BigNumber; public constructor(value: string) { super(); const valueAsNumber = this.from(value); this.set(valueAsNumber); } public get(): BigNumber { return this._value; } public set(value: BigNumber | ((current: BigNumber) => BigNumber)): void { if (this.instanceOfBigNumber(value)) { this._value = this.applyNumericRange(value); } else { this._value = this.applyNumericRange(value(this.get())); } } protected abstract from(asString: string): BigNumber; protected abstract isInRange(n: BigNumber): boolean; private applyNumericRange(value: BigNumber) { if (!this.isInRange(value)) { return new BigNumber(NaN); } return value; } private instanceOfBigNumber(value: any): value is BigNumber { return BigNumber.isBigNumber(value); } } ================================================ FILE: appformer-js/src/java-wrappers/FloatBasedJavaNumber.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NumberWrapper } from "./NumberWrapper"; export abstract class FloatBasedJavaNumber extends NumberWrapper { protected from(asString: string): number { return Number.parseFloat(asString); } } ================================================ FILE: appformer-js/src/java-wrappers/IntegerBasedJavaNumber.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NumberWrapper } from "./NumberWrapper"; export abstract class IntegerBasedJavaNumber extends NumberWrapper { protected from(asString: string): number { return Number.parseInt(asString, 10); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaArrayList.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaCollection } from "./JavaCollection"; import { instanceOfArray } from "../util/TypeUtils"; import { JavaType } from "./JavaType"; export class JavaArrayList extends JavaCollection { private readonly _fqcn = JavaType.ARRAY_LIST; private _value: T[]; constructor(value: T[]) { super(); this.set(value); } public get(): T[] { return this._value; } public set(val: ((current: T[]) => T[]) | T[]): void { if (instanceOfArray(val)) { this._value = val; } else { this._value = val(this.get()); } } } ================================================ FILE: appformer-js/src/java-wrappers/JavaBigDecimal.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BigNumber } from "bignumber.js"; import { BigNumberWrapper } from "./BigNumberWrapper"; import { JavaByte } from "./JavaByte"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaDouble } from "./JavaDouble"; import { JavaFloat } from "./JavaFloat"; import { JavaInteger } from "./JavaInteger"; import { JavaShort } from "./JavaShort"; import { JavaLong } from "./JavaLong"; import { JavaType } from "./JavaType"; export class JavaBigDecimal extends BigNumberWrapper implements JavaNumber { private readonly _fqcn = JavaType.BIG_DECIMAL; public from(asString: string): BigNumber { return new BigNumber(asString, 10); } public isInRange(n: BigNumber): boolean { return true; // arbitrary precision } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaBigInteger.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BigNumber } from "bignumber.js"; import { BigNumberWrapper } from "./BigNumberWrapper"; import { JavaByte } from "./JavaByte"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaDouble } from "./JavaDouble"; import { JavaFloat } from "./JavaFloat"; import { JavaInteger } from "./JavaInteger"; import { JavaShort } from "./JavaShort"; import { JavaLong } from "./JavaLong"; import { JavaType } from "./JavaType"; export class JavaBigInteger extends BigNumberWrapper implements JavaNumber { private readonly _fqcn = JavaType.BIG_INTEGER; public from(asString: string): BigNumber { const bigNumber = new BigNumber(asString, 10); if (bigNumber.isInteger()) { return bigNumber; } // truncates decimal part (like TS's Number type) return bigNumber.integerValue(BigNumber.ROUND_DOWN); } protected isInRange(n: BigNumber): boolean { return true; // arbitrary precision } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaBoolean.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; import { instanceOfBoolean } from "../util/TypeUtils"; import { JavaType } from "./JavaType"; export class JavaBoolean extends JavaWrapper { private readonly _fqcn = JavaType.BOOLEAN; private _value: boolean; constructor(value: boolean) { super(); this.set(value); } public get(): boolean { return this._value; } public set(val: ((current: boolean) => boolean) | boolean): void { if (instanceOfBoolean(val)) { this._value = val; } else { this._value = val(this.get()); } } } ================================================ FILE: appformer-js/src/java-wrappers/JavaByte.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { IntegerBasedJavaNumber } from "./IntegerBasedJavaNumber"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaDouble } from "./JavaDouble"; import { JavaFloat } from "./JavaFloat"; import { JavaInteger } from "./JavaInteger"; import { JavaShort } from "./JavaShort"; import { JavaLong } from "./JavaLong"; import { JavaType } from "./JavaType"; export class JavaByte extends IntegerBasedJavaNumber implements JavaNumber { public static readonly MIN_VALUE = -128; public static readonly MAX_VALUE = 127; private readonly _fqcn = JavaType.BYTE; protected isInRange(n: number): boolean { return n >= JavaByte.MIN_VALUE && n <= JavaByte.MAX_VALUE; } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaCollection.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; export abstract class JavaCollection | null> extends JavaWrapper { // this is here for type purposes only } ================================================ FILE: appformer-js/src/java-wrappers/JavaDate.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; import { instanceOfDate } from "../util/TypeUtils"; import { JavaType } from "./JavaType"; export class JavaDate extends JavaWrapper { private readonly _fqcn = JavaType.DATE; private _value: Date; constructor(date: Date) { super(); this.set(date); } public get(): Date { return this._value; } public set(val: ((current: Date) => Date) | Date): void { if (instanceOfDate(val)) { this._value = val; } else { this._value = val(this.get()); } } } ================================================ FILE: appformer-js/src/java-wrappers/JavaDouble.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { FloatBasedJavaNumber } from "./FloatBasedJavaNumber"; import { JavaByte } from "./JavaByte"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaFloat } from "./JavaFloat"; import { JavaInteger } from "./JavaInteger"; import { JavaShort } from "./JavaShort"; import { JavaLong } from "./JavaLong"; import { JavaType } from "./JavaType"; export class JavaDouble extends FloatBasedJavaNumber implements JavaNumber { private readonly _fqcn = JavaType.DOUBLE; protected isInRange(n: number): boolean { // JS' numbers are 64 bits long like Java's Double return n >= -1 * Number.MAX_VALUE && n <= Number.MAX_VALUE; } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaEnum.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Portable } from "../marshalling"; export abstract class JavaEnum> implements Portable { public readonly name: string; protected constructor(name: string) { this.name = name; } } ================================================ FILE: appformer-js/src/java-wrappers/JavaFloat.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { FloatBasedJavaNumber } from "./FloatBasedJavaNumber"; import { JavaByte } from "./JavaByte"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaDouble } from "./JavaDouble"; import { JavaInteger } from "./JavaInteger"; import { JavaShort } from "./JavaShort"; import { JavaLong } from "./JavaLong"; import { JavaType } from "./JavaType"; export class JavaFloat extends FloatBasedJavaNumber implements JavaNumber { public static readonly MIN_VALUE = -3.40282347e38; public static readonly MAX_VALUE = 3.40282347e38; private readonly _fqcn = JavaType.FLOAT; protected isInRange(n: number): boolean { return n >= JavaFloat.MIN_VALUE && n <= JavaFloat.MAX_VALUE; } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaHashMap.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; import { instanceOfMap } from "../util/TypeUtils"; import { JavaType } from "./JavaType"; export class JavaHashMap extends JavaWrapper> { private readonly _fqcn = JavaType.HASH_MAP; private _value: Map; constructor(value: Map) { super(); this.set(value); } public get(): Map { return this._value; } public set(val: ((current: Map) => Map) | Map): void { if (instanceOfMap(val)) { this._value = val; } else { this._value = val(this.get()); } } } ================================================ FILE: appformer-js/src/java-wrappers/JavaHashSet.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaCollection } from "./JavaCollection"; import { instanceOfSet } from "../util/TypeUtils"; import { JavaType } from "./JavaType"; export class JavaHashSet extends JavaCollection> { private readonly _fqcn = JavaType.HASH_SET; private _value: Set; constructor(value: Set) { super(); this.set(value); } public get(): Set { return this._value; } public set(val: ((current: Set) => Set) | Set): void { if (instanceOfSet(val)) { this._value = val; } else { this._value = val(this.get()); } } } ================================================ FILE: appformer-js/src/java-wrappers/JavaInteger.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { IntegerBasedJavaNumber } from "./IntegerBasedJavaNumber"; import { JavaByte } from "./JavaByte"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaDouble } from "./JavaDouble"; import { JavaFloat } from "./JavaFloat"; import { JavaShort } from "./JavaShort"; import { JavaLong } from "./JavaLong"; import { JavaType } from "./JavaType"; export class JavaInteger extends IntegerBasedJavaNumber implements JavaNumber { public static readonly MIN_VALUE = -21474836488; public static readonly MAX_VALUE = 2147483647; private readonly _fqcn = JavaType.INTEGER; protected isInRange(n: number): boolean { return n >= JavaInteger.MIN_VALUE && n <= JavaInteger.MAX_VALUE; } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaLinkedList.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export class JavaLinkedList {} ================================================ FILE: appformer-js/src/java-wrappers/JavaLong.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BigNumber } from "bignumber.js"; import { BigNumberWrapper } from "./BigNumberWrapper"; import { JavaByte } from "./JavaByte"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaDouble } from "./JavaDouble"; import { JavaFloat } from "./JavaFloat"; import { JavaInteger } from "./JavaInteger"; import { JavaShort } from "./JavaShort"; import { JavaType } from "./JavaType"; export class JavaLong extends BigNumberWrapper implements JavaNumber { public static readonly MIN_VALUE = new BigNumber("-9223372036854775808", 10); public static readonly MAX_VALUE = new BigNumber("9223372036854775807", 10); private readonly _fqcn = JavaType.LONG; public from(asString: string): BigNumber { // simulate Java's Long number range const BN = BigNumber.clone({ RANGE: 18, DECIMAL_PLACES: 0 }); // forces integer value (the decimal places configuration are only applied when performing a division) // Also, truncates the decimal part the same way of Number type return new BN(asString).integerValue(BigNumber.ROUND_DOWN); } protected isInRange(n: BigNumber): boolean { return n.isGreaterThanOrEqualTo(JavaLong.MIN_VALUE) && n.isLessThanOrEqualTo(JavaLong.MAX_VALUE); } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaNumber.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaDouble } from "./JavaDouble"; import { JavaInteger } from "./JavaInteger"; import { JavaShort } from "./JavaShort"; import { JavaByte } from "./JavaByte"; import { JavaFloat } from "./JavaFloat"; import { BigNumber } from "bignumber.js"; import { JavaLong } from "./JavaLong"; export interface JavaNumber { doubleValue(): JavaDouble; intValue(): JavaInteger; shortValue(): JavaShort; byteValue(): JavaByte; floatValue(): JavaFloat; longValue(): JavaLong; } export function asDouble(n: number | BigNumber) { return new JavaDouble(n.toString(10)); } export function asInteger(n: number | BigNumber) { return new JavaInteger(n.toString(10)); } export function asShort(n: number | BigNumber) { return new JavaShort(n.toString(10)); } export function asByte(n: number | BigNumber) { return new JavaByte(n.toString(10)); } export function asFloat(n: number | BigNumber) { return new JavaFloat(n.toString(10)); } export function asLong(n: number | BigNumber) { return new JavaLong(n.toString(10)); } ================================================ FILE: appformer-js/src/java-wrappers/JavaOptional.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; import { JavaType } from "./JavaType"; export class JavaOptional extends JavaWrapper { private readonly _fqcn = JavaType.OPTIONAL; private _value: T | undefined; constructor(value?: T) { super(); this.set(value); } public get(): T { if (this._value === null || this._value === undefined) { throw new Error("No value present"); } return this._value!; } public isPresent(): boolean { return this._value !== undefined; } public set(val: ((current: T | undefined) => T | undefined) | T | undefined): void { if (typeof val === "function") { this._value = val(this.get()); } else { this._value = val; } } } ================================================ FILE: appformer-js/src/java-wrappers/JavaShort.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { IntegerBasedJavaNumber } from "./IntegerBasedJavaNumber"; import { asByte, asDouble, asFloat, asInteger, asLong, asShort, JavaNumber } from "./JavaNumber"; import { JavaByte } from "./JavaByte"; import { JavaDouble } from "./JavaDouble"; import { JavaFloat } from "./JavaFloat"; import { JavaInteger } from "./JavaInteger"; import { JavaLong } from "./JavaLong"; import { JavaType } from "./JavaType"; export class JavaShort extends IntegerBasedJavaNumber implements JavaNumber { public static readonly MIN_VALUE = -32768; public static readonly MAX_VALUE = 32767; private readonly _fqcn = JavaType.SHORT; protected isInRange(n: number): boolean { return n >= JavaShort.MIN_VALUE && n <= JavaShort.MAX_VALUE; } public byteValue(): JavaByte { return asByte(super.get()); } public doubleValue(): JavaDouble { return asDouble(super.get()); } public floatValue(): JavaFloat { return asFloat(super.get()); } public intValue(): JavaInteger { return asInteger(super.get()); } public shortValue(): JavaShort { return asShort(super.get()); } public longValue(): JavaLong { return asLong(super.get()); } } ================================================ FILE: appformer-js/src/java-wrappers/JavaString.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; import { instanceOfString } from "../util/TypeUtils"; import { JavaType } from "./JavaType"; export class JavaString extends JavaWrapper { private readonly _fqcn = JavaType.STRING; private _value: string; constructor(value: string) { super(); this.set(value); } public get(): string { return this._value; } public set(val: ((current: string) => string) | string): void { if (instanceOfString(val)) { this._value = val; } else { this._value = val(this.get()); } } } ================================================ FILE: appformer-js/src/java-wrappers/JavaTreeMap.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export class JavaTreeMap {} ================================================ FILE: appformer-js/src/java-wrappers/JavaTreeSet.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export class JavaTreeSet {} ================================================ FILE: appformer-js/src/java-wrappers/JavaType.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export enum JavaType { BYTE = "java.lang.Byte", DOUBLE = "java.lang.Double", FLOAT = "java.lang.Float", INTEGER = "java.lang.Integer", LONG = "java.lang.Long", SHORT = "java.lang.Short", BOOLEAN = "java.lang.Boolean", STRING = "java.lang.String", DATE = "java.util.Date", BIG_DECIMAL = "java.math.BigDecimal", BIG_INTEGER = "java.math.BigInteger", ARRAY_LIST = "java.util.ArrayList", UNMODIFIABLE_COLLECTION = "java.util.Collections$UnmodifiableCollection", UNMODIFIABLE_SET = "java.util.Collections$UnmodifiableSet", UNMODIFIABLE_MAP = "java.util.Collections$UnmodifiableMap", HASH_SET = "java.util.HashSet", HASH_MAP = "java.util.HashMap", OPTIONAL = "java.util.Optional", ENUM = "java.lang.Enum" } ================================================ FILE: appformer-js/src/java-wrappers/JavaWrapper.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Portable } from "../marshalling/Portable"; export abstract class JavaWrapper implements Portable> { private static readonly javaWrapperInstanceIdentifier = "fbeef485-6129-4c23-a047-166c6d2fb7a9"; public abstract get(): T; public abstract set(val: T | ((current: T) => T)): void; private instanceIdentifier(): string { return JavaWrapper.javaWrapperInstanceIdentifier; } public static extendsJavaWrapper(obj: any): obj is JavaWrapper { if (!obj.instanceIdentifier) { return false; } // this is just a trick to allow the application to identify in runtime if an object extends JavaWrapper. return obj.instanceIdentifier() === JavaWrapper.javaWrapperInstanceIdentifier; } } ================================================ FILE: appformer-js/src/java-wrappers/JavaWrapperUtils.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; import { JavaType } from "./JavaType"; import { isArray, isBoolean, isDate, isMap, isSet, isString } from "../util/TypeUtils"; import { JavaArrayList } from "./JavaArrayList"; import { JavaHashSet } from "./JavaHashSet"; import { JavaHashMap } from "./JavaHashMap"; import { JavaBoolean } from "./JavaBoolean"; import { JavaString } from "./JavaString"; import { JavaDate } from "./JavaDate"; import { JavaEnum } from "./JavaEnum"; export class JavaWrapperUtils { private static wrappingFuncForType: Map<(obj: any) => boolean, (obj: any) => JavaWrapper> = new Map([ [isArray, (obj: any) => new JavaArrayList(obj) as JavaWrapper], [isSet, (obj: any) => new JavaHashSet(obj) as JavaWrapper], [isMap, (obj: any) => new JavaHashMap(obj) as JavaWrapper], [isBoolean, (obj: any) => new JavaBoolean(obj) as JavaWrapper], [isString, (obj: any) => new JavaString(obj) as JavaWrapper], [isDate, (obj: any) => new JavaDate(obj) as JavaWrapper] ]); public static needsWrapping(obj: any): boolean { return this.getWrappingFunction(obj) !== undefined; } public static wrapIfNeeded(obj: U): JavaWrapper | U { const func = this.getWrappingFunction(obj); if (!func) { return obj; } return func(obj); } public static isJavaType(fqcn: string): boolean { for (const type in JavaType) { if (JavaType[type] === fqcn) { return true; } } return false; } public static isEnum(obj: any): boolean { return obj instanceof JavaEnum; } private static getWrappingFunction(obj: any): ((obj: any) => JavaWrapper) | undefined { //tslint:disable-next-line let result: ((obj: any) => JavaWrapper) | undefined = undefined; this.wrappingFuncForType.forEach((wrapFunction, typeFilterFunction) => { if (result) { return; } if (typeFilterFunction(obj)) { result = wrapFunction; } }); return result; } } ================================================ FILE: appformer-js/src/java-wrappers/NumberWrapper.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "./JavaWrapper"; export abstract class NumberWrapper extends JavaWrapper { private _value: number; public constructor(value: string) { super(); const valueAsNumber = this.from(value); this.set(valueAsNumber); } public get(): number { return this._value; } public set(value: number | ((current: number) => number)): void { if (typeof value === "number") { this._value = this.applyNumericRange(value); } else { this._value = this.applyNumericRange(value(this.get())); } } protected abstract from(asString: string): number; protected abstract isInRange(n: number): boolean; private applyNumericRange(n: number): number { if (!this.isInRange(n)) { return Number.NaN; } return n; } } ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaArrayList.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaArrayList } from "../JavaArrayList"; import { JavaType } from "../JavaType"; describe("get", () => { test("with populated array, returns the same array", () => { const input = ["foo", "bar", "foo2"]; const output = new JavaArrayList(input).get(); expect(output).toEqual(["foo", "bar", "foo2"]); }); test("with empty array, returns the same array", () => { const input = [] as any[]; const output = new JavaArrayList(input).get(); expect(output).toEqual([]); }); }); describe("set", () => { test("with direct value, should set", () => { const input = new JavaArrayList(["foo", "bar"]); expect(input.get()).toStrictEqual(["foo", "bar"]); input.set(["foo"]); expect(input.get()).toStrictEqual(["foo"]); }); test("with value from function, should set", () => { const input = new JavaArrayList(["foo", "bar"]); expect(input.get()).toStrictEqual(["foo", "bar"]); input.set(curr => { const newArr = new Array(...curr); newArr.push("newfoo"); return newArr; }); expect(input.get()).toStrictEqual(["foo", "bar", "newfoo"]); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaArrayList(["1", "2"]) as any)._fqcn; expect(fqcn).toBe(JavaType.ARRAY_LIST); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaBigDecimal.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaBigDecimal } from "../JavaBigDecimal"; import { BigNumber } from "bignumber.js"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive float, should return same value as BigNumber", () => { const input = "12.92"; const output = new JavaBigDecimal(input).get(); expect(output).toEqual(new BigNumber("12.92")); }); test("negative float, should return same value as BigNumber", () => { const input = "-12.92"; const output = new JavaBigDecimal(input).get(); expect(output).toEqual(new BigNumber("-12.92")); }); test("positive integer, should return same value as BigNumber", () => { const input = "12"; const output = new JavaBigDecimal(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("negative integer, should return same value as BigNumber", () => { const input = "-12"; const output = new JavaBigDecimal(input).get(); expect(output).toEqual(new BigNumber("-12")); }); }); test("with invalid textual string, should return NaN", () => { const input = "abc"; const output = new JavaBigDecimal(input).get(); expect(output).toEqual(new BigNumber(NaN)); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as BigNumber", () => { const input = new BigNumber(-Number.MAX_VALUE); const output = new JavaBigDecimal(input.toString(10)).get(); expect(output).toEqual(new BigNumber(-Number.MAX_VALUE)); }); test("less than, should return same value as BigNumber", () => { const input = new BigNumber(-Number.MAX_VALUE).minus(1, 10); const output = new JavaBigDecimal(input.toString(10)).get(); expect(output).toEqual(new BigNumber(-Number.MAX_VALUE).minus(1, 10)); }); }); describe("maximum bound", () => { test("equals, should return same value as BigNumber", () => { const input = new BigNumber(Number.MAX_VALUE); const output = new JavaBigDecimal(input.toString(10)).get(); expect(output).toEqual(new BigNumber(Number.MAX_VALUE)); }); test("greater than, should return same value as BigNumber", () => { const input = new BigNumber(Number.MAX_VALUE).plus(1, 10); const output = new JavaBigDecimal(input.toString(10)).get(); expect(output).toEqual(new BigNumber(Number.MAX_VALUE).plus(1, 10)); }); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaBigDecimal("1.2"); expect(input.get()).toEqual(new BigNumber("1.2")); input.set(new BigNumber("2.2")); expect(input.get()).toEqual(new BigNumber("2.2")); }); test("with invalid direct value, should set NaN", () => { const input = new JavaBigDecimal("1.2"); expect(input.get()).toEqual(new BigNumber("1.2")); input.set(new BigNumber(NaN)); expect(input.get()).toEqual(new BigNumber(NaN)); }); test("with valid value from function, should set", () => { const input = new JavaBigDecimal("1.2"); expect(input.get()).toEqual(new BigNumber("1.2")); input.set(cur => new BigNumber("2.2").plus(cur)); expect(input.get()).toEqual(new BigNumber("3.4")); }); test("with invalid value from function, should set NaN", () => { const input = new JavaBigDecimal("1.2"); expect(input.get()).toEqual(new BigNumber("1.2")); input.set(cur => new BigNumber(NaN).plus(cur)); expect(input.get()).toEqual(new BigNumber(NaN)); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaBigDecimal("1.2"); const output = input.doubleValue(); expect(output.get()).toBe(1.2); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaBigDecimal("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaBigDecimal("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaBigDecimal("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaBigDecimal("1.1"); const output = input.floatValue(); expect(output.get()).toBe(1.1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaBigDecimal("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaBigDecimal("1") as any)._fqcn; expect(fqcn).toBe(JavaType.BIG_DECIMAL); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaBigInteger.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BigNumber } from "bignumber.js"; import { JavaBigInteger } from "../JavaBigInteger"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive integer, should return same value as BigNumber", () => { const input = "12"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("negative integer, should return same value as BigNumber", () => { const input = "-12"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("-12")); }); }); test("with invalid textual string, should return NaN", () => { const input = "abc"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber(NaN)); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as BigNumber", () => { const input = new BigNumber(-Number.MAX_VALUE); const output = new JavaBigInteger(input.toString(10)).get(); expect(output).toEqual(new BigNumber(-Number.MAX_VALUE)); }); test("less than, should return same value as BigNumber", () => { const input = new BigNumber(-Number.MAX_VALUE).minus(1, 10); const output = new JavaBigInteger(input.toString(10)).get(); expect(output).toEqual(new BigNumber(-Number.MAX_VALUE).minus(1, 10)); }); }); describe("maximum bound", () => { test("equals, should return same value as BigNumber", () => { const input = new BigNumber(Number.MAX_VALUE); const output = new JavaBigInteger(input.toString(10)).get(); expect(output).toEqual(new BigNumber(Number.MAX_VALUE)); }); test("greater than, should return same value as BigNumber", () => { const input = new BigNumber(Number.MAX_VALUE).plus(1, 10); const output = new JavaBigInteger(input.toString(10)).get(); expect(output).toEqual(new BigNumber(Number.MAX_VALUE).plus(1, 10)); }); }); }); describe("with float string", () => { test("positive with decimal closest to 0, should return truncated value as BigNumber", () => { const input = "12.1"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("positive with decimal exactly between 0 and 1, should return truncated value as BigNumber", () => { const input = "12.5"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("positive with decimal closest to 1, should return truncated value as BigNumber", () => { const input = "12.9"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("negative with decimal closest to 0, should return truncated value as BigNumber", () => { const input = "-12.1"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("-12")); }); test("negative with decimal exactly between 0 and 1, should return truncated value as BigNumber", () => { const input = "-12.5"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("-12")); }); test("negative with decimal closest to 1, should return truncated value as BigNumber", () => { const input = "-12.9"; const output = new JavaBigInteger(input).get(); expect(output).toEqual(new BigNumber("-12")); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaBigInteger("1"); expect(input.get()).toEqual(new BigNumber("1")); input.set(new BigNumber("2")); expect(input.get()).toEqual(new BigNumber("2")); }); test("with invalid direct value, should set NaN", () => { const input = new JavaBigInteger("1"); expect(input.get()).toEqual(new BigNumber("1")); input.set(new BigNumber(NaN)); expect(input.get()).toEqual(new BigNumber(NaN)); }); test("with valid value from function, should set", () => { const input = new JavaBigInteger("1"); expect(input.get()).toEqual(new BigNumber("1")); input.set(cur => new BigNumber("2").plus(cur)); expect(input.get()).toEqual(new BigNumber("3")); }); test("with invalid value from function, should set NaN", () => { const input = new JavaBigInteger("1"); expect(input.get()).toEqual(new BigNumber("1")); input.set(cur => new BigNumber(NaN).plus(cur)); expect(input.get()).toEqual(new BigNumber(NaN)); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaBigInteger("1"); const output = input.doubleValue(); expect(output.get()).toBe(1); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaBigInteger("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaBigInteger("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaBigInteger("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaBigInteger("1"); const output = input.floatValue(); expect(output.get()).toBe(1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaBigInteger("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaBigInteger("1") as any)._fqcn; expect(fqcn).toBe(JavaType.BIG_INTEGER); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaBoolean.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaBoolean } from "../JavaBoolean"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("true, should return boolean true", () => { const input = true; const output = new JavaBoolean(input).get(); expect(output).toBeTruthy(); }); test("false, should return boolean false", () => { const input = false; const output = new JavaBoolean(input).get(); expect(output).toBeFalsy(); }); }); }); describe("set", () => { test("with direct value, should set", () => { const input = new JavaBoolean(false); expect(input.get()).toBeFalsy(); input.set(true); expect(input.get()).toBeTruthy(); }); test("with value from function, should set", () => { const input = new JavaBoolean(false); expect(input.get()).toBeFalsy(); input.set(cur => !cur); expect(input.get()).toBeTruthy(); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaBoolean(true) as any)._fqcn; expect(fqcn).toBe(JavaType.BOOLEAN); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaByte.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaByte } from "../JavaByte"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive integer, should return same value as number", () => { const input = "12"; const output = new JavaByte(input).get(); expect(output).toEqual(12); }); test("negative integer, should return same value as number", () => { const input = "-12"; const output = new JavaByte(input).get(); expect(output).toEqual(-12); }); }); test("with invalid textual string, should return NaN", () => { const input = "abc"; const output = new JavaByte(input).get(); expect(output).toBeNaN(); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaByte.MIN_VALUE}`; const output = new JavaByte(input).get(); expect(output).toEqual(JavaByte.MIN_VALUE); }); test("less than, should return NaN", () => { const input = `${JavaByte.MIN_VALUE - 1}`; const output = new JavaByte(input).get(); expect(output).toEqual(NaN); }); }); describe("maximum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaByte.MAX_VALUE}`; const output = new JavaByte(input).get(); expect(output).toEqual(JavaByte.MAX_VALUE); }); test("greater than, should return NaN", () => { const input = `${JavaByte.MAX_VALUE + 1}`; const output = new JavaByte(input).get(); expect(output).toEqual(NaN); }); }); }); describe("with float string", () => { test("positive with decimal closest to 0, should return truncated value as Number", () => { const input = "12.1"; const output = new JavaByte(input).get(); expect(output).toEqual(12); }); test("positive with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "12.5"; const output = new JavaByte(input).get(); expect(output).toEqual(12); }); test("positive with decimal closest to 1, should return truncated value as Number", () => { const input = "12.9"; const output = new JavaByte(input).get(); expect(output).toEqual(12); }); test("negative with decimal closest to 0, should return truncated value as Number", () => { const input = "-12.1"; const output = new JavaByte(input).get(); expect(output).toEqual(-12); }); test("negative with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "-12.5"; const output = new JavaByte(input).get(); expect(output).toEqual(-12); }); test("negative with decimal closest to 1, should return truncated value as Number", () => { const input = "-12.9"; const output = new JavaByte(input).get(); expect(output).toEqual(-12); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaByte("1"); expect(input.get()).toEqual(1); input.set(2); expect(input.get()).toEqual(2); }); test("with invalid direct value, should set NaN", () => { const input = new JavaByte("1"); expect(input.get()).toEqual(1); input.set(JavaByte.MAX_VALUE + 1); expect(input.get()).toEqual(NaN); }); test("with valid value from function, should set", () => { const input = new JavaByte("1"); expect(input.get()).toEqual(1); input.set(cur => 2 + cur); expect(input.get()).toEqual(3); }); test("with invalid value from function, should set NaN", () => { const input = new JavaByte("1"); expect(input.get()).toEqual(1); input.set(cur => JavaByte.MAX_VALUE + cur); expect(input.get()).toEqual(NaN); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaByte("1"); const output = input.doubleValue(); expect(output.get()).toBe(1); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaByte("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaByte("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaByte("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaByte("1"); const output = input.floatValue(); expect(output.get()).toBe(1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaByte("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaByte("1") as any)._fqcn; expect(fqcn).toBe(JavaType.BYTE); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaDate.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaDate } from "../JavaDate"; import { JavaType } from "../JavaType"; describe("get", () => { test("with date, should return same value as Date", () => { const input = new Date(); const output = new JavaDate(input).get(); expect(output).toEqual(input); }); }); describe("set", () => { test("with direct value, should set", () => { const firstDate = new Date(); const input = new JavaDate(firstDate); expect(input.get()).toEqual(firstDate); const secondDate = new Date(); input.set(secondDate); expect(input.get()).toEqual(secondDate); }); test("with value from function, should set", () => { const firstDate = new Date(); const input = new JavaDate(firstDate); expect(input.get()).toEqual(firstDate); input.set(cur => { const newDate = new Date(cur.getUTCMilliseconds()); newDate.setHours(cur.getHours() + 1); return newDate; }); const expectedDate = new Date(firstDate.getUTCMilliseconds()); expectedDate.setHours(firstDate.getHours() + 1); expect(input.get()).toEqual(expectedDate); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaDate(new Date()) as any)._fqcn; expect(fqcn).toBe(JavaType.DATE); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaDouble.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaDouble } from "../JavaDouble"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive float, should return same value as number", () => { const input = "12.24"; const output = new JavaDouble(input).get(); expect(output).toEqual(12.24); }); test("negative float, should return same value as number", () => { const input = "-12.24"; const output = new JavaDouble(input).get(); expect(output).toEqual(-12.24); }); test("positive integer, should return same value as number", () => { const input = "12"; const output = new JavaDouble(input).get(); expect(output).toEqual(12); }); test("negative integer, should return same value as number", () => { const input = "-12"; const output = new JavaDouble(input).get(); expect(output).toEqual(-12); }); }); test("with invalid input string, should return NaN", () => { const input = "abc"; const output = new JavaDouble(input).get(); expect(output).toBeNaN(); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as Number", () => { const input = `${-Number.MAX_VALUE}`; const output = new JavaDouble(input).get(); expect(output).toEqual(-Number.MAX_VALUE); }); test("less than, should return same value as Number", () => { const input = `${-Number.MAX_VALUE - 1}`; const output = new JavaDouble(input).get(); expect(output).toEqual(-Number.MAX_VALUE - 1); }); }); describe("maximum bound", () => { test("equals, should return same value as Number", () => { const input = `${Number.MAX_VALUE}`; const output = new JavaDouble(input).get(); expect(output).toEqual(Number.MAX_VALUE); }); test("greater than, should return same value as Number", () => { const input = `${Number.MAX_VALUE + 1}`; const output = new JavaDouble(input).get(); expect(output).toEqual(Number.MAX_VALUE + 1); }); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaDouble("1"); expect(input.get()).toEqual(1); input.set(2); expect(input.get()).toEqual(2); }); test("with invalid direct value, should set NaN", () => { const input = new JavaDouble("1"); expect(input.get()).toEqual(1); input.set(Number.MAX_VALUE * 2); expect(input.get()).toEqual(NaN); }); test("with valid value from function, should set", () => { const input = new JavaDouble("1"); expect(input.get()).toEqual(1); input.set(cur => 2 + cur); expect(input.get()).toEqual(3); }); test("with invalid value from function, should set NaN", () => { const input = new JavaDouble("2"); expect(input.get()).toEqual(2); input.set(cur => Number.MAX_VALUE * cur); expect(input.get()).toEqual(NaN); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaDouble("1.1"); const output = input.doubleValue(); expect(output.get()).toBe(1.1); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaDouble("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaDouble("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaDouble("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaDouble("1.1"); const output = input.floatValue(); expect(output.get()).toBe(1.1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaDouble("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaDouble("1") as any)._fqcn; expect(fqcn).toBe(JavaType.DOUBLE); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaFloat.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaFloat } from "../JavaFloat"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive float, should return same value as BigNumber", () => { const input = "12.92"; const output = new JavaFloat(input).get(); expect(output).toEqual(12.92); }); test("negative float, should return same value as BigNumber", () => { const input = "-12.92"; const output = new JavaFloat(input).get(); expect(output).toEqual(-12.92); }); test("positive integer, should return same value as BigNumber", () => { const input = "12"; const output = new JavaFloat(input).get(); expect(output).toEqual(12); }); test("negative integer, should return same value as BigNumber", () => { const input = "-12"; const output = new JavaFloat(input).get(); expect(output).toEqual(-12); }); }); test("with invalid textual string, should return NaN", () => { const input = "abc"; const output = new JavaFloat(input).get(); expect(output).toBeNaN(); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as BigNumber", () => { const input = `${JavaFloat.MIN_VALUE}`; const output = new JavaFloat(input).get(); expect(output).toEqual(JavaFloat.MIN_VALUE); }); test("less than, should return NaN", () => { const input = `${JavaFloat.MIN_VALUE - 1e23}`; // smaller value inside float's precision const output = new JavaFloat(input).get(); expect(output).toBeNaN(); }); }); describe("maximum bound", () => { test("equals, should return same value as BigNumber", () => { const input = `${JavaFloat.MAX_VALUE}`; const output = new JavaFloat(input).get(); expect(output).toEqual(JavaFloat.MAX_VALUE); }); test("greater than, should return same value as BigNumber", () => { const input = `${JavaFloat.MAX_VALUE + 1e23}`; // smaller value inside float's precision const output = new JavaFloat(input).get(); expect(output).toEqual(NaN); }); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaFloat("1"); expect(input.get()).toEqual(1); input.set(2); expect(input.get()).toEqual(2); }); test("with invalid direct value, should set NaN", () => { const input = new JavaFloat("1"); expect(input.get()).toEqual(1); input.set(JavaFloat.MAX_VALUE * 2); expect(input.get()).toEqual(NaN); }); test("with valid value from function, should set", () => { const input = new JavaFloat("1"); expect(input.get()).toEqual(1); input.set(cur => 2 + cur); expect(input.get()).toEqual(3); }); test("with invalid value from function, should set NaN", () => { const input = new JavaFloat("2"); expect(input.get()).toEqual(2); input.set(cur => JavaFloat.MAX_VALUE * cur); expect(input.get()).toEqual(NaN); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaFloat("1.1"); const output = input.doubleValue(); expect(output.get()).toBe(1.1); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaFloat("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaFloat("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaFloat("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaFloat("1.1"); const output = input.floatValue(); expect(output.get()).toBe(1.1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaFloat("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaFloat("1") as any)._fqcn; expect(fqcn).toBe(JavaType.FLOAT); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaHashMap.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaHashMap } from "../JavaHashMap"; import { JavaType } from "../JavaType"; describe("get", () => { test("with populated map, returns the same map", () => { const input = new Map([["foo1", "bar1"], ["foo2", "bar2"]]); const output = new JavaHashMap(input).get(); expect(output).toEqual(new Map([["foo1", "bar1"], ["foo2", "bar2"]])); }); test("with empty map, returns the same map", () => { const input = new Map(); const output = new JavaHashMap(input).get(); expect(output).toEqual(new Map()); }); }); describe("set", () => { test("with direct value, should set", () => { const input = new JavaHashMap(new Map([["k1", "v1"]])); expect(input.get()).toEqual(new Map([["k1", "v1"]])); input.set(new Map([["k2", "v2"]])); expect(input.get()).toEqual(new Map([["k2", "v2"]])); }); test("with value from function, should set", () => { const input = new JavaHashMap(new Map([["k1", "v1"]])); expect(input.get()).toEqual(new Map([["k1", "v1"]])); input.set(cur => { const newMap = new Map(cur); newMap.set("k2", "v2"); return newMap; }); expect(input.get()).toEqual(new Map([["k1", "v1"], ["k2", "v2"]])); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaHashMap(new Map([["foo1", "bar1"]])) as any)._fqcn; expect(fqcn).toBe(JavaType.HASH_MAP); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaHashSet.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaHashSet } from "../JavaHashSet"; import { JavaType } from "../JavaType"; describe("get", () => { test("with populated set, returns the same set", () => { const input = new Set(["foo", "bar", "foo2"]); const output = new JavaHashSet(input).get(); expect(output).toEqual(new Set(["foo", "bar", "foo2"])); }); test("with empty set, returns the same set", () => { const input = new Set(); const output = new JavaHashSet(input).get(); expect(output).toEqual(new Set()); }); }); describe("set", () => { test("with direct value, should set", () => { const input = new JavaHashSet(new Set(["k1", "v1"])); expect(input.get()).toEqual(new Set(["k1", "v1"])); input.set(new Set(["k2", "v2"])); expect(input.get()).toEqual(new Set(["k2", "v2"])); }); test("with value from function, should set", () => { const input = new JavaHashSet(new Set(["k1", "v1"])); expect(input.get()).toEqual(new Set(["k1", "v1"])); input.set(cur => { const newSet = new Set(cur); newSet.add("k2"); return newSet; }); expect(input.get()).toEqual(new Set(["k1", "v1", "k2"])); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaHashSet(new Set(["1", "2"])) as any)._fqcn; expect(fqcn).toBe(JavaType.HASH_SET); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaInteger.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaInteger } from "../JavaInteger"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive integer, should return same value as number", () => { const input = "12"; const output = new JavaInteger(input).get(); expect(output).toEqual(12); }); test("negative integer, should return same value as number", () => { const input = "-12"; const output = new JavaInteger(input).get(); expect(output).toEqual(-12); }); }); test("with invalid textual string, should return NaN", () => { const input = "abc"; const output = new JavaInteger(input).get(); expect(output).toBeNaN(); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaInteger.MIN_VALUE}`; const output = new JavaInteger(input).get(); expect(output).toEqual(JavaInteger.MIN_VALUE); }); test("less than, should return NaN", () => { const input = `${JavaInteger.MIN_VALUE - 1}`; const output = new JavaInteger(input).get(); expect(output).toEqual(NaN); }); }); describe("maximum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaInteger.MAX_VALUE}`; const output = new JavaInteger(input).get(); expect(output).toEqual(JavaInteger.MAX_VALUE); }); test("greater than, should return NaN", () => { const input = `${JavaInteger.MAX_VALUE + 1}`; const output = new JavaInteger(input).get(); expect(output).toEqual(NaN); }); }); }); describe("with float string", () => { test("positive with decimal closest to 0, should return truncated value as Number", () => { const input = "12.1"; const output = new JavaInteger(input).get(); expect(output).toEqual(12); }); test("positive with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "12.5"; const output = new JavaInteger(input).get(); expect(output).toEqual(12); }); test("positive with decimal closest to 1, should return truncated value as Number", () => { const input = "12.9"; const output = new JavaInteger(input).get(); expect(output).toEqual(12); }); test("negative with decimal closest to 0, should return truncated value as Number", () => { const input = "-12.1"; const output = new JavaInteger(input).get(); expect(output).toEqual(-12); }); test("negative with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "-12.5"; const output = new JavaInteger(input).get(); expect(output).toEqual(-12); }); test("negative with decimal closest to 1, should return truncated value as Number", () => { const input = "-12.9"; const output = new JavaInteger(input).get(); expect(output).toEqual(-12); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaInteger("1"); expect(input.get()).toEqual(1); input.set(2); expect(input.get()).toEqual(2); }); test("with invalid direct value, should set NaN", () => { const input = new JavaInteger("1"); expect(input.get()).toEqual(1); input.set(JavaInteger.MAX_VALUE + 1); expect(input.get()).toEqual(NaN); }); test("with valid value from function, should set", () => { const input = new JavaInteger("1"); expect(input.get()).toEqual(1); input.set(cur => 2 + cur); expect(input.get()).toEqual(3); }); test("with invalid value from function, should set NaN", () => { const input = new JavaInteger("1"); expect(input.get()).toEqual(1); input.set(cur => JavaInteger.MAX_VALUE + cur); expect(input.get()).toEqual(NaN); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaInteger("1"); const output = input.doubleValue(); expect(output.get()).toBe(1); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaInteger("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaInteger("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaInteger("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaInteger("1"); const output = input.floatValue(); expect(output.get()).toBe(1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaInteger("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaInteger("1") as any)._fqcn; expect(fqcn).toBe(JavaType.INTEGER); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaLong.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaLong } from "../JavaLong"; import { BigNumber } from "bignumber.js"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive integer, should return same value as number", () => { const input = "12"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("negative integer, should return same value as number", () => { const input = "-12"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("-12")); }); }); test("with invalid textual string, should return NaN", () => { const input = "abc"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber(NaN)); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaLong.MIN_VALUE}`; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber(`${JavaLong.MIN_VALUE}`)); }); test("less than, should return NaN", () => { const input = new BigNumber(`${JavaLong.MIN_VALUE}`).minus(1, 10); const output = new JavaLong(input.toString(10)).get(); expect(output).toEqual(new BigNumber(NaN)); }); }); describe("maximum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaLong.MAX_VALUE}`; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber(`${JavaLong.MAX_VALUE}`)); }); test("greater than, should return NaN", () => { const input = new BigNumber(`${JavaLong.MAX_VALUE}`).plus(1, 10); const output = new JavaLong(input.toString(10)).get(); expect(output).toEqual(new BigNumber(NaN)); }); }); }); describe("with float string", () => { test("positive with decimal closest to 0, should return truncated value as Number", () => { const input = "12.1"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("positive with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "12.5"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("positive with decimal closest to 1, should return truncated value as Number", () => { const input = "12.9"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("12")); }); test("negative with decimal closest to 0, should return truncated value as Number", () => { const input = "-12.1"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("-12")); }); test("negative with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "-12.5"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("-12")); }); test("negative with decimal closest to 1, should return truncated value as Number", () => { const input = "-12.9"; const output = new JavaLong(input).get(); expect(output).toEqual(new BigNumber("-12")); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaLong("1"); expect(input.get()).toEqual(new BigNumber("1")); input.set(new BigNumber("2")); expect(input.get()).toEqual(new BigNumber("2")); }); test("with invalid direct value, should set NaN", () => { const input = new JavaLong("1"); expect(input.get()).toEqual(new BigNumber("1")); input.set(new BigNumber(`${JavaLong.MAX_VALUE}`).plus(1, 10)); expect(input.get()).toEqual(new BigNumber(NaN)); }); test("with valid value from function, should set", () => { const input = new JavaLong("1"); expect(input.get()).toEqual(new BigNumber("1")); input.set(cur => new BigNumber("2").plus(cur)); expect(input.get()).toEqual(new BigNumber("3")); }); test("with invalid value from function, should set NaN", () => { const input = new JavaLong(`${JavaLong.MAX_VALUE}`); expect(input.get()).toEqual(new BigNumber(`${JavaLong.MAX_VALUE}`)); input.set(cur => new BigNumber(`${JavaLong.MAX_VALUE}`).plus(cur)); expect(input.get()).toEqual(new BigNumber(NaN)); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaLong("1"); const output = input.doubleValue(); expect(output.get()).toBe(1); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaLong("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaLong("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaLong("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaLong("1"); const output = input.floatValue(); expect(output.get()).toBe(1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaLong("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaLong("1") as any)._fqcn; expect(fqcn).toBe(JavaType.LONG); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaOptional.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaOptional } from "../JavaOptional"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("defined element, should return same element", () => { const input = "foo"; const output = new JavaOptional(input).get(); expect(output).toBe("foo"); }); test("undefined element, should throw error", () => { const input = undefined; const optional = new JavaOptional(input); expect(() => optional.get()).toThrowError(); }); }); }); describe("set", () => { test("with defined direct value, should set", () => { const input = new JavaOptional("foo"); expect(input.get()).toEqual("foo"); input.set("bar"); expect(input.get()).toEqual("bar"); }); test("with undefined direct value, should set", () => { const input = new JavaOptional("foo"); expect(input.get()).toEqual("foo"); input.set(undefined); expect(() => input.get()).toThrowError(); }); test("with defined value from function, should set", () => { const input = new JavaOptional("foo"); expect(input.get()).toEqual("foo"); input.set(cur => cur + "bar"); expect(input.get()).toEqual("foobar"); }); test("with undefined value from function, should set", () => { const input = new JavaOptional("foo"); expect(input.get()).toEqual("foo"); input.set(_ => undefined); expect(() => input.get()).toThrowError(); }); }); describe("ifPresent", () => { test("with defined element, should return true", () => { const input = new JavaOptional("str"); const output = input.isPresent(); expect(output).toBeTruthy(); }); test("with undefined element, should return true", () => { const input = new JavaOptional(undefined); const output = input.isPresent(); expect(output).toBeFalsy(); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaOptional("foo") as any)._fqcn; expect(fqcn).toBe(JavaType.OPTIONAL); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaShort.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaShort } from "../JavaShort"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("positive integer, should return same value as number", () => { const input = "12"; const output = new JavaShort(input).get(); expect(output).toEqual(12); }); test("negative integer, should return same value as number", () => { const input = "-12"; const output = new JavaShort(input).get(); expect(output).toEqual(-12); }); }); test("with invalid textual string, should return NaN", () => { const input = "abc"; const output = new JavaShort(input).get(); expect(output).toBeNaN(); }); describe("with input in the numeric bounds", () => { describe("minimum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaShort.MIN_VALUE}`; const output = new JavaShort(input).get(); expect(output).toEqual(JavaShort.MIN_VALUE); }); test("less than, should return NaN", () => { const input = `${JavaShort.MIN_VALUE - 1}`; const output = new JavaShort(input).get(); expect(output).toEqual(NaN); }); }); describe("maximum bound", () => { test("equals, should return same value as number", () => { const input = `${JavaShort.MAX_VALUE}`; const output = new JavaShort(input).get(); expect(output).toEqual(JavaShort.MAX_VALUE); }); test("greater than, should return NaN", () => { const input = `${JavaShort.MAX_VALUE + 1}`; const output = new JavaShort(input).get(); expect(output).toEqual(NaN); }); }); }); describe("with float string", () => { test("positive with decimal closest to 0, should return truncated value as Number", () => { const input = "12.1"; const output = new JavaShort(input).get(); expect(output).toEqual(12); }); test("positive with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "12.5"; const output = new JavaShort(input).get(); expect(output).toEqual(12); }); test("positive with decimal closest to 1, should return truncated value as Number", () => { const input = "12.9"; const output = new JavaShort(input).get(); expect(output).toEqual(12); }); test("negative with decimal closest to 0, should return truncated value as Number", () => { const input = "-12.1"; const output = new JavaShort(input).get(); expect(output).toEqual(-12); }); test("negative with decimal exactly between 0 and 1, should return truncated value as Number", () => { const input = "-12.5"; const output = new JavaShort(input).get(); expect(output).toEqual(-12); }); test("negative with decimal closest to 1, should return truncated value as Number", () => { const input = "-12.9"; const output = new JavaShort(input).get(); expect(output).toEqual(-12); }); }); }); describe("set", () => { test("with valid direct value, should set", () => { const input = new JavaShort("1"); expect(input.get()).toEqual(1); input.set(2); expect(input.get()).toEqual(2); }); test("with invalid direct value, should set NaN", () => { const input = new JavaShort("1"); expect(input.get()).toEqual(1); input.set(JavaShort.MAX_VALUE + 1); expect(input.get()).toEqual(NaN); }); test("with valid value from function, should set", () => { const input = new JavaShort("1"); expect(input.get()).toEqual(1); input.set(cur => 2 + cur); expect(input.get()).toEqual(3); }); test("with invalid value from function, should set NaN", () => { const input = new JavaShort("1"); expect(input.get()).toEqual(1); input.set(cur => JavaShort.MAX_VALUE + cur); expect(input.get()).toEqual(NaN); }); }); describe("doubleValue", () => { test("should convert successfully", () => { const input = new JavaShort("1"); const output = input.doubleValue(); expect(output.get()).toBe(1); }); }); describe("intValue", () => { test("should convert successfully", () => { const input = new JavaShort("1"); const output = input.intValue(); expect(output.get()).toBe(1); }); }); describe("shortValue", () => { test("should convert successfully", () => { const input = new JavaShort("1"); const output = input.shortValue(); expect(output.get()).toBe(1); }); }); describe("byteValue", () => { test("should convert successfully", () => { const input = new JavaShort("1"); const output = input.byteValue(); expect(output.get()).toBe(1); }); }); describe("floatValue", () => { test("should convert successfully", () => { const input = new JavaShort("1"); const output = input.floatValue(); expect(output.get()).toBe(1); }); }); describe("longValue", () => { test("should convert successfully", () => { const input = new JavaShort("1"); const output = input.longValue(); expect(output.get().toNumber()).toBe(1); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaShort("1") as any)._fqcn; expect(fqcn).toBe(JavaType.SHORT); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaString.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaString } from "../JavaString"; import { JavaType } from "../JavaType"; describe("get", () => { describe("with valid input", () => { test("non-empty string, should return same string", () => { const input = "foo"; const output = new JavaString(input).get(); expect(output).toBe("foo"); }); test("empty string, should return same string", () => { const input = ""; const output = new JavaString(input).get(); expect(output).toBe(""); }); }); }); describe("set", () => { test("with direct value, should set", () => { const input = new JavaString("foo"); expect(input.get()).toBe("foo"); input.set("bar"); expect(input.get()).toBe("bar"); }); test("with value from function, should set", () => { const input = new JavaString("foo"); expect(input.get()).toBe("foo"); input.set(cur => cur + "bar"); expect(input.get()).toBe("foobar"); }); }); describe("_fqcn", () => { test("must be the same than in Java", () => { const fqcn = (new JavaString("foo") as any)._fqcn; expect(fqcn).toBe(JavaType.STRING); }); }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaWrapper.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapper } from "../JavaWrapper"; describe("extendsJavaWrapper", () => { test("with class extending java wrapper, should return true", () => { const input = new MyNumberType(1); const output = JavaWrapper.extendsJavaWrapper(input); expect(output).toBeTruthy(); }); test("with class not extending java wrapper, should return false", () => { const input = { foo: "bar" }; const output = JavaWrapper.extendsJavaWrapper(input); expect(output).toBeFalsy(); }); class MyNumberType extends JavaWrapper { private _value: number; constructor(value: number) { super(); this._value = value; } public get(): number { return this._value; } public set(val: ((current: number) => number) | number): void { // not used } } }); ================================================ FILE: appformer-js/src/java-wrappers/__tests__/JavaWrapperUtils.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapperUtils } from "../JavaWrapperUtils"; import { JavaArrayList } from "../JavaArrayList"; import { JavaHashSet } from "../JavaHashSet"; import { JavaHashMap } from "../JavaHashMap"; import { JavaBoolean } from "../JavaBoolean"; import { JavaString } from "../JavaString"; import { JavaDate } from "../JavaDate"; import { JavaType } from "../JavaType"; import { JavaEnum } from "../JavaEnum"; describe("needsWrapping", () => { test("with array object, should return true", () => { const input = ["foo1", "foo2", "foo3"]; expect(JavaWrapperUtils.needsWrapping(input)).toBeTruthy(); }); test("with set object, should return true", () => { const input = new Set(["foo1", "foo2", "foo3"]); expect(JavaWrapperUtils.needsWrapping(input)).toBeTruthy(); }); test("with map object, should return true", () => { const input = new Map([["foo1", "bar1"], ["foo2", "bar2"]]); expect(JavaWrapperUtils.needsWrapping(input)).toBeTruthy(); }); test("with boolean object, should return true", () => { const input = false; expect(JavaWrapperUtils.needsWrapping(input)).toBeTruthy(); }); test("with string object, should return true", () => { const input = "foo"; expect(JavaWrapperUtils.needsWrapping(input)).toBeTruthy(); }); test("with date object, should return true", () => { const input = new Date(); expect(JavaWrapperUtils.needsWrapping(input)).toBeTruthy(); }); test("with custom object, should return false", () => { const input = { foo: "bar1", foo2: "bar2" }; expect(JavaWrapperUtils.needsWrapping(input)).toBeFalsy(); }); test("with enum type, should return false", () => { const input = FooEnum.FOO; expect(JavaWrapperUtils.needsWrapping(input)).toBeFalsy(); }); }); describe("wrapIfNeeded", () => { test("with array object, should return a JavaArray instance", () => { const input = ["foo1", "foo2", "foo3"]; expect(JavaWrapperUtils.wrapIfNeeded(input)).toEqual(new JavaArrayList(["foo1", "foo2", "foo3"])); }); test("with set object, should return a JavaHashSet instance", () => { const input = new Set(["foo1", "foo2", "foo3"]); const output = new JavaHashSet(new Set(["foo1", "foo2", "foo3"])); expect(JavaWrapperUtils.wrapIfNeeded(input)).toEqual(output); }); test("with map object, should return a JavaHashMap instance", () => { const input = new Map([["foo1", "bar1"], ["foo2", "bar2"]]); const output = new JavaHashMap(new Map([["foo1", "bar1"], ["foo2", "bar2"]])); expect(JavaWrapperUtils.wrapIfNeeded(input)).toEqual(output); }); test("with boolean object, should return a JavaBoolean instance", () => { const input = false; const output = new JavaBoolean(false); expect(JavaWrapperUtils.wrapIfNeeded(input)).toEqual(output); }); test("with string object, should return a JavaString instance", () => { const input = "foo"; const output = new JavaString("foo"); expect(JavaWrapperUtils.wrapIfNeeded(input)).toEqual(output); }); test("with date object, should return a JavaDate instance", () => { const input = new Date(); const output = new JavaDate(input); expect(JavaWrapperUtils.wrapIfNeeded(input)).toEqual(output); }); test("with custom object, should return same object", () => { const input = { foo: "bar1", foo2: "bar2" }; expect(JavaWrapperUtils.wrapIfNeeded(input)).toStrictEqual(input); }); test("with enum value, should return same value", () => { const input = FooEnum.BAR; expect(JavaWrapperUtils.wrapIfNeeded(input)).toStrictEqual(input); }); }); describe("isJavaType", () => { test("with Java Byte's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.BYTE)).toBeTruthy(); }); test("with Java Double's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.DOUBLE)).toBeTruthy(); }); test("with Java Float's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.FLOAT)).toBeTruthy(); }); test("with Java Integer's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.INTEGER)).toBeTruthy(); }); test("with Java Long's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.LONG)).toBeTruthy(); }); test("with Java Short's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.SHORT)).toBeTruthy(); }); test("with Java Boolean's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.BOOLEAN)).toBeTruthy(); }); test("with Java String's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.STRING)).toBeTruthy(); }); test("with Java BigDecimal's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.BIG_DECIMAL)).toBeTruthy(); }); test("with Java BigInteger's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.BIG_INTEGER)).toBeTruthy(); }); test("with Java ArrayList's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.ARRAY_LIST)).toBeTruthy(); }); test("with Java HashSet's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.HASH_SET)).toBeTruthy(); }); test("with Java HashMap's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.HASH_MAP)).toBeTruthy(); }); test("with Java Date's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.DATE)).toBeTruthy(); }); test("with non Java type fqcn, should return false", () => { expect(JavaWrapperUtils.isJavaType("foo")).toBeFalsy(); }); test("with Java Optional's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.OPTIONAL)).toBeTruthy(); }); test("with Java Enum's fqcn, should return true", () => { expect(JavaWrapperUtils.isJavaType(JavaType.ENUM)).toBeTruthy(); }); }); describe("isEnum", () => { test("with Enum input, should return true", () => { const input = FooEnum.BAR; expect(JavaWrapperUtils.isEnum(input)).toBeTruthy(); }); test("with non enum input, should return false", () => { const input = { foo: "bar" }; expect(JavaWrapperUtils.isEnum(input)).toBeFalsy(); }); }); class FooEnum extends JavaEnum { public static readonly FOO: FooEnum = new FooEnum("FOO"); public static readonly BAR: FooEnum = new FooEnum("BAR"); protected readonly _fqcn: string = FooEnum.__fqcn(); public static __fqcn(): string { return "com.app.my.AddressType"; } public static values() { return [FooEnum.FOO, FooEnum.BAR]; } } ================================================ FILE: appformer-js/src/java-wrappers/index.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./JavaArrayList"; export * from "./JavaHashMap"; export * from "./JavaHashSet"; export * from "./JavaByte"; export * from "./JavaDouble"; export * from "./JavaFloat"; export * from "./JavaInteger"; export * from "./JavaNumber"; export * from "./JavaLong"; export * from "./JavaShort"; export * from "./JavaBigInteger"; export * from "./JavaBigDecimal"; export * from "./JavaBoolean"; export * from "./JavaString"; export * from "./JavaDate"; export * from "./JavaOptional"; export * from "./JavaTreeMap"; export * from "./JavaTreeSet"; export * from "./JavaLinkedList"; export * from "./JavaEnum"; ================================================ FILE: appformer-js/src/marshalling/Marshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "./MarshallingContext"; import { Portable } from "./Portable"; import { UnmarshallingContext } from "./UnmarshallingContext"; // marshall(T) => U // unmarshall(V) => X export interface Marshaller, U, V, X> { marshall(input: T, ctx: MarshallingContext): U | null; unmarshall(input: V | undefined, ctx: UnmarshallingContext): X | undefined; } ================================================ FILE: appformer-js/src/marshalling/MarshallerProvider.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaWrapperUtils } from "../java-wrappers/JavaWrapperUtils"; import { JavaType } from "../java-wrappers/JavaType"; import { Marshaller } from "./Marshaller"; import { JavaHashMapMarshaller } from "./marshallers/JavaHashMapMarshaller"; import { JavaShortMarshaller } from "./marshallers/JavaShortMarshaller"; import { JavaDoubleMarshaller } from "./marshallers/JavaDoubleMarshaller"; import { DefaultMarshaller } from "./marshallers/DefaultMarshaller"; import { JavaStringMarshaller } from "./marshallers/JavaStringMarshaller"; import { JavaIntegerMarshaller } from "./marshallers/JavaIntegerMarshaller"; import { JavaBigIntegerMarshaller } from "./marshallers/JavaBigIntegerMarshaller"; import { JavaFloatMarshaller } from "./marshallers/JavaFloatMarshaller"; import { JavaBooleanMarshaller } from "./marshallers/JavaBooleanMarshaller"; import { JavaLongMarshaller } from "./marshallers/JavaLongMarshaller"; import { JavaBigDecimalMarshaller } from "./marshallers/JavaBigDecimalMarshaller"; import { JavaByteMarshaller } from "./marshallers/JavaByteMarshaller"; import { JavaDateMarshaller } from "./marshallers/JavaDateMarshaller"; import { JavaOptionalMarshaller } from "./marshallers/JavaOptionalMarshaller"; import { JavaArrayListMarshaller, JavaHashSetMarshaller } from "./marshallers/JavaCollectionMarshaller"; import { Portable } from "./Portable"; import { JavaEnumMarshaller } from "./marshallers/JavaEnumMarshaller"; export class MarshallerProvider { private static initialized: boolean = false; private static marshallersByJavaType: Map>; private static defaultMarshaller: Marshaller; public static initialize() { if (this.initialized) { return; } this.defaultMarshaller = new DefaultMarshaller(); this.marshallersByJavaType = new Map(); this.marshallersByJavaType.set(JavaType.BYTE, new JavaByteMarshaller()); this.marshallersByJavaType.set(JavaType.DOUBLE, new JavaDoubleMarshaller()); this.marshallersByJavaType.set(JavaType.FLOAT, new JavaFloatMarshaller()); this.marshallersByJavaType.set(JavaType.INTEGER, new JavaIntegerMarshaller()); this.marshallersByJavaType.set(JavaType.LONG, new JavaLongMarshaller()); this.marshallersByJavaType.set(JavaType.SHORT, new JavaShortMarshaller()); this.marshallersByJavaType.set(JavaType.BOOLEAN, new JavaBooleanMarshaller()); this.marshallersByJavaType.set(JavaType.STRING, new JavaStringMarshaller()); this.marshallersByJavaType.set(JavaType.DATE, new JavaDateMarshaller()); this.marshallersByJavaType.set(JavaType.BIG_DECIMAL, new JavaBigDecimalMarshaller()); this.marshallersByJavaType.set(JavaType.BIG_INTEGER, new JavaBigIntegerMarshaller()); this.marshallersByJavaType.set(JavaType.ARRAY_LIST, new JavaArrayListMarshaller()); this.marshallersByJavaType.set(JavaType.UNMODIFIABLE_COLLECTION, new JavaHashSetMarshaller()); this.marshallersByJavaType.set(JavaType.UNMODIFIABLE_SET, new JavaHashSetMarshaller()); this.marshallersByJavaType.set(JavaType.HASH_SET, new JavaHashSetMarshaller()); this.marshallersByJavaType.set(JavaType.HASH_MAP, new JavaHashMapMarshaller()); this.marshallersByJavaType.set(JavaType.UNMODIFIABLE_MAP, new JavaHashMapMarshaller()); this.marshallersByJavaType.set(JavaType.OPTIONAL, new JavaOptionalMarshaller()); this.marshallersByJavaType.set(JavaType.ENUM, new JavaEnumMarshaller()); this.initialized = true; } public static getForObject(obj: Portable): Marshaller { this.assertInitialization(); if (obj === null || obj === undefined) { return this.defaultMarshaller; } const fqcn = (obj as any)._fqcn; if (!fqcn) { return this.defaultMarshaller; } return this.getForFqcn(fqcn); } public static getForFqcn(fqcn: string): Marshaller { this.assertInitialization(); if (!fqcn) { return this.defaultMarshaller; } if (!JavaWrapperUtils.isJavaType(fqcn)) { // portable objects defines an fqcn but we don't have specific marshallers for it. return this.defaultMarshaller; } const marshaller = MarshallerProvider.marshallersByJavaType.get(fqcn); if (!marshaller) { throw new Error(`Missing marshaller implementation for type ${fqcn}`); } return marshaller; } public static getForEnum(): Marshaller { return this.getForFqcn(JavaType.ENUM); } private static assertInitialization() { if (!this.initialized) { throw new Error("Initialize MarshallerProvider before using."); } } } ================================================ FILE: appformer-js/src/marshalling/Marshalling.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Portable } from "./Portable"; import { MarshallerProvider } from "./MarshallerProvider"; import { MarshallingContext } from "./MarshallingContext"; import { UnmarshallingContext } from "./UnmarshallingContext"; import { ErraiObjectConstants } from "./model/ErraiObjectConstants"; /** * Serializes a Portable object into an Errai json. * @param obj */ export function marshall(obj: Portable): string | null { if (obj === null || obj === undefined) { return null; } const marshaller = MarshallerProvider.getForObject(obj); return JSON.stringify(marshaller.marshall(obj, new MarshallingContext())); } /** * Deserializes an Errai json creating a Portable object. * * @param json * The Errai json. * @param oracle * A map containing fqcns as keys and a function returning an empty Portable associated with that fqcn. */ export function unmarshall(json: string, oracle: Map Portable>): Portable | null | void { if (json === null || json === undefined) { return undefined; } const jsonObj = JSON.parse(json); const fqcn = jsonObj[ErraiObjectConstants.ENCODED_TYPE]; const marshaller = MarshallerProvider.getForFqcn(fqcn); return marshaller.unmarshall(jsonObj, new UnmarshallingContext(oracle)); } ================================================ FILE: appformer-js/src/marshalling/MarshallingContext.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ErraiObject } from "./model/ErraiObject"; import { ErraiObjectConstants } from "./model/ErraiObjectConstants"; import { Portable } from "./Portable"; import { JavaWrapper } from "../java-wrappers/JavaWrapper"; export class MarshallingContext { private objContext: Map, ErraiObject>; private objectId: number; constructor() { this.objContext = new Map(); this.objectId = 0; } public incrementAndGetObjectId() { return ++this.objectId; } public cacheObject(key: Portable, obj: ErraiObject) { this.objContext.set(this.unwrap(key), { [ErraiObjectConstants.ENCODED_TYPE]: obj[ErraiObjectConstants.ENCODED_TYPE], [ErraiObjectConstants.OBJECT_ID]: obj[ErraiObjectConstants.OBJECT_ID] }); } public getCached(key: Portable): ErraiObject | undefined { return this.objContext.get(this.unwrap(key))!; } private unwrap(key: Portable) { if (JavaWrapper.extendsJavaWrapper(key)) { // When handling wrapped values, we use the raw typescript value as cache key. // This is needed because in the marshalling flow we wrap the values automatically // if they represent a Java type, creating a new wrapper object every time. If we use the wrapper // object directly, the value will never be found in cache, because it'll always be a different pointer return key.get(); } return key; } } ================================================ FILE: appformer-js/src/marshalling/Portable.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // tslint:disable-next-line export interface Portable> {} ================================================ FILE: appformer-js/src/marshalling/UnmarshallingContext.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Portable } from "./Portable"; import { ErraiObject } from "./model/ErraiObject"; import { ErraiObjectConstants } from "./model/ErraiObjectConstants"; export class UnmarshallingContext { private readonly _oracle: Map Portable>; private readonly _objectsCache: Map>; constructor(oracle: Map Portable>) { this._oracle = oracle; this._objectsCache = new Map(); } public cacheObject(input: ErraiObject, obj: Portable) { const objectId = input[ErraiObjectConstants.OBJECT_ID]; if (objectId) { this._objectsCache.set(objectId, obj); } } public getCached(input: ErraiObject): Portable | undefined { const objectId = input[ErraiObjectConstants.OBJECT_ID]; if (!objectId) { return undefined; } return this._objectsCache.get(objectId); } public getFactory(fqcn: string): (() => Portable) | undefined { return this._oracle.get(fqcn); } } ================================================ FILE: appformer-js/src/marshalling/__tests__/MarshallerProvider.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaArrayList, JavaBigDecimal, JavaBigInteger, JavaBoolean, JavaByte, JavaDate, JavaDouble, JavaFloat, JavaHashMap, JavaHashSet, JavaInteger, JavaLong, JavaOptional, JavaShort, JavaString } from "../../java-wrappers"; import { MarshallerProvider } from "../MarshallerProvider"; import { JavaBigIntegerMarshaller } from "../marshallers/JavaBigIntegerMarshaller"; import { JavaHashMapMarshaller } from "../marshallers/JavaHashMapMarshaller"; import { JavaByteMarshaller } from "../marshallers/JavaByteMarshaller"; import { JavaBigDecimalMarshaller } from "../marshallers/JavaBigDecimalMarshaller"; import { JavaStringMarshaller } from "../marshallers/JavaStringMarshaller"; import { JavaBooleanMarshaller } from "../marshallers/JavaBooleanMarshaller"; import { JavaShortMarshaller } from "../marshallers/JavaShortMarshaller"; import { JavaLongMarshaller } from "../marshallers/JavaLongMarshaller"; import { JavaIntegerMarshaller } from "../marshallers/JavaIntegerMarshaller"; import { JavaFloatMarshaller } from "../marshallers/JavaFloatMarshaller"; import { JavaDoubleMarshaller } from "../marshallers/JavaDoubleMarshaller"; import { DefaultMarshaller } from "../marshallers/DefaultMarshaller"; import { JavaWrapperUtils } from "../../java-wrappers/JavaWrapperUtils"; import { JavaType } from "../../java-wrappers/JavaType"; import * as JavaCollectionMarshaller from "../marshallers/JavaCollectionMarshaller"; import { JavaDateMarshaller } from "../marshallers/JavaDateMarshaller"; import { JavaOptionalMarshaller } from "../marshallers/JavaOptionalMarshaller"; describe("getForObject", () => { test("without initialize, should return Error", () => { const input = new JavaString("foo"); expect(() => MarshallerProvider.getForObject(input)).toThrowError(); }); describe("properly initialized", () => { beforeEach(() => { MarshallerProvider.initialize(); }); afterEach(() => { // force reinitialization (MarshallerProvider as any).initialized = false; }); test("with JavaByte instance, should return JavaByteMarshaller instance", () => { const input = new JavaByte("1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaByteMarshaller()); }); test("with JavaDouble instance, should return JavaDoubleMarshaller instance", () => { const input = new JavaDouble("1.1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaDoubleMarshaller()); }); test("with JavaFloat instance, should return JavaFloatMarshaller instance", () => { const input = new JavaFloat("1.1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaFloatMarshaller()); }); test("with JavaInteger instance, should return JavaIntegerMarshaller instance", () => { const input = new JavaInteger("1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaIntegerMarshaller()); }); test("with JavaLong instance, should return JavaLongMarshaller instance", () => { const input = new JavaLong("1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaLongMarshaller()); }); test("with JavaShort instance, should return JavaShortMarshaller instance", () => { const input = new JavaShort("1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaShortMarshaller()); }); test("with JavaBoolean instance, should return JavaBooleanMarshaller instance", () => { const input = new JavaBoolean(false); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaBooleanMarshaller()); }); test("with JavaString instance, should return JavaStringMarshaller instance", () => { const input = new JavaString("foo"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaStringMarshaller()); }); test("with JavaDate instance, should return JavaDateMarshaller instance", () => { const input = new JavaDate(new Date()); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaDateMarshaller()); }); test("with JavaBigDecimal instance, should return JavaBigDecimalMarshaller instance", () => { const input = new JavaBigDecimal("1.1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaBigDecimalMarshaller()); }); test("with JavaBigInteger instance, should return JavaBigIntegerMarshaller instance", () => { const input = new JavaBigInteger("1"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaBigIntegerMarshaller()); }); test("with JavaArrayList instance, should return JavaArrayListMarshaller instance", () => { const input = new JavaArrayList([1, 2, 3]); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaCollectionMarshaller.JavaArrayListMarshaller()); }); test("with JavaHashSet instance, should return JavaHashSetMarshaller instance", () => { const input = new JavaHashSet(new Set([1, 2, 3])); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaCollectionMarshaller.JavaHashSetMarshaller()); }); test("with JavaHashMap instance, should return JavaHashMapMarshaller instance", () => { const input = new JavaHashMap(new Map([["foo", "bar"]])); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaHashMapMarshaller()); }); test("with JavaOptional instance, should return JavaOptionalMarshaller instance", () => { const input = new JavaOptional("str"); expect(MarshallerProvider.getForObject(input)).toEqual(new JavaOptionalMarshaller()); }); test("with input without fqcn, should return default marshaller", () => { const input = { foo: "bar", bar: "foo" }; expect(MarshallerProvider.getForObject(input)).toEqual(new DefaultMarshaller()); }); test("with input with a custom fqcn, should return default marshaller", () => { const fqcn = "com.myapp.custom.pojo"; const input = { _fqcn: fqcn, foo: "bar", bar: "foo" }; // it is a custom pojo (i.e. no pre-defined marshaller) expect(JavaWrapperUtils.isJavaType(fqcn)).toBeFalsy(); expect(MarshallerProvider.getForObject(input)).toEqual(new DefaultMarshaller()); }); test("with a Java type without marshaller, should throw error", () => { // the only scenario it throws errors is when a Java-wrapped type has no marshaller associated. // little trick to mess with internal state const marshallers = (MarshallerProvider as any).marshallersByJavaType; marshallers.delete(JavaType.STRING); const input = new JavaString("foo"); expect(() => MarshallerProvider.getForObject(input)).toThrowError(); }); }); }); describe("getForFqcn", () => { test("without initialize, should return Error", () => { expect(() => MarshallerProvider.getForFqcn("anything")).toThrowError(); }); describe("properly initialized", () => { beforeEach(() => { MarshallerProvider.initialize(); }); afterEach(() => { // force reinitialization (MarshallerProvider as any).initialized = false; }); test("with Java's Byte fqcn, should return JavaByteMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.BYTE)).toEqual(new JavaByteMarshaller()); }); test("with Java's Double fqcn, should return JavaDoubleMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.DOUBLE)).toEqual(new JavaDoubleMarshaller()); }); test("with Java's Float fqcn, should return JavaFloatMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.FLOAT)).toEqual(new JavaFloatMarshaller()); }); test("with Java's Integer fqcn, should return JavaIntegerMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.INTEGER)).toEqual(new JavaIntegerMarshaller()); }); test("with Java's Long fqcn, should return JavaLongMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.LONG)).toEqual(new JavaLongMarshaller()); }); test("with Java's Short fqcn, should return JavaShortMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.SHORT)).toEqual(new JavaShortMarshaller()); }); test("with Java's Boolean fqcn, should return JavaBooleanMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.BOOLEAN)).toEqual(new JavaBooleanMarshaller()); }); test("with Java's String fqcn, should return JavaStringMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.STRING)).toEqual(new JavaStringMarshaller()); }); test("with Java's Date fqcn, should return JavaDateMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.DATE)).toEqual(new JavaDateMarshaller()); }); test("with Java's BigDecimal fqcn, should return JavaBigDecimalMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.BIG_DECIMAL)).toEqual(new JavaBigDecimalMarshaller()); }); test("with Java's BigInteger fqcn, should return JavaBigIntegerMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.BIG_INTEGER)).toEqual(new JavaBigIntegerMarshaller()); }); test("with Java's ArrayList fqcn, should return JavaArrayListMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.ARRAY_LIST)).toEqual( new JavaCollectionMarshaller.JavaArrayListMarshaller() ); }); test("with Java's HashSet fqcn, should return JavaHashSetMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.HASH_SET)).toEqual( new JavaCollectionMarshaller.JavaHashSetMarshaller() ); }); test("with Java's HashMap fqcn, should return JavaHashMapMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.HASH_MAP)).toEqual(new JavaHashMapMarshaller()); }); test("with Java's Optional fqcn, should return JavaOptionalMarshaller instance", () => { expect(MarshallerProvider.getForFqcn(JavaType.OPTIONAL)).toEqual(new JavaOptionalMarshaller()); }); test("with null fqcn, should return default marshaller", () => { const fqcn = null as any; expect(MarshallerProvider.getForFqcn(fqcn)).toEqual(new DefaultMarshaller()); }); test("with undefined fqcn, should return default marshaller", () => { const fqcn = undefined as any; expect(MarshallerProvider.getForFqcn(fqcn)).toEqual(new DefaultMarshaller()); }); test("with empty string, should return default marshaller", () => { const fqcn = ""; expect(MarshallerProvider.getForFqcn(fqcn)).toEqual(new DefaultMarshaller()); }); test("with custom fqcn, should return default marshaller", () => { const fqcn = "com.myapp.custom.pojo"; // it is a custom pojo (i.e. no pre-defined marshaller) expect(JavaWrapperUtils.isJavaType(fqcn)).toBeFalsy(); expect(MarshallerProvider.getForFqcn(fqcn)).toEqual(new DefaultMarshaller()); }); }); }); describe("consistency validations", () => { beforeEach(() => { (MarshallerProvider as any).initialized = false; // force reinitialization MarshallerProvider.initialize(); }); test("all Java types should have a marshaller associated", () => { // this test is important to avoid developers to forget to add marshallers to new JavaTypes const marshallers = (MarshallerProvider as any).marshallersByJavaType; Object.keys(JavaType) .map((k: keyof typeof JavaType) => JavaType[k]) .forEach(javaType => expect(marshallers.get(javaType)).toBeDefined()); }); }); describe("getForEnum", () => { beforeEach(() => { MarshallerProvider.initialize(); }); afterEach(() => { // force reinitialization (MarshallerProvider as any).initialized = false; }); test("should return exactly the same enum marshaller object", () => { const enumMarshaller = (MarshallerProvider as any).marshallersByJavaType.get(JavaType.ENUM); expect(MarshallerProvider.getForEnum()).toStrictEqual(enumMarshaller); }); }); ================================================ FILE: appformer-js/src/marshalling/__tests__/Marshalling.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallerProvider } from "../MarshallerProvider"; import * as Marshalling from "../Marshalling"; import { unmarshall } from "../Marshalling"; import { JavaInteger } from "../../java-wrappers"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; import { JavaType } from "../../java-wrappers/JavaType"; const originalGetForObject = MarshallerProvider.getForObject; const originalGetForFqcn = MarshallerProvider.getForFqcn; afterEach(() => { // reset static function, otherwise other tests will be invoking the function set by this test MarshallerProvider.getForFqcn = originalGetForFqcn; MarshallerProvider.getForObject = originalGetForObject; }); describe("marshall", () => { test("with regular input, should return an errai object json-string version of it", () => { const input = new JavaInteger("1"); const inputErraiObject = new NumValBasedErraiObject(JavaType.INTEGER, 1).asErraiObject(); const expectedJson = JSON.stringify(inputErraiObject); // skip actual marshaller implementation const mockedMarshaller = { marshall: jest.fn(() => inputErraiObject), unmarshall: jest.fn() }; MarshallerProvider.getForObject = jest.fn(() => mockedMarshaller); // == // ====== test const output = Marshalling.marshall(input); // == assertion expect(expectedJson).toEqual(output); }); test("with null input, should return null", () => { const input = null as any; const output = Marshalling.marshall(input); expect(output).toBeNull(); }); test("with undefined input, should serialize marshaller output", () => { const input = undefined as any; const output = Marshalling.marshall(input); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with null input, should return undefined", () => { const input = null; const output = unmarshall(input as any, new Map()); expect(output).toBeUndefined(); }); test("with undefined input, should return undefined", () => { const input = undefined; const output = unmarshall(input as any, new Map()); expect(output).toBeUndefined(); }); test("with invalid json, should throw error", () => { const input = "{ broken json }"; expect(() => unmarshall(input, new Map())).toThrowError(); }); test("with regular input, should return marshallers' specific content", () => { const inputJson = new NumValBasedErraiObject(JavaType.INTEGER, 1).asErraiObject(); const expectedOutput = new JavaInteger("1"); // skip actual marshaller implementation const mockedMarshaller = { unmarshall: jest.fn(() => expectedOutput), marshall: jest.fn() }; MarshallerProvider.getForFqcn = jest.fn(() => mockedMarshaller); // == // ====== test const output = Marshalling.unmarshall(JSON.stringify(inputJson), new Map()); // == assertion expect(expectedOutput).toEqual(output); }); }); ================================================ FILE: appformer-js/src/marshalling/__tests__/MarshallingContext.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../MarshallingContext"; import { ErraiObject } from "../model/ErraiObject"; import { ErraiObjectConstants } from "../model/ErraiObjectConstants"; import { JavaWrapper } from "../../java-wrappers/JavaWrapper"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; describe("incrementAndGetObjectId", () => { test("with sequential calls, should return different ids", () => { const context = new MarshallingContext(); const firstObjectId = context.incrementAndGetObjectId(); const secondObjectId = context.incrementAndGetObjectId(); expect(firstObjectId).not.toEqual(secondObjectId); }); }); describe("cacheObject", () => { let context: MarshallingContext; beforeEach(() => { context = new MarshallingContext(); }); test("with regular object, should record the correct ErraiObject instance", () => { const inputPortable = { _fqcn: "com.myapp.my.portable", foo: "bar", bar: "foo" }; const inputErraiObject = new NumValBasedErraiObject("com.foo.bar", "123", "1").asErraiObject(); context.cacheObject(inputPortable, inputErraiObject); // the only cached fields are the encodedType and objectId expect((context as any).objContext.get(inputPortable)).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.foo.bar", [ErraiObjectConstants.OBJECT_ID]: "1" }); }); test("with object overwritten, should return the last version", () => { const inputPortable = { _fqcn: "com.myapp.my.portable", foo: "bar", bar: "foo" }; const inputErraiObject = new NumValBasedErraiObject("com.foo.bar", "123", "1").asErraiObject(); context.cacheObject(inputPortable, inputErraiObject); // override object context.cacheObject(inputPortable, { ...inputErraiObject, [ErraiObjectConstants.OBJECT_ID]: "2" }); expect((context as any).objContext.get(inputPortable)).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.foo.bar", [ErraiObjectConstants.OBJECT_ID]: "2" }); }); test("with java wrapper object, should use the inner value as cache key", () => { const innerValue = 1; const wrappedValue = new MyNumberWrappedType(innerValue); const inputErraiObject = new NumValBasedErraiObject("com.foo.bar", "123", "1").asErraiObject(); context.cacheObject(wrappedValue, inputErraiObject); // use the inner value object as cache key expect((context as any).objContext.get(innerValue)).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.foo.bar", [ErraiObjectConstants.OBJECT_ID]: "1" }); // do not use the wrapped object as cache key expect((context as any).objContext.get(wrappedValue)).toBeUndefined(); }); }); describe("getCached", () => { let context: MarshallingContext; beforeEach(() => { context = new MarshallingContext(); }); test("with non-existent key, should return undefined", () => { const input = { _fqcn: "com.myapp.my.portable", foo: "bar", bar: "foo" }; expect(context.getCached(input)).toBeUndefined(); }); test("with existent key, should same object recorded previously", () => { const inputPortable = { _fqcn: "com.myapp.my.portable", foo: "bar", bar: "foo" }; const inputErraiObject = { [ErraiObjectConstants.ENCODED_TYPE]: "com.foo.bar", [ErraiObjectConstants.OBJECT_ID]: "1" } as ErraiObject; (context as any).objContext.set(inputPortable, inputErraiObject); expect(context.getCached(inputPortable)).toStrictEqual(inputErraiObject); }); test("with java wrapper object, should use the inner value as cache key", () => { const innerValue = 1; const wrappedValue = new MyNumberWrappedType(innerValue); const inputErraiObject = { [ErraiObjectConstants.ENCODED_TYPE]: "com.foo.bar", [ErraiObjectConstants.OBJECT_ID]: "1" } as ErraiObject; (context as any).objContext.set(innerValue, inputErraiObject); // use the inner value object as cache key expect(context.getCached(innerValue)).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.foo.bar", [ErraiObjectConstants.OBJECT_ID]: "1" }); expect(context.getCached(wrappedValue)).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.foo.bar", [ErraiObjectConstants.OBJECT_ID]: "1" }); }); }); class MyNumberWrappedType extends JavaWrapper { private readonly _fqcn = "com.type.wrapped.number.my"; private readonly _value: number; constructor(value: number) { super(); this._value = value; } public get(): number { return this._value; } public set(val: ((current: number) => number) | number): void { // not used } } ================================================ FILE: appformer-js/src/marshalling/__tests__/UnmarshallingContext.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { UnmarshallingContext } from "../UnmarshallingContext"; import { Portable } from "../Portable"; import { ErraiObjectConstants } from "../model/ErraiObjectConstants"; describe("cacheObject", () => { test("with regular input, should cache it using the object's id as key", () => { const context = new UnmarshallingContext(new Map()); const erraiObj = { [ErraiObjectConstants.ENCODED_TYPE]: "bla", [ErraiObjectConstants.OBJECT_ID]: "1", foo: "bar" }; const portable = new MyPortable({ foo: "bar" }); context.cacheObject(erraiObj, portable); const cache = (context as any)._objectsCache; const cachedValue = cache.get("1"); expect(cachedValue).toStrictEqual(portable); expect(cache.size).toBe(1); }); test("with repeated calls, should cache the last version", () => { const context = new UnmarshallingContext(new Map()); const erraiObj = { [ErraiObjectConstants.ENCODED_TYPE]: "bla", [ErraiObjectConstants.OBJECT_ID]: "1", foo: "bar" }; const portable = new MyPortable({ foo: "bar" }); const portableV2 = new MyPortable({ foo: "bar2" }); context.cacheObject(erraiObj, portable); context.cacheObject(erraiObj, portableV2); const cache = (context as any)._objectsCache; const cachedValue = cache.get("1"); expect(cachedValue).toStrictEqual(portableV2); expect(cache.size).toBe(1); }); test("with input without object id, should not cache it", () => { const context = new UnmarshallingContext(new Map()); const erraiObj = { [ErraiObjectConstants.ENCODED_TYPE]: "bla", [ErraiObjectConstants.OBJECT_ID]: "", foo: "bar" }; const portable = new MyPortable({ foo: "bar" }); context.cacheObject(erraiObj, portable); const cache = (context as any)._objectsCache; const cachedValue = cache.get("1"); expect(cachedValue).toBeUndefined(); expect(cache.size).toBe(0); }); }); describe("getCached", () => { test("with cached input, should return it", () => { const context = new UnmarshallingContext(new Map()); const erraiObj = { [ErraiObjectConstants.ENCODED_TYPE]: "bla", [ErraiObjectConstants.OBJECT_ID]: "1", foo: "bar" }; const portable = new MyPortable({ foo: "bar" }); context.cacheObject(erraiObj, portable); const cachedValue = context.getCached(erraiObj); expect(cachedValue).toStrictEqual(portable); }); test("with input without object id, should return undefined", () => { const context = new UnmarshallingContext(new Map()); const spy = jest.spyOn((context as any)._objectsCache, "get"); const erraiObj = { // no object id [ErraiObjectConstants.ENCODED_TYPE]: "bla", [ErraiObjectConstants.OBJECT_ID]: "", foo: "bar" }; context.getCached(erraiObj); expect(spy).not.toHaveBeenCalled(); }); test("with non existent input, should return undefined", () => { const context = new UnmarshallingContext(new Map()); // add some dummy entry to the cache const erraiObj = { [ErraiObjectConstants.ENCODED_TYPE]: "bla", [ErraiObjectConstants.OBJECT_ID]: "1", foo: "bar" }; const cachedValue = context.getCached(erraiObj); expect(cachedValue).toBeUndefined(); expect((context as any)._objectsCache.size).toEqual(0); }); }); describe("getFactory", () => { test("with existent factory for fqcn, should return it", () => { const oracle = new Map([["com.app.my", () => new MyPortable({} as any)]]); const context = new UnmarshallingContext(oracle); const factory = context.getFactory("com.app.my"); expect(factory).toBeDefined(); expect(factory!()).toEqual(new MyPortable({} as any)); }); test("with non-existent factory for fqcn, should return it", () => { const oracle = new Map([["com.app.my2", () => new MyPortable({} as any)]]); const context = new UnmarshallingContext(oracle); const factory = context.getFactory("com.app.my"); expect(factory).toBeUndefined(); }); }); class MyPortable implements Portable { private readonly _fqcn = "com.app.my"; public readonly foo: string; constructor(self: { foo: string }) { Object.assign(this, self); } } ================================================ FILE: appformer-js/src/marshalling/index.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallerProvider } from "./MarshallerProvider"; export * from "./Marshalling"; export * from "./Portable"; // Load marshallers to be used in RPC flow MarshallerProvider.initialize(); ================================================ FILE: appformer-js/src/marshalling/marshallers/DefaultMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallerProvider } from "../MarshallerProvider"; import { MarshallingContext } from "../MarshallingContext"; import { ErraiObject } from "../model/ErraiObject"; import { JavaWrapperUtils } from "../../java-wrappers/JavaWrapperUtils"; import { ErraiObjectConstants } from "../model/ErraiObjectConstants"; import { Portable } from "../Portable"; import { NullableMarshaller } from "./NullableMarshaller"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { JavaWrapper } from "../../java-wrappers/JavaWrapper"; export class DefaultMarshaller> extends NullableMarshaller< T, ErraiObject, ErraiObject, Portable > { public notNullMarshall(input: T, ctx: MarshallingContext): ErraiObject { const cachedObject = ctx.getCached(input); if (cachedObject) { return cachedObject; } const rootFqcn = (input as any)._fqcn; if (!rootFqcn) { // the input may be of primitive type, if it is a Java-wrappable type, // we need to wrap it before marshalling if (JavaWrapperUtils.needsWrapping(input)) { return DefaultMarshaller.marshallWrappableType(input, ctx); } else { throw new Error(`Don't know how to marshall ${input}. Portable types must contain a '_fqcn' property!`); } } // Input has fqcn, so, it represents a Java type. We need to check if it // is a primitive Java type or not, because this marshaller handles only // custom types (i.e. Portable). if (JavaWrapperUtils.isJavaType(rootFqcn)) { const marshaller = MarshallerProvider.getForObject(input); const marshalledObject = marshaller.marshall(input, ctx); ctx.cacheObject(input, marshalledObject); return marshalledObject; } if (JavaWrapperUtils.isEnum(input)) { return MarshallerProvider.getForEnum().marshall(input, ctx); } const _this = this.marshallCustomObject(input, ctx, rootFqcn); ctx.cacheObject(input, _this); return _this; } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): Portable { const cachedObject = ctx.getCached(input); if (cachedObject) { return cachedObject; } const rootFqcn = input[ErraiObjectConstants.ENCODED_TYPE]; if (!rootFqcn) { return DefaultMarshaller.unmarshallUnqualifiedValue(input, ctx); } const targetFactory = ctx.getFactory(rootFqcn); if (!targetFactory) { // this input is not a custom object, otherwise, we would be able to find a factory function. // try to unmarshall it as a java type (that we know how to build) return DefaultMarshaller.unmarshallJavaType(rootFqcn, input, ctx); } if (this.isEnumObject(input as any)) { return MarshallerProvider.getForEnum().unmarshall(input, ctx); } const targetObj = this.unmarshallCustomObject(targetFactory, input, ctx); ctx.cacheObject(input, targetObj); return targetObj; } private marshallCustomObject(input: any, ctx: MarshallingContext, fqcn: string) { const _this = { ...input }; Object.keys(_this).forEach(k => { if (typeof _this[k] === "function") { delete _this[k]; } else if (_this[k] === undefined || _this[k] === null) { _this[k] = null; } else if (_this[k]._fqcn) { const marshaller = MarshallerProvider.getForObject(_this[k]); _this[k] = marshaller.marshall(_this[k], ctx); } else { _this[k] = this.marshall(_this[k], ctx); } }); _this[ErraiObjectConstants.ENCODED_TYPE] = fqcn; _this[ErraiObjectConstants.OBJECT_ID] = `${ctx.incrementAndGetObjectId()}`; delete _this._fqcn; return _this; } private unmarshallCustomObject(targetFactory: () => any, input: ErraiObject, ctx: UnmarshallingContext) { // instantiate an empty target object in order to be able to discover the // types of unqualified values present in the JSON const targetObj = targetFactory(); // clone the input, removing non useful fields const _this = { ...(input as any) }; delete _this[ErraiObjectConstants.ENCODED_TYPE]; delete _this[ErraiObjectConstants.OBJECT_ID]; Object.keys(_this).forEach(k => { if (_this[k] === null || _this[k] === undefined) { targetObj[k] = undefined; } else if (_this[k][ErraiObjectConstants.ENCODED_TYPE]) { const fqcn = _this[k][ErraiObjectConstants.ENCODED_TYPE]; targetObj[k] = MarshallerProvider.getForFqcn(fqcn).unmarshall(_this[k], ctx); } else { // no fqcn, try to infer it asking the field's type to the target object const inferredFqcn = DefaultMarshaller.qualifyValue(k, _this[k], targetObj); if (!inferredFqcn) { throw new Error(`Don't know how to unmarshall field ${k} of ${input}`); } targetObj[k] = MarshallerProvider.getForFqcn(inferredFqcn).unmarshall(_this[k], ctx); } }); return targetObj; } private isEnumObject(input: ErraiObject): boolean { return input[ErraiObjectConstants.ENUM_STRING_VALUE] !== undefined; } private static marshallWrappableType(input: any, ctx: MarshallingContext): any { // convert native JS types to a default Java type implementation const wrappedType = JavaWrapperUtils.wrapIfNeeded(input); return MarshallerProvider.getForObject(wrappedType).marshall(wrappedType, ctx); } private static unmarshallJavaType(fqcn: string, input: ErraiObject, ctx: UnmarshallingContext) { if (!JavaWrapperUtils.isJavaType(fqcn)) { throw new Error(`No factory provided for ${fqcn}. Cannot unmarshall.`); } return MarshallerProvider.getForFqcn(fqcn).unmarshall(input, ctx); } private static unmarshallUnqualifiedValue(input: ErraiObject, ctx: UnmarshallingContext) { if (!JavaWrapperUtils.needsWrapping(input)) { // field is not wrappable, so, there's no way to know what is the target object throw new Error("Don't know how to unmarshall types without encoded type"); } // qualify the input (i.e. discover its fqcn) const wrappedType = JavaWrapperUtils.wrapIfNeeded(input); return MarshallerProvider.getForObject(wrappedType).unmarshall((wrappedType as JavaWrapper).get(), ctx); } private static qualifyValue(fieldName: string, fieldValue: any, targetObj: any): string | undefined { if (JavaWrapperUtils.needsWrapping(fieldValue)) { return (JavaWrapperUtils.wrapIfNeeded(fieldValue) as any)._fqcn; } if (targetObj[fieldName] === null || targetObj[fieldName] === undefined) { return undefined; } return (targetObj[fieldName] as any)._fqcn; } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaBigDecimalMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaBigDecimal } from "../../java-wrappers/JavaBigDecimal"; import { ErraiObject } from "../model/ErraiObject"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ValueBasedErraiObject } from "../model/ValueBasedErraiObject"; import { NumberUtils } from "../../util/NumberUtils"; import { isString } from "../../util/TypeUtils"; export class JavaBigDecimalMarshaller extends NullableMarshaller< JavaBigDecimal, ErraiObject, ErraiObject, JavaBigDecimal > { public notNullMarshall(input: JavaBigDecimal, ctx: MarshallingContext): ErraiObject { const fqcn = (input as any)._fqcn; const value = input.get().toString(10); const objectId = ctx.incrementAndGetObjectId().toString(10); return new ValueBasedErraiObject(fqcn, value, objectId).asErraiObject(); } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): JavaBigDecimal { const valueFromJson = ValueBasedErraiObject.from(input).value as string; if (!JavaBigDecimalMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid BigDecimal value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaBigDecimal(valueFromJson); } private static isValid(valueFromJson: string): boolean { if (!valueFromJson) { return false; } if (!isString(valueFromJson)) { return false; } return NumberUtils.isFloatString(valueFromJson); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaBigIntegerMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaBigInteger } from "../../java-wrappers/JavaBigInteger"; import { ErraiObject } from "../model/ErraiObject"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ValueBasedErraiObject } from "../model/ValueBasedErraiObject"; import { NumberUtils } from "../../util/NumberUtils"; import { isString } from "../../util/TypeUtils"; export class JavaBigIntegerMarshaller extends NullableMarshaller< JavaBigInteger, ErraiObject, ErraiObject, JavaBigInteger > { public notNullMarshall(input: JavaBigInteger, ctx: MarshallingContext): ErraiObject { const fqcn = (input as any)._fqcn; const value = input.get().toString(10); const objectId = ctx.incrementAndGetObjectId().toString(10); return new ValueBasedErraiObject(fqcn, value, objectId).asErraiObject(); } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): JavaBigInteger { const valueFromJson = ValueBasedErraiObject.from(input).value as string; if (!JavaBigIntegerMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid BigInteger value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaBigInteger(valueFromJson); } private static isValid(valueFromJson: string): boolean { if (!isString(valueFromJson)) { return false; } if (!valueFromJson) { return false; } return NumberUtils.isIntegerString(valueFromJson); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaBooleanMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaBoolean } from "../../java-wrappers/JavaBoolean"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ErraiObject } from "../model/ErraiObject"; import { instanceOfBoolean } from "../../util/TypeUtils"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; export class JavaBooleanMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaBoolean, ctx: MarshallingContext): boolean { return input.get(); } public notNullUnmarshall(input: ErraiObject | boolean, ctx: UnmarshallingContext): boolean { if (instanceOfBoolean(input)) { return input; } const valueFromJson = NumValBasedErraiObject.from(input).numVal; if (!JavaBooleanMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid boolean value ${valueFromJson}. Can't unmarshall json ${input}`); } return valueFromJson as boolean; } private static isValid(valueFromJson: any): boolean { if (valueFromJson === null || valueFromJson === undefined) { return false; } return instanceOfBoolean(valueFromJson); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaByteMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaByte } from "../../java-wrappers/JavaByte"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ErraiObject } from "../model/ErraiObject"; import { instanceOfNumber } from "../../util/TypeUtils"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; import { NumberUtils } from "../../util/NumberUtils"; export class JavaByteMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaByte, ctx: MarshallingContext): number { return input.get(); } public notNullUnmarshall(input: ErraiObject | number, ctx: UnmarshallingContext): JavaByte { const valueFromJson = instanceOfNumber(input) ? input : NumValBasedErraiObject.from(input).numVal; if (!JavaByteMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid byte value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaByte(`${valueFromJson}`); } private static isValid(valueFromJson: any): boolean { if (valueFromJson === null || valueFromJson === undefined) { return false; } if (!instanceOfNumber(valueFromJson)) { return false; } return NumberUtils.isIntegerString(`${valueFromJson}`); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaCollectionMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaCollection } from "../../java-wrappers/JavaCollection"; import { ErraiObject } from "../model/ErraiObject"; import { MarshallingContext } from "../MarshallingContext"; import { Portable } from "../Portable"; import { NullableMarshaller } from "./NullableMarshaller"; import { GenericsTypeMarshallingUtils } from "./util/GenericsTypeMarshallingUtils"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { isArray } from "../../util/TypeUtils"; import { JavaArrayList, JavaHashSet } from "../../java-wrappers"; import { ValueBasedErraiObject } from "../model/ValueBasedErraiObject"; import { MarshallerProvider } from "../MarshallerProvider"; abstract class JavaCollectionMarshaller | null>> extends NullableMarshaller< JavaCollection, ErraiObject, ErraiObject, T > { public notNullMarshall(input: JavaCollection, ctx: MarshallingContext): ErraiObject { const cachedObject = ctx.getCached(input); if (cachedObject) { return cachedObject; } const elements = input.get(); const serializedValues = []; for (const element of Array.from(elements)) { serializedValues.push(GenericsTypeMarshallingUtils.marshallGenericsTypeElement(element, ctx)); } const fqcn = (input as any)._fqcn; const value = serializedValues; const objectId = ctx.incrementAndGetObjectId().toString(10); const resultObject = new ValueBasedErraiObject(fqcn, value, objectId).asErraiObject(); ctx.cacheObject(input, resultObject); return resultObject; } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): T { const cachedObject = ctx.getCached(input); if (cachedObject) { return (cachedObject as JavaCollection).get(); } const collection = ValueBasedErraiObject.from(input).value; if (!JavaCollectionMarshaller.isValid(collection)) { throw new Error(`Invalid collection value ${collection}. Can't unmarshall json ${input}`); } const unmarshalledValues = []; for (const element of Array.from(collection)) { unmarshalledValues.push(MarshallerProvider.getForObject(element).unmarshall(element, ctx)); } const javaCollection = this.fromArray(unmarshalledValues); ctx.cacheObject(input, javaCollection); return javaCollection.get(); } protected abstract fromArray(values: Array>): JavaCollection; private static isValid(input: any): boolean { if (input === null || input === undefined) { return false; } // inside the json, all collections are represented as an array return isArray(input); } } export class JavaArrayListMarshaller extends JavaCollectionMarshaller | null>> { protected fromArray(values: Array>): JavaArrayList> { return new JavaArrayList(values); } } export class JavaHashSetMarshaller extends JavaCollectionMarshaller | null>> { protected fromArray(values: Array>): JavaHashSet> { return new JavaHashSet(new Set(values)); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaDateMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaDate } from "../../java-wrappers/JavaDate"; import { ErraiObject } from "../model/ErraiObject"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { isString } from "../../util/TypeUtils"; import { ValueBasedErraiObject } from "../model/ValueBasedErraiObject"; import { NumberUtils } from "../../util/NumberUtils"; export class JavaDateMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaDate, ctx: MarshallingContext): ErraiObject { return new ValueBasedErraiObject((input as any)._fqcn, `${input.get().getTime()}`).asErraiObject(); } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): Date { const valueFromJson = ValueBasedErraiObject.from(input).value; if (!JavaDateMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid date value ${valueFromJson}. Can't unmarshall json ${input}`); } const asNumber = Number.parseInt(valueFromJson, 10); return new Date(asNumber); } private static isValid(input: any) { if (!input) { return false; } if (!isString(input)) { return false; } return NumberUtils.isNonNegativeIntegerString(input); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaDoubleMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaDouble } from "../../java-wrappers/JavaDouble"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ErraiObject } from "../model/ErraiObject"; import { instanceOfNumber } from "../../util/TypeUtils"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; export class JavaDoubleMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaDouble, ctx: MarshallingContext): number { return input.get(); } public notNullUnmarshall(input: ErraiObject | number, ctx: UnmarshallingContext): JavaDouble { if (instanceOfNumber(input)) { return new JavaDouble(`${input}`); } const valueFromJson = NumValBasedErraiObject.from(input).numVal; if (!JavaDoubleMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid double value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaDouble(`${valueFromJson}`); } private static isValid(valueFromJson: any): boolean { if (valueFromJson === null || valueFromJson === undefined) { return false; } return instanceOfNumber(valueFromJson); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaEnumMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaEnum } from "../../java-wrappers"; import { ErraiObject } from "../model/ErraiObject"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { EnumStringValueBasedErraiObject } from "../model/EnumStringValueBasedErraiObject"; export class JavaEnumMarshaller> extends NullableMarshaller< JavaEnum, ErraiObject, ErraiObject, JavaEnum > { public notNullMarshall(input: JavaEnum, ctx: MarshallingContext): ErraiObject { return new EnumStringValueBasedErraiObject((input as any)._fqcn, input.name).asErraiObject(); } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): JavaEnum { const valueObject = EnumStringValueBasedErraiObject.from(input); const factory = ctx.getFactory(valueObject.encodedType); // the factory method for enums receives the enum name and returns the appropriate enum value return (factory as any)(valueObject.enumValueName); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaFloatMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { JavaFloat } from "../../java-wrappers/JavaFloat"; import { MarshallingContext } from "../MarshallingContext"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { instanceOfNumber } from "../../util/TypeUtils"; import { ErraiObject } from "../model/ErraiObject"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; export class JavaFloatMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaFloat, ctx: MarshallingContext): number { return input.get(); } public notNullUnmarshall(input: ErraiObject | number, ctx: UnmarshallingContext): JavaFloat { if (instanceOfNumber(input)) { return new JavaFloat(`${input}`); } const valueFromJson = NumValBasedErraiObject.from(input).numVal; if (!JavaFloatMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid float value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaFloat(`${valueFromJson}`); } private static isValid(valueFromJson: any): boolean { if (valueFromJson === null || valueFromJson === undefined) { return false; } return instanceOfNumber(valueFromJson); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaHashMapMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NullableMarshaller } from "./NullableMarshaller"; import { ErraiObjectConstants } from "../model/ErraiObjectConstants"; import { GenericsTypeMarshallingUtils } from "./util/GenericsTypeMarshallingUtils"; import { JavaHashMap } from "../../java-wrappers/JavaHashMap"; import { MarshallingContext } from "../MarshallingContext"; import { ErraiObject } from "../model/ErraiObject"; import { isString } from "../../util/TypeUtils"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ValueBasedErraiObject } from "../model/ValueBasedErraiObject"; import { MarshallerProvider } from "../MarshallerProvider"; export class JavaHashMapMarshaller extends NullableMarshaller< JavaHashMap, ErraiObject, ErraiObject, Map > { public notNullMarshall(input: JavaHashMap, ctx: MarshallingContext): ErraiObject { const cachedObject = ctx.getCached(input); if (cachedObject) { return cachedObject; } const marshalledEntriesMap = this.marshallEntries(input.get().entries(), ctx); const fqcn = (input as any)._fqcn; const value = marshalledEntriesMap; const objectId = ctx.incrementAndGetObjectId().toString(10); const result = new ValueBasedErraiObject(fqcn, value, objectId).asErraiObject(); ctx.cacheObject(input, result); return result; } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): Map { const cachedObject = ctx.getCached(input); if (cachedObject) { return (cachedObject as JavaHashMap).get(); } const mapObj = ValueBasedErraiObject.from(input).value; if (!mapObj) { throw new Error(`Invalid Map value ${mapObj}. Can't unmarshall json ${input}`); } const map = this.unmarshallEntries(mapObj, ctx); ctx.cacheObject(input, map); return map.get(); } private marshallEntries(entries: IterableIterator<[T, U]>, ctx: MarshallingContext) { return Array.from(entries) .map(([key, value]) => this.marshallEntry(key, value, ctx)) .reduce((acc, cur) => ({ ...acc, ...cur }), {}); } private marshallEntry(key: T, value: U, ctx: MarshallingContext) { const marshalledKey = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(key, ctx); const marshalledValue = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(value, ctx); if (marshalledKey === null) { return { [ErraiObjectConstants.NULL]: marshalledValue }; } if (!isString(marshalledKey)) { // need to prefix the key in order to tell errai-marshalling that the key is not a native string return { [ErraiObjectConstants.JSON + JSON.stringify(marshalledKey)]: marshalledValue }; } return { [`${marshalledKey}`]: marshalledValue }; } private unmarshallEntries(map: any, ctx: UnmarshallingContext): JavaHashMap { const unmarshalledMap = new Map(); Object.keys(map).forEach(key => { const unmarshalledKey = this.unmarshallKey(key, ctx); const unmarshalledValue = MarshallerProvider.getForObject(map[key]).unmarshall(map[key], ctx); unmarshalledMap.set(unmarshalledKey, unmarshalledValue); }); return new JavaHashMap(unmarshalledMap); } private unmarshallKey(key: string, ctx: UnmarshallingContext): T | undefined { if (!key) { throw new Error(`Invalid Map's key ${key}. Can't unmarshall json!`); } if (key === ErraiObjectConstants.NULL) { return undefined; } if (key.startsWith(ErraiObjectConstants.JSON)) { // this prefix indicates that the key is not a native string, it is a json object serialized to string const keyJson = JSON.parse(key.replace(ErraiObjectConstants.JSON, "")); return MarshallerProvider.getForObject(keyJson).unmarshall(keyJson, ctx); } // the map key has type string return key as any; } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaIntegerMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../MarshallingContext"; import { JavaInteger } from "../../java-wrappers/JavaInteger"; import { NullableMarshaller } from "./NullableMarshaller"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ErraiObject } from "../model/ErraiObject"; import { instanceOfNumber } from "../../util/TypeUtils"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; import { NumberUtils } from "../../util/NumberUtils"; export class JavaIntegerMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaInteger, ctx: MarshallingContext): number { return input.get(); } public notNullUnmarshall(input: ErraiObject | number, ctx: UnmarshallingContext): JavaInteger { const valueFromJson = instanceOfNumber(input) ? input : NumValBasedErraiObject.from(input).numVal; if (!JavaIntegerMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid integer value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaInteger(`${valueFromJson}`); } private static isValid(valueFromJson: any): boolean { if (valueFromJson === null || valueFromJson === undefined) { return false; } if (!instanceOfNumber(valueFromJson)) { return false; } return NumberUtils.isIntegerString(`${valueFromJson}`); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaLongMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaLong } from "../../java-wrappers/JavaLong"; import { ErraiObject } from "../model/ErraiObject"; import { MarshallingContext } from "../MarshallingContext"; import { NullableMarshaller } from "./NullableMarshaller"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; import { NumberUtils } from "../../util/NumberUtils"; export class JavaLongMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaLong, ctx: MarshallingContext): ErraiObject { const asString = `${input.get().toString(10)}`; return new NumValBasedErraiObject((input as any)._fqcn, asString).asErraiObject(); } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): JavaLong { const valueFromJson = NumValBasedErraiObject.from(input).numVal as string; if (!JavaLongMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid long value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaLong(valueFromJson); } private static isValid(jsonValue: string) { if (jsonValue === null || jsonValue === undefined) { return false; } return NumberUtils.isIntegerString(jsonValue); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaOptionalMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../MarshallingContext"; import { NullableMarshaller } from "./NullableMarshaller"; import { JavaOptional } from "../../java-wrappers/JavaOptional"; import { ErraiObject } from "../model/ErraiObject"; import { GenericsTypeMarshallingUtils } from "./util/GenericsTypeMarshallingUtils"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { ValueBasedErraiObject } from "../model/ValueBasedErraiObject"; import { MarshallerProvider } from "../MarshallerProvider"; export class JavaOptionalMarshaller extends NullableMarshaller< JavaOptional, ErraiObject, ErraiObject, JavaOptional > { public notNullMarshall(input: JavaOptional, ctx: MarshallingContext): ErraiObject { const innerValue = this.retrieveOptionalInnerValue(input, ctx); return new ValueBasedErraiObject((input as any)._fqcn, innerValue).asErraiObject(); } public notNullUnmarshall(input: ErraiObject, ctx: UnmarshallingContext): JavaOptional { const value = ValueBasedErraiObject.from(input).value; if (value === null || value === undefined) { return new JavaOptional(undefined); } const unmarshalledValue = MarshallerProvider.getForObject(value).unmarshall(value, ctx); return new JavaOptional(unmarshalledValue); } private retrieveOptionalInnerValue(input: JavaOptional, ctx: MarshallingContext) { if (!input.isPresent()) { return null; } return GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input.get(), ctx); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaShortMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaShort } from "../../java-wrappers/JavaShort"; import { MarshallingContext } from "../MarshallingContext"; import { NullableMarshaller } from "./NullableMarshaller"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { instanceOfNumber } from "../../util/TypeUtils"; import { ErraiObject } from "../model/ErraiObject"; import { NumValBasedErraiObject } from "../model/NumValBasedErraiObject"; import { NumberUtils } from "../../util/NumberUtils"; export class JavaShortMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaShort, ctx: MarshallingContext): number { return input.get(); } public notNullUnmarshall(input: ErraiObject | number, ctx: UnmarshallingContext): JavaShort { const valueFromJson = instanceOfNumber(input) ? input : NumValBasedErraiObject.from(input).numVal; if (!JavaShortMarshaller.isValid(valueFromJson)) { throw new Error(`Invalid short value ${valueFromJson}. Can't unmarshall json ${input}`); } return new JavaShort(`${valueFromJson}`); } private static isValid(valueFromJson: any): boolean { if (valueFromJson === null || valueFromJson === undefined) { return false; } if (!instanceOfNumber(valueFromJson)) { return false; } return NumberUtils.isIntegerString(`${valueFromJson}`); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/JavaStringMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaString } from "../../java-wrappers/JavaString"; import { MarshallingContext } from "../MarshallingContext"; import { NullableMarshaller } from "./NullableMarshaller"; import { UnmarshallingContext } from "../UnmarshallingContext"; import { instanceOfString } from "../../util/TypeUtils"; export class JavaStringMarshaller extends NullableMarshaller { public notNullMarshall(input: JavaString, ctx: MarshallingContext): string { return input.get(); } public notNullUnmarshall(input: string | JavaString, ctx: UnmarshallingContext): string { if (instanceOfString(input)) { return input; } return input.get(); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/NullableMarshaller.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../MarshallingContext"; import { Marshaller } from "../Marshaller"; import { Portable } from "../Portable"; import { UnmarshallingContext } from "../UnmarshallingContext"; export abstract class NullableMarshaller, U, V, X> implements Marshaller { public marshall(input: T, ctx: MarshallingContext): U | null { if (input === null || input === undefined) { return null; } return this.notNullMarshall(input, ctx); } public unmarshall(input: V | undefined, ctx: UnmarshallingContext): X | undefined { if (input === null || input === undefined) { return undefined; } return this.notNullUnmarshall(input, ctx); } public abstract notNullMarshall(input: T, ctx: MarshallingContext): U; public abstract notNullUnmarshall(input: V, ctx: UnmarshallingContext): X; } ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/DefaultMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaArrayList, JavaBigDecimal, JavaBigInteger, JavaBoolean, JavaByte, JavaDate, JavaDouble, JavaEnum, JavaFloat, JavaHashMap, JavaHashSet, JavaInteger, JavaLong, JavaOptional, JavaShort, JavaString } from "../../../java-wrappers"; import { DefaultMarshaller } from "../DefaultMarshaller"; import { MarshallingContext } from "../../MarshallingContext"; import { ErraiObjectConstants } from "../../model/ErraiObjectConstants"; import { MarshallerProvider } from "../../MarshallerProvider"; import { Portable } from "../../Portable"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { ValueBasedErraiObject } from "../../model/ValueBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; import { NumberUtils } from "../../../util/NumberUtils"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { EnumStringValueBasedErraiObject } from "../../model/EnumStringValueBasedErraiObject"; beforeEach(() => { MarshallerProvider.initialize(); }); describe("marshall", () => { const objectId = ErraiObjectConstants.OBJECT_ID; const encodedType = ErraiObjectConstants.ENCODED_TYPE; const value = ErraiObjectConstants.VALUE; const enumStringValue = ErraiObjectConstants.ENUM_STRING_VALUE; describe("pojo marshalling", () => { test("custom pojo, should return serialize it normally", () => { const input = new User({ name: "my name", sendSpam: false, age: new JavaInteger("10"), address: new Address({ line1: "address line 1", type: AddressType.WORK }), bestFriend: new User({ name: "my name 2", sendSpam: true, address: new Address({ line1: "address 2 line 1" }) }) }); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: "com.app.my.Pojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), name: "my name", age: 10, sendSpam: false, address: { [encodedType]: "com.app.my.Address", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), line1: "address line 1", type: new EnumStringValueBasedErraiObject("com.app.my.AddressType", AddressType.WORK.name).asErraiObject() }, bestFriend: { [encodedType]: "com.app.my.Pojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), name: "my name 2", sendSpam: true, age: null, address: { [encodedType]: "com.app.my.Address", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), line1: "address 2 line 1", type: null }, bestFriend: null } }); }); test("custom pojo with function, should serialize it normally and ignore the function", () => { const input = { _fqcn: "com.app.my.Pojo", foo: "bar", doSomething: () => { return "hey!"; } }; const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: "com.app.my.Pojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "bar" }); }); test("custom pojo without fqcn, should throw error", () => { const input = { foo: "bar" }; const context = new MarshallingContext(); const marshaller = new DefaultMarshaller(); expect(() => marshaller.marshall(input, context)).toThrowError(); }); test("custom pojo with a pojo without fqcn as property, should throw error", () => { const input = { _fqcn: "com.app.my.Pojo", name: "my name", childPojo: { foo: "bar" } }; const context = new MarshallingContext(); const marshaller = new DefaultMarshaller(); expect(() => marshaller.marshall(input, context)).toThrowError(); }); test("custom pojo with java types, should serialize it normally", () => { const date = new Date(); const input = new JavaTypesPojo({ bigDecimal: new JavaBigDecimal("1.1"), bigInteger: new JavaBigInteger("2"), boolean: false, byte: new JavaByte("3"), double: new JavaDouble("1.2"), float: new JavaFloat("1.3"), integer: new JavaInteger("4"), long: new JavaLong("5"), short: new JavaShort("6"), string: "str", date: new Date(date), optional: new JavaOptional("optstr") }); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: "com.app.my.Pojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), bigDecimal: { [encodedType]: JavaType.BIG_DECIMAL, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "1.1" }, bigInteger: { [encodedType]: JavaType.BIG_INTEGER, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "2" }, boolean: false, byte: 3, double: 1.2, float: 1.3, integer: 4, long: new NumValBasedErraiObject(JavaType.LONG, "5").asErraiObject(), short: 6, string: "str", date: new ValueBasedErraiObject(JavaType.DATE, `${date.getTime()}`).asErraiObject(), optional: new ValueBasedErraiObject(JavaType.OPTIONAL, "optstr").asErraiObject() }); }); test("custom pojo with collection type, should serialize it normally", () => { const input = { _fqcn: "com.app.my.Pojo", list: ["1", "2", "3"], set: new Set(["3", "2", "1"]), map: new Map([["k1", "v1"], ["k2", "v2"]]) }; const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: "com.app.my.Pojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), list: { [encodedType]: JavaType.ARRAY_LIST, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: ["1", "2", "3"] }, set: { [encodedType]: JavaType.HASH_SET, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: ["3", "2", "1"] }, map: { [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { k1: "v1", k2: "v2" } } }); }); test("custom pojo with enum type, should serialize it normally", () => { const input = { _fqcn: "com.app.my.Pojo", str: "foo", enum: AddressType.HOME }; const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: "com.app.my.Pojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), str: "foo", enum: new EnumStringValueBasedErraiObject("com.app.my.AddressType", AddressType.HOME.name).asErraiObject() }); }); }); describe("object caching", () => { test("custom pojo with repeated pojo objects, should cache the object and don't repeat data", () => { // === scenario // repeatedNode appears two times in the hierarchy, all other nodes are unique const repeatedNode = new Node({ data: "repeatedNode" }); const input = new Node({ data: "root", right: new Node({ data: "rightNode", left: repeatedNode, right: new Node({ data: "rightLeaf" }) }), left: repeatedNode }); // === test const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); // === assertion // expects all nodes to contain their data and a unique objectId, except for the deepest left node. // the deepest left node should contain only its encodedType and objectId, which needs to be the same as the root's left node const rootObjId = output![objectId]; expect(output![encodedType]).toEqual("com.app.my.Node"); expect((output as any).data).toEqual("root"); const firstLeftLeaf = (output as any).left; const firstLeftLeafObjId = firstLeftLeaf[objectId]; expect(firstLeftLeaf.data).toEqual("repeatedNode"); const rightNodeOut = (output as any).right; const rightNodeObjId = rightNodeOut[objectId]; expect(rightNodeOut.data).toEqual("rightNode"); const repeatedLeftLeaf = (rightNodeOut as any).left; const repeatedLeftLeafObjId = repeatedLeftLeaf[objectId]; expect(repeatedLeftLeaf.data).toBeUndefined(); const rightLeafOut = (rightNodeOut as any).right; const rightLeafObjId = rightLeafOut[objectId]; expect(rightLeafOut.data).toEqual("rightLeaf"); expect(firstLeftLeafObjId).toEqual(repeatedLeftLeafObjId); // reuse same id const allObjIds = [rootObjId, firstLeftLeafObjId, rightNodeObjId, repeatedLeftLeafObjId, rightLeafObjId]; expect(allObjIds.forEach(id => expect(id).toMatch(NumberUtils.nonNegativeIntegerRegex))); // all ids unique (excluding the reused one) const uniqueObjIds = new Set(allObjIds); expect(uniqueObjIds).toStrictEqual(new Set([rootObjId, firstLeftLeafObjId, rightNodeObjId, rightLeafObjId])); }); test("custom pojo with repeated JavaBigDecimal objects, should not cache it and not reuse data", () => { const repeatedValue = new JavaBigDecimal("1.1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaBigDecimal("1.2") }), right: new Node({ data: repeatedValue }) }); // === test const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootDataObjId = (output as any).data[objectId]; expect((output as any).data[value]).toEqual("1.1"); const leftObjId = (output as any).left[objectId]; const leftDataObjId = (output as any).left.data[objectId]; expect((output as any).left.data[value]).toEqual("1.2"); const rightObjId = (output as any).right[objectId]; const rightDataObjId = (output as any).right.data[objectId]; expect((output as any).right.data[value]).toEqual("1.1"); const allObjectIds = [rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId, rightDataObjId]; allObjectIds.forEach(id => expect(id).toBeDefined()); // create new object ids even for same obj references expect(new Set(allObjectIds)).toStrictEqual(new Set(allObjectIds)); // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaBigInteger objects, should not cache it", () => { const repeatedValue = new JavaBigInteger("1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaBigInteger("2") }), right: new Node({ data: repeatedValue }) }); // === test const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootDataObjId = (output as any).data[objectId]; expect((output as any).data[value]).toEqual("1"); const leftObjId = (output as any).left[objectId]; const leftDataObjId = (output as any).left.data[objectId]; expect((output as any).left.data[value]).toEqual("2"); const rightObjId = (output as any).right[objectId]; const rightDataObjId = (output as any).right.data[objectId]; expect((output as any).right.data[value]).toEqual("1"); const allObjectIds = [rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId, rightDataObjId]; allObjectIds.forEach(id => expect(id).toBeDefined()); // create new object ids even for same obj references expect(new Set(allObjectIds)).toStrictEqual(new Set(allObjectIds)); // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaBoolean objects, should not cache it", () => { const repeatedValue = new JavaBoolean(false); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaBoolean(true) }), right: new Node({ data: repeatedValue }) }); const context = new MarshallingContext(); new DefaultMarshaller().marshall(input, context); // in this test we're not interested in the output structure, because Boolean types are not wrapped into an // ErraiObject, so, it doesn't even have an objectId assigned. // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaByte objects, should not cache it", () => { const repeatedValue = new JavaByte("1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaByte("2") }), right: new Node({ data: repeatedValue }) }); const context = new MarshallingContext(); new DefaultMarshaller().marshall(input, context); // in this test we're not interested in the output structure, because Byte types are not wrapped into an // ErraiObject, so, it doesn't even have an objectId assigned. // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated array objects, should cache the object and don't repeat data", () => { const repeatedValue = ["a", "b", "c"]; const arrayInput = new Node({ data: repeatedValue, left: new Node({ data: ["d", "e"] }), right: new Node({ data: repeatedValue }) }); const javaArrayListInput = new Node({ data: new JavaArrayList(repeatedValue), left: new Node({ data: new JavaArrayList(["d", "e"]) }), right: new Node({ data: new JavaArrayList(repeatedValue) }) }); [arrayInput, javaArrayListInput].forEach(input => { const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootDataObjId = (output as any).data[objectId]; expect((output as any).data).toStrictEqual({ [encodedType]: JavaType.ARRAY_LIST, [objectId]: expect.anything(), [value]: ["a", "b", "c"] }); const leftObjId = (output as any).left[objectId]; const leftDataObjId = (output as any).left.data[objectId]; expect((output as any).left.data).toStrictEqual({ [encodedType]: JavaType.ARRAY_LIST, [objectId]: expect.anything(), [value]: ["d", "e"] }); const rightObjId = (output as any).right[objectId]; const rightDataObjId = (output as any).right.data[objectId]; expect((output as any).right.data).toStrictEqual({ [encodedType]: JavaType.ARRAY_LIST, [objectId]: expect.anything() // missing value since it is cached }); const allObjectIds = [rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId, rightDataObjId]; allObjectIds.forEach(id => expect(id).toBeDefined()); // all ids are unique except for the right data id, that was reused expect(new Set(allObjectIds)).toStrictEqual( new Set([rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId]) ); // do not cache repeated object const cached = context.getCached(repeatedValue); expect(ValueBasedErraiObject.from(cached!)).toStrictEqual( new ValueBasedErraiObject(JavaType.ARRAY_LIST, undefined, rootDataObjId) ); }); }); test("custom pojo with repeated set objects, should cache the object and don't repeat data", () => { const repeatedValue = new Set(["a", "b", "c"]); const setInput = new Node({ data: repeatedValue, left: new Node({ data: new Set(["d", "e"]) }), right: new Node({ data: repeatedValue }) }); const javaHashSetInput = new Node({ data: new JavaHashSet(repeatedValue), left: new Node({ data: new JavaHashSet(new Set(["d", "e"])) }), right: new Node({ data: new JavaHashSet(repeatedValue) }) }); [setInput, javaHashSetInput].forEach(input => { const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootDataObjId = (output as any).data[objectId]; expect((output as any).data).toStrictEqual({ [encodedType]: JavaType.HASH_SET, [objectId]: expect.anything(), [value]: ["a", "b", "c"] }); const leftObjId = (output as any).left[objectId]; const leftDataObjId = (output as any).left.data[objectId]; expect((output as any).left.data).toStrictEqual({ [encodedType]: JavaType.HASH_SET, [objectId]: expect.anything(), [value]: ["d", "e"] }); const rightObjId = (output as any).right[objectId]; const rightDataObjId = (output as any).right.data[objectId]; expect((output as any).right.data).toStrictEqual({ [encodedType]: JavaType.HASH_SET, [objectId]: expect.anything() // missing value since it is cached }); const allObjectIds = [rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId, rightDataObjId]; allObjectIds.forEach(id => expect(id).toBeDefined()); // all ids are unique except for the right data id, that was reused expect(new Set(allObjectIds)).toStrictEqual( new Set([rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId]) ); // do not cache repeated object const cached = context.getCached(repeatedValue); expect(ValueBasedErraiObject.from(cached!)).toStrictEqual( new ValueBasedErraiObject(JavaType.HASH_SET, undefined, rootDataObjId) ); }); }); test("custom pojo with repeated map objects, should cache the object and don't repeat data", () => { const repeatedMap = new Map([["k1", "v1"]]); const mapInput = new Node({ data: repeatedMap, left: new Node({ data: new Map([["k2", "v2"]]) }), right: new Node({ data: repeatedMap }) }); const javaHashMapInput = new Node({ data: new JavaHashMap(repeatedMap), left: new Node({ data: new JavaHashMap(new Map([["k2", "v2"]])) }), right: new Node({ data: new JavaHashMap(repeatedMap) }) }); [mapInput, javaHashMapInput].forEach(input => { const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootDataObjId = (output as any).data[objectId]; expect((output as any).data).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.anything(), [value]: { k1: "v1" } }); const leftObjId = (output as any).left[objectId]; const leftDataObjId = (output as any).left.data[objectId]; expect((output as any).left.data).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.anything(), [value]: { k2: "v2" } }); const rightObjId = (output as any).right[objectId]; const rightDataObjId = (output as any).right.data[objectId]; expect((output as any).right.data).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.anything() // missing value since it is cached }); const allObjectIds = [rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId, rightDataObjId]; allObjectIds.forEach(id => expect(id).toBeDefined()); // all ids are unique except for the right data id, that was reused expect(new Set(allObjectIds)).toStrictEqual( new Set([rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId]) ); // do not cache repeated object's data const cached = context.getCached(repeatedMap); expect(ValueBasedErraiObject.from(cached!)).toStrictEqual( new ValueBasedErraiObject(JavaType.HASH_MAP, undefined, rootDataObjId) ); }); }); test("custom pojo with repeated JavaDouble objects, should not cache it", () => { const repeatedValue = new JavaDouble("1.1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaDouble("1.2") }), right: new Node({ data: repeatedValue }) }); const context = new MarshallingContext(); new DefaultMarshaller().marshall(input, context); // in this test we're not interested in the output structure, because Double types are not wrapped into an // ErraiObject, so, it doesn't even have an objectId assigned. // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaFloat objects, should not cache it", () => { const repeatedValue = new JavaFloat("1.1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaFloat("1.2") }), right: new Node({ data: repeatedValue }) }); const context = new MarshallingContext(); new DefaultMarshaller().marshall(input, context); // in this test we're not interested in the output structure, because Float types are not wrapped into an // ErraiObject, so, it doesn't even have an objectId assigned. // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaInteger objects, should not cache it", () => { const repeatedValue = new JavaInteger("1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaInteger("2") }), right: new Node({ data: repeatedValue }) }); const context = new MarshallingContext(); new DefaultMarshaller().marshall(input, context); // in this test we're not interested in the output structure, because Integer types are not wrapped into an // ErraiObject, so, it doesn't even have an objectId assigned. // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaLong objects, should not cache it", () => { const repeatedValue = new JavaLong("1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaLong("2") }), right: new Node({ data: repeatedValue }) }); // === test const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootData = NumValBasedErraiObject.from((output as any).data); expect(rootData.numVal).toEqual("1"); const leftObj = NumValBasedErraiObject.from((output as any).left); const leftData = NumValBasedErraiObject.from((output as any).left.data); expect(leftData.numVal).toEqual("2"); const rightObj = NumValBasedErraiObject.from((output as any).right); const rightData = NumValBasedErraiObject.from((output as any).right.data); expect(rightData.numVal).toEqual("1"); const allObjectIds = [rootObjId, rootData.objId, leftObj.objId, leftData.objId, rightObj.objId, rightData.objId]; allObjectIds.forEach(id => expect(id).toBeDefined()); // create new object ids even for same obj references expect(new Set(allObjectIds)).toStrictEqual(new Set(allObjectIds)); // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaShort objects, should not cache it", () => { const repeatedValue = new JavaShort("1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaShort("2") }), right: new Node({ data: repeatedValue }) }); const context = new MarshallingContext(); new DefaultMarshaller().marshall(input, context); // in this test we're not interested in the output structure, because Short types are not wrapped into an // ErraiObject, so, it doesn't even have an objectId assigned. // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaString objects, should not cache it", () => { const repeatedValue = new JavaString("str1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaString("str2") }), right: new Node({ data: repeatedValue }) }); const context = new MarshallingContext(); new DefaultMarshaller().marshall(input, context); // in this test we're not interested in the output structure, because String types are not wrapped into an // ErraiObject, so, it doesn't even have an objectId assigned. // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaOptional objects, should not cache it", () => { const repeatedValue = new JavaOptional("str1"); const input = new Node({ data: repeatedValue, left: new Node({ data: new JavaOptional("str2") }), right: new Node({ data: repeatedValue }) }); // === test const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootDataObjId = (output as any).data[objectId]; expect((output as any).data[value]).toStrictEqual("str1"); const leftObjId = (output as any).left[objectId]; const leftDataObjId = (output as any).left.data[objectId]; expect((output as any).left.data[value]).toEqual("str2"); const rightObjId = (output as any).right[objectId]; const rightDataObjId = (output as any).right.data[objectId]; expect((output as any).right.data[value]).toEqual("str1"); const allObjectIds = [rootObjId, rootDataObjId, leftObjId, leftDataObjId, rightObjId, rightDataObjId]; allObjectIds.forEach(id => expect(id).toBeDefined()); // optional objects always use the same object id (its value doesn't matter) expect(new Set(allObjectIds)).toStrictEqual(new Set([rootObjId, rootDataObjId, leftObjId, rightObjId])); expect(rootDataObjId).toEqual(leftDataObjId); expect(rootDataObjId).toEqual(rightDataObjId); // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); test("custom pojo with repeated JavaEnum objects, should not cache it", () => { const repeatedValue = AddressType.WORK; const input = new Node({ data: repeatedValue, left: new Node({ data: AddressType.HOME }), right: new Node({ data: repeatedValue }) }); // === test const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context); // === assertions const rootObjId = output![objectId]; const rootDataObjId = (output as any).data[objectId]; expect((output as any).data[enumStringValue]).toStrictEqual(AddressType.WORK.name); const leftObjId = (output as any).left[objectId]; const leftDataObjId = (output as any).left.data[objectId]; expect((output as any).left.data[enumStringValue]).toEqual(AddressType.HOME.name); const rightObjId = (output as any).right[objectId]; const rightDataObjId = (output as any).right.data[objectId]; expect((output as any).right.data[enumStringValue]).toEqual(AddressType.WORK.name); // every Node object has an unique id expect(new Set([rootObjId, leftObjId, rightObjId])).toStrictEqual(new Set([rootObjId, leftObjId, rightObjId])); // every enum field doesn't have an object id defined [rootDataObjId, rightDataObjId, leftDataObjId].forEach(id => expect(id).toBeUndefined()); // do not cache repeated object expect(context.getCached(repeatedValue)).toBeUndefined(); }); }); describe("non-pojo root types", () => { test("root null object, should serialize to null", () => { const input = null as any; const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root JavaBigDecimal object, should serialize it normally", () => { const input = new JavaBigDecimal("1.2"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.BIG_DECIMAL, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "1.2" }); }); test("root JavaBigInteger object, should serialize it normally", () => { const input = new JavaBigInteger("1"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.BIG_INTEGER, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "1" }); }); test("root JavaByte object, should serialize it to byte raw value", () => { const input = new JavaByte("1"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toEqual(1); }); test("root JavaDouble object, should serialize it to double raw value", () => { const input = new JavaDouble("1.1"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toEqual(1.1); }); test("root JavaFloat object, should serialize it to float raw value", () => { const input = new JavaFloat("1.1"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toEqual(1.1); }); test("root JavaInteger object, should serialize it to integer raw value", () => { const input = new JavaInteger("1"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toEqual(1); }); test("root JavaLong object, should serialize it normally", () => { const input = new JavaLong("1"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(new NumValBasedErraiObject(JavaType.LONG, "1").asErraiObject()); }); test("root JavaShort object, should serialize it normally to short raw value", () => { const input = new JavaShort("1"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toEqual(1); }); test("root JavaOptional object, should serialize it normally", () => { const input = new JavaOptional("str"); const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(new ValueBasedErraiObject(JavaType.OPTIONAL, "str").asErraiObject()); }); test("root JavaEnum object, should serialize it normally", () => { const input = AddressType.WORK; const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual( new EnumStringValueBasedErraiObject(AddressType.__fqcn(), AddressType.WORK.name).asErraiObject() ); }); test("root string object, should serialize it to string raw value", () => { const stringInput = "str"; const javaStringInput = new JavaString("str"); [stringInput, javaStringInput].forEach(input => { const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toEqual("str"); }); }); test("root date object, should serialize it normally", () => { const date = new Date(); const javaDate = new JavaDate(date); [date, javaDate].forEach(input => { const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(new ValueBasedErraiObject(JavaType.DATE, `${date.getTime()}`).asErraiObject()); }); }); test("root boolean object, should serialize it to boolean raw value", () => { const booleanInput = false; const javaBooleanInput = new JavaBoolean(false); [booleanInput, javaBooleanInput].forEach(input => { const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toEqual(false); }); }); test("root number object, should throw error", () => { const input = 125.1; const marshaller = new DefaultMarshaller(); const ctx = new MarshallingContext(); expect(() => marshaller.marshall(input, ctx)).toThrowError(); }); test("root array object, should serialize it normally", () => { const arrayInput = ["1", "2", "3"]; const javaArrayListInput = new JavaArrayList(["1", "2", "3"]); [arrayInput, javaArrayListInput].forEach(input => { const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.ARRAY_LIST, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: ["1", "2", "3"] }); }); }); test("root set object, should serialize it normally", () => { const setInput = new Set(["1", "2", "3"]); const javaHashSetInput = new JavaHashSet(new Set(["1", "2", "3"])); [setInput, javaHashSetInput].forEach(input => { const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_SET, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: ["1", "2", "3"] }); }); }); test("root map object, should serialize it normally", () => { const mapInput = new Map([["k1", "v1"], ["k2", "v2"]]); const javaHashMapInput = new JavaHashMap(new Map([["k1", "v1"], ["k2", "v2"]])); [mapInput, javaHashMapInput].forEach(input => { const output = new DefaultMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { k1: "v1", k2: "v2" } }); }); }); }); class Node implements Portable { private readonly _fqcn = "com.app.my.Node"; public readonly data?: any = undefined; public readonly left?: Node = undefined; public readonly right?: Node = undefined; constructor(self: { data?: any; left?: Node; right?: Node }) { Object.assign(this, self); } } }); describe("unmarshall", () => { describe("non-pojo root types", () => { test("root null object, should unmarshall to undefined", () => { const marshaller = new DefaultMarshaller(); const input = null as any; const marshalledInput = marshaller.marshall(input, new MarshallingContext()) as any; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toBeUndefined(); }); test("root undefined object, should unmarshall to null", () => { const marshaller = new DefaultMarshaller(); const input = undefined as any; const marshalledInput = marshaller.marshall(input, new MarshallingContext()) as any; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toBeUndefined(); }); test("root JavaBigDecimal object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = new JavaBigDecimal("1.1"); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaBigDecimal("1.1")); }); test("root JavaBigInteger object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = new JavaBigInteger("1"); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaBigInteger("1")); }); test("root JavaByte object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = 1; const marshalledInput = new NumValBasedErraiObject(JavaType.BYTE, input).asErraiObject(); const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaByte("1")); }); test("root JavaDouble object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = 1.1; const marshalledInput = new NumValBasedErraiObject(JavaType.DOUBLE, input).asErraiObject(); const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaDouble("1.1")); }); test("root JavaFloat object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = 1.1; const marshalledInput = new NumValBasedErraiObject(JavaType.FLOAT, input).asErraiObject(); const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaFloat("1.1")); }); test("root JavaInteger object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = 1; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaInteger("1")); }); test("root JavaLong object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = new JavaLong("1"); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaLong("1")); }); test("root JavaShort object, should unmarshall it normally", () => { const marshaller = new DefaultMarshaller(); const input = 1; const marshalledInput = new NumValBasedErraiObject(JavaType.SHORT, input).asErraiObject(); const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaShort("1")); }); test("root JavaOptional object, should serialize it normally", () => { const marshaller = new DefaultMarshaller(); const input = new JavaOptional("1"); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional("1")); }); test("root JavaEnum object, should serialize it normally", () => { const marshaller = new DefaultMarshaller(); const input = AddressType.WORK; const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const factory = new Map([ [ "com.app.my.AddressType", ((name: string) => { switch (name) { case "HOME": return AddressType.HOME; case "WORK": return AddressType.WORK; default: throw new Error(`Unknown value ${name} for enum AddressType!`); } }) as any ] ]); const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(factory)); expect(output).toStrictEqual(AddressType.WORK); }); test("root string object, should unmarshall it to native string", () => { const marshaller = new DefaultMarshaller(); const stringInput = "foo"; const javaStringInput = new JavaString("foo"); [stringInput, javaStringInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual("foo"); }); }); test("root date object, should unmarshall it to native date", () => { const marshaller = new DefaultMarshaller(); const baseDate = new Date(); const dateInput = new Date(baseDate); const javaDateInput = new JavaDate(new Date(baseDate)); [dateInput, javaDateInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(baseDate); }); }); test("root boolean object, should unmarshall it to native boolean", () => { const marshaller = new DefaultMarshaller(); const booleanInput = false; const javaBooleanInput = new JavaBoolean(false); [booleanInput, javaBooleanInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(false); }); }); test("root array object, should unmarshall it to native array", () => { const marshaller = new DefaultMarshaller(); const arrayInput = ["foo"]; const javaArrayInput = new JavaArrayList(["foo"]); [arrayInput, javaArrayInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(["foo"]); }); }); test("root set object, should unmarshall it to native set", () => { const marshaller = new DefaultMarshaller(); const setInput = new Set(["foo"]); const javaSetInput = new JavaHashSet(new Set(["foo"])); [setInput, javaSetInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new Set(["foo"])); }); }); test("root map object, should unmarshall it native map", () => { const marshaller = new DefaultMarshaller(); const mapInput = new Map([["foo", "bar"]]); const javaMapInput = new JavaHashMap(new Map([["foo", "bar"]])); [mapInput, javaMapInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([["foo", "bar"]])); }); }); test("root integer number object, should throw error", () => { const marshaller = new DefaultMarshaller(); const input = 1; expect(() => marshaller.unmarshall(input as any, new UnmarshallingContext(new Map()))).toThrowError(); }); test("root float number object, should throw error", () => { const marshaller = new DefaultMarshaller(); const input = 1.1; expect(() => marshaller.unmarshall(input as any, new UnmarshallingContext(new Map()))).toThrowError(); }); }); describe("pojo root types", () => { test("with custom pojo, should unmarshall correctly", () => { const oracle = new Map([ ["com.app.my.Pojo", () => new User({ age: new JavaInteger("0") }) as any], ["com.app.my.Address", () => new Address({} as any) as any], [ "com.app.my.AddressType", ((name: string) => { switch (name) { case "HOME": return AddressType.HOME; case "WORK": return AddressType.WORK; default: throw new Error(`Unknown value ${name} for enum AddressType!`); } }) as any ] ]); const marshaller = new DefaultMarshaller(); const input = new User({ name: "my name", sendSpam: false, age: new JavaInteger("10"), address: new Address({ line1: "address line 1", type: AddressType.HOME }), bestFriend: new User({ name: "my name 2", sendSpam: true, address: new Address({ line1: "address 2 line 1" }) }) }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(oracle)); expect(output).toEqual(input); }); test("with custom pojo with function, should unmarshall to a correct object containing the function", () => { const oracle = new Map([["com.app.my.PojoWithFunction", () => new PojoWithFunction({})]]); const marshaller = new DefaultMarshaller(); const input = new PojoWithFunction({ foo: "bar" }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(oracle)) as PojoWithFunction; expect(output).toEqual(input); // generates a full functional object of the correct type expect(output.whatToSay()).toEqual("Hello, bar!"); }); test("with custom pojo with java types, should unmarshall normally", () => { const marshaller = new DefaultMarshaller(); const oracle = new Map([ [ "com.app.my.Pojo", () => new JavaTypesPojo({ bigDecimal: new JavaBigDecimal("0"), bigInteger: new JavaBigInteger("0"), byte: new JavaByte("0"), double: new JavaDouble("0"), float: new JavaFloat("0"), integer: new JavaInteger("0"), short: new JavaShort("0") }) ] ]); const input = new JavaTypesPojo({ bigDecimal: new JavaBigDecimal("1.1"), bigInteger: new JavaBigInteger("2"), boolean: false, byte: new JavaByte("3"), double: new JavaDouble("1.2"), float: new JavaFloat("1.3"), integer: new JavaInteger("4"), long: new JavaLong("5"), short: new JavaShort("6"), string: "str", date: new Date(), optional: new JavaOptional("optstr") }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(oracle)); expect(output).toEqual(input); }); test("with custom pojo with java collection types, should unmarshall normally", () => { const marshaller = new DefaultMarshaller(); const oracle = new Map([["com.app.my.JavaCollectionTypesPojo", () => new JavaCollectionTypesPojo({})]]); const input = new JavaCollectionTypesPojo({ list: ["1", "2"], set: new Set(["3", "2"]), map: new Map([["k1", "v1"], ["k2", "v2"]]) }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(oracle)); expect(output).toEqual(input); }); test("with custom pojo without fqcn, should throw error", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.Pojo", () => new User({ age: new JavaInteger("0") })]]) ); const input = new User({}); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; // remove its fqcn delete marshalledInput[ErraiObjectConstants.ENCODED_TYPE]; expect(() => marshaller.unmarshall(marshalledInput, unmarshallContext)).toThrowError(); }); test("with custom pojo without factory, should throw error", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext(new Map()); const input = new User({}); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; expect(() => marshaller.unmarshall(marshalledInput, unmarshallContext)).toThrowError(); }); test("with custom pojo with property without fqcn, should throw error", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ ["com.app.my.Pojo", () => new User({ age: new JavaInteger("0") }) as any], ["com.app.my.Address", () => new Address({} as any) as any] ]) ); const input = new User({ name: "foo", address: new Address({ line1: "bla" }) }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; // remove its fqcn delete (marshalledInput as any).address[ErraiObjectConstants.ENCODED_TYPE]; expect(() => marshaller.unmarshall(marshalledInput, unmarshallContext)).toThrowError(); }); class PojoWithFunction implements Portable { private readonly _fqcn = "com.app.my.PojoWithFunction"; public readonly foo?: string = undefined; constructor(self: { foo?: string }) { Object.assign(this, self); } public whatToSay() { return `Hello, ${this.foo}!`; } } class JavaCollectionTypesPojo implements Portable { private readonly _fqcn = "com.app.my.JavaCollectionTypesPojo"; public readonly list?: string[] = undefined; public readonly set?: Set = undefined; public readonly map?: Map = undefined; constructor(self: { list?: string[]; set?: Set; map?: Map }) { Object.assign(this, self); } } }); describe("object caching", () => { test("custom pojo with repeated pojo objects, should cache the object and reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ ["com.app.my.Address", () => new Address({}) as any], ["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any] ]) ); const repeatedObject = new Address({ line1: "bla address" }); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo
; expect(output).toEqual(input); expect(output.field1!).toBe(output.field2!); }); test("custom pojo with repeated JavaBigDecimal objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any]]) ); const repeatedObject = new JavaBigDecimal("1.1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaBigInteger objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any]]) ); const repeatedObject = new JavaBigInteger("1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaByte objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ [ "com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({ field1: new JavaByte("0"), field2: new JavaByte("0") }) as any ] ]) ); const repeatedObject = new JavaByte("1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaDouble objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ [ "com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({ field1: new JavaDouble("0"), field2: new JavaDouble("0") }) as any ] ]) ); const repeatedObject = new JavaDouble("1.1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaFloat objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ [ "com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({ field1: new JavaFloat("0"), field2: new JavaFloat("0") }) as any ] ]) ); const repeatedObject = new JavaFloat("1.1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaInteger objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ [ "com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({ field1: new JavaInteger("0"), field2: new JavaInteger("0") }) as any ] ]) ); const repeatedObject = new JavaInteger("1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaLong objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any]]) ); const repeatedObject = new JavaLong("1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaShort objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ [ "com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({ field1: new JavaShort("0"), field2: new JavaShort("0") }) as any ] ]) ); const repeatedObject = new JavaShort("1"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaOptional objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any]]) ); const repeatedObject = new JavaOptional("foo"); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo< JavaOptional >; expect(output).toEqual(input); expect(output.field1!).not.toBe(output.field2!); }); test("custom pojo with repeated JavaEnum objects, should not cache it and don't reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([ ["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any], [ "com.app.my.AddressType", ((name: string) => { switch (name) { case "HOME": return AddressType.HOME; case "WORK": return AddressType.WORK; default: throw new Error(`Unknown value ${name} for enum AddressType!`); } }) as any ] ]) ); const repeatedObject = AddressType.HOME; const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).toBe(output.field2!); }); test("custom pojo with repeated array objects, should cache the object and reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any]]) ); const repeatedInlineArray = ["foo", "bar"]; const inlineArrayInput = new RepeatedFieldsPojo({ field1: repeatedInlineArray, field2: repeatedInlineArray }); const repeatedNewArray = new Array("foo", "bar"); const newArrayInput = new RepeatedFieldsPojo({ field1: repeatedNewArray, field2: repeatedNewArray }); [inlineArrayInput, newArrayInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo; expect(output).toEqual(input); expect(output.field1!).toBe(output.field2!); }); }); test("custom pojo with repeated set objects, should cache the object and reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any]]) ); const repeatedObject = new Set(["foo", "bar"]); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo>; expect(output).toEqual(input); expect(output.field1!).toBe(output.field2!); }); test("custom pojo with repeated map objects, should cache the object and reuse data", () => { const marshaller = new DefaultMarshaller(); const unmarshallContext = new UnmarshallingContext( new Map([["com.app.my.RepeatedFieldsPojo", () => new RepeatedFieldsPojo({}) as any]]) ); const repeatedObject = new Map([["foo1", "bar1"], ["foo2", "bar2"]]); const input = new RepeatedFieldsPojo({ field1: repeatedObject, field2: repeatedObject }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, unmarshallContext) as RepeatedFieldsPojo< Map >; expect(output).toEqual(input); expect(output.field1!).toBe(output.field2!); }); class RepeatedFieldsPojo implements Portable> { private readonly _fqcn = "com.app.my.RepeatedFieldsPojo"; public field1?: T = undefined; public field2?: T = undefined; constructor(self: { field1?: T; field2?: T }) { Object.assign(this, self); } } }); }); class User implements Portable { private readonly _fqcn = "com.app.my.Pojo"; public readonly name?: string = undefined; public readonly sendSpam?: boolean = undefined; public readonly age?: JavaInteger = undefined; public readonly address?: Address = undefined; public readonly bestFriend?: User = undefined; constructor(self: { name?: string; sendSpam?: boolean; age?: JavaInteger; address?: Address; bestFriend?: User }) { Object.assign(this, self); } } class Address implements Portable
{ private readonly _fqcn = "com.app.my.Address"; public line1?: string = undefined; public type?: AddressType = undefined; constructor(self: { line1?: string; type?: AddressType }) { Object.assign(this, self); } } class AddressType extends JavaEnum { public static readonly HOME: AddressType = new AddressType("HOME"); public static readonly WORK: AddressType = new AddressType("WORK"); protected readonly _fqcn: string = AddressType.__fqcn(); public static __fqcn(): string { return "com.app.my.AddressType"; } public static values() { return [AddressType.HOME, AddressType.WORK]; } } class JavaTypesPojo implements Portable { private readonly _fqcn = "com.app.my.Pojo"; public readonly bigDecimal?: JavaBigDecimal = undefined; public readonly bigInteger?: JavaBigInteger = undefined; public readonly boolean?: boolean = undefined; public readonly byte?: JavaByte = undefined; public readonly double?: JavaDouble = undefined; public readonly float?: JavaFloat = undefined; public readonly integer?: JavaInteger = undefined; public readonly long?: JavaLong = undefined; public readonly short?: JavaShort = undefined; public readonly string?: string = undefined; public readonly date?: Date = undefined; public readonly optional?: JavaOptional = undefined; constructor(self: { bigDecimal?: JavaBigDecimal; bigInteger?: JavaBigInteger; boolean?: boolean; byte?: JavaByte; double?: JavaDouble; float?: JavaFloat; integer?: JavaInteger; long?: JavaLong; short?: JavaShort; string?: string; date?: Date; optional?: JavaOptional; }) { Object.assign(this, self); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaBigDecimalMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaBigDecimal } from "../../../java-wrappers"; import { JavaBigDecimalMarshaller } from "../JavaBigDecimalMarshaller"; import { MarshallingContext } from "../../MarshallingContext"; import { ErraiObjectConstants } from "../../model/ErraiObjectConstants"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { JavaType } from "../../../java-wrappers/JavaType"; import { ValueBasedErraiObject } from "../../model/ValueBasedErraiObject"; import { NumberUtils } from "../../../util/NumberUtils"; describe("marshall", () => { test("with regular big decimal, should serialize it normally", () => { const input = new JavaBigDecimal("12.12"); const output = new JavaBigDecimalMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: JavaType.BIG_DECIMAL, [ErraiObjectConstants.OBJECT_ID]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [ErraiObjectConstants.VALUE]: "12.12" }); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaBigDecimalMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaBigDecimalMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with regular input, should return a JavaBigDecimal instance", () => { const marshaller = new JavaBigDecimalMarshaller(); const context = new UnmarshallingContext(new Map()); const input = new JavaBigDecimal("125.2"); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output.get().toString(10)).toEqual(input.get().toString(10)); }); test("with non string value, should throw error", () => { const marshaller = new JavaBigDecimalMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_DECIMAL, false, "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with non numeric string value, should throw error", () => { const marshaller = new JavaBigDecimalMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_DECIMAL, "abc", "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should return a JavaBigDecimal instance containing NaN", () => { const marshaller = new JavaBigDecimalMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_DECIMAL, null, "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should return a JavaBigDecimal instance containing NaN", () => { const marshaller = new JavaBigDecimalMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_DECIMAL, undefined, "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with empty string value, should return a JavaBigDecimal instance containing NaN", () => { const marshaller = new JavaBigDecimalMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_DECIMAL, "", "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaBigIntegerMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { ErraiObjectConstants } from "../../model/ErraiObjectConstants"; import { JavaBigInteger } from "../../../java-wrappers"; import { JavaBigIntegerMarshaller } from "../JavaBigIntegerMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { JavaType } from "../../../java-wrappers/JavaType"; import { ValueBasedErraiObject } from "../../model/ValueBasedErraiObject"; import { NumberUtils } from "../../../util/NumberUtils"; describe("marshall", () => { test("with regular big integer, should serialize it normally", () => { const input = new JavaBigInteger("12"); const output = new JavaBigIntegerMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: JavaType.BIG_INTEGER, [ErraiObjectConstants.OBJECT_ID]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [ErraiObjectConstants.VALUE]: "12" }); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaBigIntegerMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaBigIntegerMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with regular input, should return a JavaBigInteger instance", () => { const marshaller = new JavaBigIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = new JavaBigInteger("125"); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output.get().toString(10)).toEqual(input.get().toString(10)); }); test("with non string value, should return a JavaBigInteger instance containing NaN", () => { const marshaller = new JavaBigIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_INTEGER, false, "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with non numeric string value, should throw error", () => { const marshaller = new JavaBigIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_INTEGER, "abc", "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should return a JavaBigInteger instance containing NaN", () => { const marshaller = new JavaBigIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_INTEGER, null, "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should return a JavaBigInteger instance containing NaN", () => { const marshaller = new JavaBigIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_INTEGER, undefined, "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with empty string value, should return a JavaBigInteger instance containing NaN", () => { const marshaller = new JavaBigIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const marshalledInput = new ValueBasedErraiObject(JavaType.BIG_INTEGER, "", "1").asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaBooleanMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaBoolean } from "../../../java-wrappers"; import { JavaBooleanMarshaller } from "../JavaBooleanMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { JavaType } from "../../../java-wrappers/JavaType"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; describe("marshall", () => { test("with regular boolean, should return the same value", () => { const input = new JavaBoolean(false); const output = new JavaBooleanMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(false); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaBooleanMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaBooleanMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with boolean input, should return a boolean instance", () => { const marshaller = new JavaBooleanMarshaller(); const context = new UnmarshallingContext(new Map()); const input = true; const output = marshaller.notNullUnmarshall(input, context); expect(output).toBeTruthy(); }); test("with ErraiObject regular input, should return a boolean instance", () => { const marshaller = new JavaBooleanMarshaller(); const context = new UnmarshallingContext(new Map()); const input = false; const marshalledInput = new NumValBasedErraiObject(JavaType.BOOLEAN, input).asErraiObject(); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output).toBeFalsy(); }); test("with non boolean value, should throw error", () => { const marshaller = new JavaBooleanMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new NumValBasedErraiObject(JavaType.BOOLEAN, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should throw error", () => { const marshaller = new JavaBooleanMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new NumValBasedErraiObject(JavaType.BOOLEAN, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should throw error", () => { const marshaller = new JavaBooleanMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new NumValBasedErraiObject(JavaType.BOOLEAN, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaByteMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaByte } from "../../../java-wrappers"; import { JavaByteMarshaller } from "../JavaByteMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { test("with regular byte, should return same value", () => { const input = new JavaByte("2"); const output = new JavaByteMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(2); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaByteMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaByteMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { describe("number input", () => { test("with byte, should return a JavaByte instance", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1; const output = marshaller.notNullUnmarshall(input, context); expect(output).toEqual(new JavaByte("1")); }); test("with float, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.2; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with string, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with null, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with undefined, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); }); describe("ErraiObject input", () => { test("with byte, should return a JavaByte instance", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1; const marshalledInput = new NumValBasedErraiObject(JavaType.BYTE, input).asErraiObject(); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output).toEqual(new JavaByte("1")); }); test("with float, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.2; const marshalledInput = new NumValBasedErraiObject(JavaType.BYTE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with string, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new NumValBasedErraiObject(JavaType.BYTE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new NumValBasedErraiObject(JavaType.BYTE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined, should throw error", () => { const marshaller = new JavaByteMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new NumValBasedErraiObject(JavaType.BYTE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaCollectionSubTypesMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaArrayListMarshaller, JavaHashSetMarshaller } from "../JavaCollectionMarshaller"; import { JavaArrayList, JavaBigDecimal, JavaBigInteger, JavaBoolean, JavaByte, JavaDate, JavaDouble, JavaFloat, JavaHashMap, JavaHashSet, JavaInteger, JavaLong, JavaOptional, JavaShort, JavaString } from "../../../java-wrappers"; import { MarshallingContext } from "../../MarshallingContext"; import { ErraiObjectConstants } from "../../model/ErraiObjectConstants"; import { MarshallerProvider } from "../../MarshallerProvider"; import { JavaBigIntegerMarshaller } from "../JavaBigIntegerMarshaller"; import { Portable } from "../../Portable"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { NumberUtils } from "../../../util/NumberUtils"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { ValueBasedErraiObject } from "../../model/ValueBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { const encodedType = ErraiObjectConstants.ENCODED_TYPE; const objectId = ErraiObjectConstants.OBJECT_ID; const value = ErraiObjectConstants.VALUE; let context: MarshallingContext; beforeEach(() => { MarshallerProvider.initialize(); context = new MarshallingContext(); }); test("with empty collection, should serialize normally", () => { const arrayListScenario = () => { const input = new JavaArrayList([]); return { fqcn: JavaType.ARRAY_LIST, output: new JavaArrayListMarshaller().marshall(input, context) }; }; const hashSetScenario = () => { const input = new JavaHashSet(new Set([])); return { fqcn: JavaType.HASH_SET, output: new JavaHashSetMarshaller().marshall(input, context) }; }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const { fqcn, output } = outputFunc(); expect(output).toStrictEqual({ [encodedType]: fqcn, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: [] }); }); }); test("with JavaNumber collection, should wrap every element into an errai object", () => { const numberArray = [new JavaInteger("1"), new JavaInteger("2"), new JavaInteger("3")]; const arrayListScenario = () => { const input = new JavaArrayList(numberArray); return { fqcn: JavaType.ARRAY_LIST, output: new JavaArrayListMarshaller().marshall(input, context) }; }; const hashSetScenario = () => { const input = new JavaHashSet(new Set(numberArray)); return { fqcn: JavaType.HASH_SET, output: new JavaHashSetMarshaller().marshall(input, context) }; }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const { fqcn, output } = outputFunc(); expect(output).toStrictEqual({ [encodedType]: fqcn, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: [ new NumValBasedErraiObject(JavaType.INTEGER, 1).asErraiObject(), new NumValBasedErraiObject(JavaType.INTEGER, 2).asErraiObject(), new NumValBasedErraiObject(JavaType.INTEGER, 3).asErraiObject() ] }); }); }); test("with JavaBoolean collection, should wrap every element into an errai object", () => { const booleanArray = [new JavaBoolean(true), new JavaBoolean(false)]; const arrayListScenario = () => { const input = new JavaArrayList(booleanArray); return { fqcn: JavaType.ARRAY_LIST, output: new JavaArrayListMarshaller().marshall(input, context) }; }; const hashSetScenario = () => { const input = new JavaHashSet(new Set(booleanArray)); return { fqcn: JavaType.HASH_SET, output: new JavaHashSetMarshaller().marshall(input, context) }; }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const { fqcn, output } = outputFunc(); expect(output).toStrictEqual({ [encodedType]: fqcn, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: [ new NumValBasedErraiObject(JavaType.BOOLEAN, true).asErraiObject(), new NumValBasedErraiObject(JavaType.BOOLEAN, false).asErraiObject() ] }); }); }); test("with JavaBigNumber collection, should serialize every element normally", () => { const bigIntegerMarshaller = new JavaBigIntegerMarshaller(); const bigNumberArray = [new JavaBigInteger("1"), new JavaBigInteger("2"), new JavaBigInteger("3")]; const arrayListScenario = () => { const input = new JavaArrayList(bigNumberArray); return { fqcn: JavaType.ARRAY_LIST, output: new JavaArrayListMarshaller().marshall(input, context) }; }; const hashSetScenario = () => { const input = new JavaHashSet(new Set(bigNumberArray)); return { fqcn: JavaType.HASH_SET, output: new JavaHashSetMarshaller().marshall(input, context) }; }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const { fqcn, output } = outputFunc(); expect(output).toStrictEqual({ [encodedType]: fqcn, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: [ { ...(bigIntegerMarshaller.marshall(new JavaBigInteger("1"), context) as any), [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex) }, { ...(bigIntegerMarshaller.marshall(new JavaBigInteger("2"), context) as any), [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex) }, { ...(bigIntegerMarshaller.marshall(new JavaBigInteger("3"), context) as any), [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex) } ] }); }); }); test("with custom object collection, should serialize every element normally", () => { const portableArray = [ new MyPortable({ foo: "foo1", bar: "bar1" }), new MyPortable({ foo: "foo2", bar: "bar2" }), new MyPortable({ foo: "foo3", bar: "bar3" }) ]; const arrayListScenario = () => { const input = new JavaArrayList(portableArray); return { fqcn: JavaType.ARRAY_LIST, output: new JavaArrayListMarshaller().marshall(input, new MarshallingContext()) }; }; const hashSetScenario = () => { const input = new JavaHashSet(new Set(portableArray)); return { fqcn: JavaType.HASH_SET, output: new JavaHashSetMarshaller().marshall(input, new MarshallingContext()) }; }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const { fqcn, output } = outputFunc(); expect(output).toStrictEqual({ [encodedType]: fqcn, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: [ { [encodedType]: "com.portable.my", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "foo1", bar: "bar1" }, { [encodedType]: "com.portable.my", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "foo2", bar: "bar2" }, { [encodedType]: "com.portable.my", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "foo3", bar: "bar3" } ] }); }); }); test("with collection containing null elements, should serialize every element normally", () => { const arrayListScenario = () => { const input = new JavaArrayList([null]); return { fqcn: JavaType.ARRAY_LIST, output: new JavaArrayListMarshaller().marshall(input, new MarshallingContext()) }; }; const hashSetScenario = () => { const input = new JavaHashSet(new Set([null])); return { fqcn: JavaType.HASH_SET, output: new JavaHashSetMarshaller().marshall(input, new MarshallingContext()) }; }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const { fqcn, output } = outputFunc(); expect(output).toStrictEqual({ [encodedType]: fqcn, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: [null] }); }); }); test("with custom pojo array containing repeated elements, should cache inner objects and don't repeat data", () => { const repeatedValue = new Node({ data: "foo1", left: undefined, right: undefined }); const portableArray = [repeatedValue, new Node({ data: "foo2", left: undefined, right: repeatedValue })]; const arrayListScenario = () => { const input = new JavaArrayList(portableArray); return { fqcn: JavaType.ARRAY_LIST, output: new JavaArrayListMarshaller().marshall(input, new MarshallingContext()) }; }; const hashSetScenario = () => { const input = new JavaHashSet(new Set(portableArray)); return { fqcn: JavaType.HASH_SET, output: new JavaHashSetMarshaller().marshall(input, new MarshallingContext()) }; }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const { fqcn, output } = outputFunc(); const rootObjId = output![objectId]; expect(output![encodedType]).toEqual(fqcn); expect(rootObjId).toMatch(NumberUtils.nonNegativeIntegerRegex); const rootObjValue = output![value] as any[]; const foo2Objects = rootObjValue.filter(obj => obj.data === "foo2"); expect(foo2Objects.length).toEqual(1); const uniqueObjId = foo2Objects[0][objectId]; expect(uniqueObjId).toMatch(NumberUtils.nonNegativeIntegerRegex); const repeatedObjects = rootObjValue.filter(obj => obj.data !== "foo2"); expect(repeatedObjects.length).toEqual(1); const repeatedObjId = repeatedObjects[0][objectId]; expect(repeatedObjId).toMatch(NumberUtils.nonNegativeIntegerRegex); expect(rootObjValue).toEqual([ { [encodedType]: "com.app.my.Node", [objectId]: repeatedObjId, data: "foo1", left: null, right: null }, { [encodedType]: "com.app.my.Node", [objectId]: uniqueObjId, data: "foo2", right: { [encodedType]: "com.app.my.Node", [objectId]: repeatedObjId }, left: null } ]); }); }); test("root null object, should serialize to null", () => { const input = null as any; const arrayListScenario = () => { return new JavaArrayListMarshaller().marshall(input, new MarshallingContext()); }; const hashSetScenario = () => { return new JavaHashSetMarshaller().marshall(input, new MarshallingContext()); }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const output = outputFunc(); expect(output).toBeNull(); }); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const arrayListScenario = () => { return new JavaArrayListMarshaller().marshall(input, new MarshallingContext()); }; const hashSetScenario = () => { return new JavaHashSetMarshaller().marshall(input, new MarshallingContext()); }; [arrayListScenario, hashSetScenario].forEach(outputFunc => { const output = outputFunc(); expect(output).toBeNull(); }); }); }); describe("unmarshall", () => { beforeEach(() => { MarshallerProvider.initialize(); }); test("with empty collection, should unmarshall to empty collection", () => { const arrayInput = { input: new JavaArrayList([]), marshaller: new JavaArrayListMarshaller(), expected: [] }; const setInput = { input: new JavaHashSet(new Set([])), marshaller: new JavaHashSetMarshaller(), expected: new Set([]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with Array collection, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([["foo"]]), marshaller: new JavaArrayListMarshaller(), expected: [["foo"]] }; const setInput = { input: new JavaHashSet(new Set([["foo"]])), marshaller: new JavaHashSetMarshaller(), expected: new Set([["foo"]]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaArrayList collection, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaArrayList(["foo"])]), marshaller: new JavaArrayListMarshaller(), expected: [["foo"]] }; const setInput = { input: new JavaHashSet(new Set([new JavaArrayList(["foo"])])), marshaller: new JavaHashSetMarshaller(), expected: new Set([["foo"]]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with Set input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new Set(["foo"])]), marshaller: new JavaArrayListMarshaller(), expected: [new Set(["foo"])] }; const setInput = { input: new JavaHashSet(new Set([new Set(["foo"])])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new Set(["foo"])]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with HashSet input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaHashSet(new Set(["foo"]))]), marshaller: new JavaArrayListMarshaller(), expected: [new Set(["foo"])] }; const setInput = { input: new JavaHashSet(new Set([new JavaHashSet(new Set(["foo"]))])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new Set(["foo"])]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with Map input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new Map([["foo", "bar"]])]), marshaller: new JavaArrayListMarshaller(), expected: [new Map([["foo", "bar"]])] }; const setInput = { input: new JavaHashSet(new Set([new Map([["foo", "bar"]])])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new Map([["foo", "bar"]])]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaHashMap input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaHashMap(new Map([["foo", "bar"]]))]), marshaller: new JavaArrayListMarshaller(), expected: [new Map([["foo", "bar"]])] }; const setInput = { input: new JavaHashSet(new Set([new JavaHashMap(new Map([["foo", "bar"]]))])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new Map([["foo", "bar"]])]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with Date input, should unmarshall correctly", () => { const baseDate = new Date(); const arrayInput = { input: new JavaArrayList([new Date(baseDate)]), marshaller: new JavaArrayListMarshaller(), expected: [new Date(baseDate)] }; const setInput = { input: new JavaHashSet(new Set([new Date(baseDate)])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new Date(baseDate)]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaDate input, should unmarshall correctly", () => { const baseDate = new Date(); const arrayInput = { input: new JavaArrayList([new JavaDate(new Date(baseDate))]), marshaller: new JavaArrayListMarshaller(), expected: [new Date(baseDate)] }; const setInput = { input: new JavaHashSet(new Set([new JavaDate(new Date(baseDate))])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new Date(baseDate)]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with Boolean input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([false]), marshaller: new JavaArrayListMarshaller(), expected: [false] }; const setInput = { input: new JavaHashSet(new Set([false])), marshaller: new JavaHashSetMarshaller(), expected: new Set([false]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaBoolean input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaBoolean(false)]), marshaller: new JavaArrayListMarshaller(), expected: [false] }; const setInput = { input: new JavaHashSet(new Set([new JavaBoolean(false)])), marshaller: new JavaHashSetMarshaller(), expected: new Set([false]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with String input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList(["foo"]), marshaller: new JavaArrayListMarshaller(), expected: ["foo"] }; const setInput = { input: new JavaHashSet(new Set(["foo"])), marshaller: new JavaHashSetMarshaller(), expected: new Set(["foo"]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaString input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaString("foo")]), marshaller: new JavaArrayListMarshaller(), expected: ["foo"] }; const setInput = { input: new JavaHashSet(new Set([new JavaString("foo")])), marshaller: new JavaHashSetMarshaller(), expected: new Set(["foo"]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaOptional input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaOptional("foo")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaOptional("foo")] }; const setInput = { input: new JavaHashSet(new Set([new JavaOptional("foo")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaOptional("foo")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaBigDecimal input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaBigDecimal("1.1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaBigDecimal("1.1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaBigDecimal("1.1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaBigDecimal("1.1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaBigInteger should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaBigInteger("1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaBigInteger("1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaBigInteger("1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaBigInteger("1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaLong input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaLong("1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaLong("1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaLong("1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaLong("1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaByte input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaByte("1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaByte("1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaByte("1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaByte("1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaDouble input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaDouble("1.1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaDouble("1.1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaDouble("1.1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaDouble("1.1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaFloat input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaFloat("1.1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaFloat("1.1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaFloat("1.1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaFloat("1.1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaInteger input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaInteger("1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaInteger("1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaInteger("1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaInteger("1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with JavaShort input, should unmarshall correctly", () => { const arrayInput = { input: new JavaArrayList([new JavaShort("1")]), marshaller: new JavaArrayListMarshaller(), expected: [new JavaShort("1")] }; const setInput = { input: new JavaHashSet(new Set([new JavaShort("1")])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new JavaShort("1")]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual(scenario.expected); }); }); test("with custom object optional, should unmarshall correctly", () => { const oracle = new Map([["com.portable.my", () => new MyPortable({} as any)]]); const arrayInput = { input: new JavaArrayList([new MyPortable({ foo: "bar", bar: "foo" })]), marshaller: new JavaArrayListMarshaller(), expected: [new MyPortable({ foo: "bar", bar: "foo" })] }; const setInput = { input: new JavaHashSet(new Set([new MyPortable({ foo: "bar", bar: "foo" })])), marshaller: new JavaHashSetMarshaller(), expected: new Set([new MyPortable({ foo: "bar", bar: "foo" })]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(oracle)); expect(output).toEqual(scenario.expected); }); }); test("with root null object, should unmarshall to undefined", () => { [new JavaArrayListMarshaller(), new JavaHashSetMarshaller()].forEach(marshaller => { const output = marshaller.unmarshall(null as any, new UnmarshallingContext(new Map())); expect(output).toBeUndefined(); }); }); test("with root undefined object, should unmarshall to undefined", () => { [new JavaArrayListMarshaller(), new JavaHashSetMarshaller()].forEach(marshaller => { const output = marshaller.unmarshall(undefined as any, new UnmarshallingContext(new Map())); expect(output).toBeUndefined(); }); }); test("with undefined value inside ErraiObject, should throw error", () => { const arrayInput = { input: new ValueBasedErraiObject(JavaType.ARRAY_LIST, undefined).asErraiObject(), marshaller: new JavaArrayListMarshaller() }; const setInput = { input: new ValueBasedErraiObject(JavaType.HASH_SET, undefined).asErraiObject(), marshaller: new JavaHashSetMarshaller() }; [arrayInput, setInput].forEach(scenario => { expect(() => scenario.marshaller.unmarshall(scenario.input, new UnmarshallingContext(new Map()))).toThrowError(); }); }); test("with null value inside ErraiObject, should throw error", () => { const arrayInput = { input: new ValueBasedErraiObject(JavaType.ARRAY_LIST, null).asErraiObject(), marshaller: new JavaArrayListMarshaller() }; const setInput = { input: new ValueBasedErraiObject(JavaType.HASH_SET, null).asErraiObject(), marshaller: new JavaHashSetMarshaller() }; [arrayInput, setInput].forEach(scenario => { expect(() => scenario.marshaller.unmarshall(scenario.input, new UnmarshallingContext(new Map()))).toThrowError(); }); }); test("with non array value inside ErraiObject, should throw error", () => { const arrayInput = { input: new ValueBasedErraiObject(JavaType.ARRAY_LIST, false).asErraiObject(), marshaller: new JavaArrayListMarshaller() }; const setInput = { input: new ValueBasedErraiObject(JavaType.HASH_SET, false).asErraiObject(), marshaller: new JavaHashSetMarshaller() }; [arrayInput, setInput].forEach(scenario => { expect(() => scenario.marshaller.unmarshall(scenario.input, new UnmarshallingContext(new Map()))).toThrowError(); }); }); test("with custom pojo containing repeated elements, should reuse cached objects and don't recreate data", () => { const oracle = new Map([["com.app.my.Node", () => new Node({} as any)]]); const repeatedValue = new Node({ data: "foo1" }); const portableArray = [repeatedValue, new Node({ data: "foo2", right: repeatedValue })]; const arrayInput = { input: new JavaArrayList(portableArray), marshaller: new JavaArrayListMarshaller(), expected: portableArray }; const setInput = { input: new JavaHashSet(new Set(portableArray)), marshaller: new JavaHashSetMarshaller(), expected: new Set(portableArray) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const output = scenario.marshaller.unmarshall(input, new UnmarshallingContext(oracle)); // compares value equality expect(output).toEqual(scenario.expected); // check if the repeated object was reused from cache const asArray = Array.from(scenario.expected); const repeatedNode = asArray[0]; const uniqueNode = asArray[1]; expect(repeatedNode).toBe(uniqueNode.right!); }); }); test("with repeated collection unmarshalling, should reuse cached collection and don't recreate it", () => { const arrayInput = { input: new JavaArrayList(["list"]), marshaller: new JavaArrayListMarshaller(), expected: ["list"] }; const setInput = { input: new JavaHashSet(new Set(["set"])), marshaller: new JavaHashSetMarshaller(), expected: new Set(["set"]) }; [arrayInput, setInput].forEach(scenario => { const input = (scenario.marshaller as any).marshall(scenario.input as any, new MarshallingContext()); const context = new UnmarshallingContext(new Map()); const output = scenario.marshaller.unmarshall(input, context); const repeatedOutput = scenario.marshaller.unmarshall(input, context); expect(output).toEqual(scenario.expected); expect(output).toBe(repeatedOutput!); }); }); }); class MyPortable implements Portable { private readonly _fqcn = "com.portable.my"; public readonly foo: string; public readonly bar: string; constructor(self: { foo: string; bar: string }) { Object.assign(this, self); } } class Node implements Portable { private readonly _fqcn = "com.app.my.Node"; public readonly data: any; public readonly left?: Node; public readonly right?: Node; constructor(self: { data: any; left?: Node; right?: Node }) { Object.assign(this, self); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaDateMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaDate } from "../../../java-wrappers"; import { JavaDateMarshaller } from "../JavaDateMarshaller"; import { ValueBasedErraiObject } from "../../model/ValueBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; import { UnmarshallingContext } from "../../UnmarshallingContext"; describe("marshall", () => { test("with regular date, should should serialize it normally", () => { const date = new Date(); const input = new JavaDate(date); const output = new JavaDateMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(new ValueBasedErraiObject(JavaType.DATE, `${date.getTime()}`).asErraiObject()); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaDateMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaDateMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with ErraiObject regular input, should return the same Date instance", () => { const marshaller = new JavaDateMarshaller(); const context = new UnmarshallingContext(new Map()); const input = new Date(); const expectedDate = new Date(input.getTime()); const marshalledInput = marshaller.notNullMarshall(new JavaDate(input), new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output).toEqual(expectedDate); }); test("with non numeric string value, should throw error", () => { const marshaller = new JavaDateMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new ValueBasedErraiObject(JavaType.DATE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with non string value, should throw error", () => { const marshaller = new JavaDateMarshaller(); const context = new UnmarshallingContext(new Map()); const input = true as any; const marshalledInput = new ValueBasedErraiObject(JavaType.DATE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with negative timestamp string value, should throw error", () => { const marshaller = new JavaDateMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "-1"; const marshalledInput = new ValueBasedErraiObject(JavaType.DATE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should throw error", () => { const marshaller = new JavaDateMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new ValueBasedErraiObject(JavaType.DATE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should throw error", () => { const marshaller = new JavaDateMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new ValueBasedErraiObject(JavaType.DATE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaDoubleMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaDouble } from "../../../java-wrappers"; import { JavaDoubleMarshaller } from "../JavaDoubleMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { test("with regular double, should return the same value", () => { const input = new JavaDouble("2.1"); const output = new JavaDoubleMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(2.1); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaDoubleMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaDoubleMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with number input, should return a JavaDouble instance", () => { const marshaller = new JavaDoubleMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.1; const output = marshaller.notNullUnmarshall(input, context); expect(output).toEqual(new JavaDouble("1.1")); }); test("with ErraiObject regular input, should return a JavaDouble instance", () => { const marshaller = new JavaDoubleMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.1; const marshalledInput = new NumValBasedErraiObject(JavaType.DOUBLE, input).asErraiObject(); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output).toEqual(new JavaDouble("1.1")); }); test("with non double value, should throw error", () => { const marshaller = new JavaDoubleMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new NumValBasedErraiObject(JavaType.DOUBLE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should throw error", () => { const marshaller = new JavaDoubleMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new NumValBasedErraiObject(JavaType.DOUBLE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should throw error", () => { const marshaller = new JavaDoubleMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new NumValBasedErraiObject(JavaType.DOUBLE, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaEnumMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaEnum } from "../../../java-wrappers"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { JavaEnumMarshaller } from "../JavaEnumMarshaller"; import { EnumStringValueBasedErraiObject } from "../../model/EnumStringValueBasedErraiObject"; describe("marshall", () => { test("with regular enum, should return the same value", () => { const input = FooEnum.BAR; const output = new JavaEnumMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual( new EnumStringValueBasedErraiObject(FooEnum.__fqcn(), FooEnum.BAR.name).asErraiObject() ); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaEnumMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaEnumMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with enum input, should return an enum instance", () => { const marshaller = new JavaEnumMarshaller(); const context = new UnmarshallingContext( new Map([ [ `${FooEnum.__fqcn()}`, ((name: string) => { switch (name) { case "FOO": return FooEnum.FOO; case "BAR": return FooEnum.BAR; default: throw new Error(`Unknown value ${name} for enum AddressType!`); } }) as any ] ]) ); const input = new EnumStringValueBasedErraiObject(FooEnum.__fqcn(), FooEnum.FOO.name).asErraiObject(); const output = marshaller.notNullUnmarshall(input, context); expect(output).toStrictEqual(FooEnum.FOO); }); test("with invalid enum value, should throw error", () => { const marshaller = new JavaEnumMarshaller(); const context = new UnmarshallingContext( new Map([ [ `${FooEnum.__fqcn()}`, ((name: string) => { switch (name) { case "FOO": return FooEnum.FOO; case "BAR": return FooEnum.BAR; default: throw new Error(`Unknown value ${name} for enum AddressType!`); } }) as any ] ]) ); const input = "abc" as any; const marshalledInput = new EnumStringValueBasedErraiObject(FooEnum.__fqcn(), input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should throw error", () => { const marshaller = new JavaEnumMarshaller(); const context = new UnmarshallingContext( new Map([ [ `${FooEnum.__fqcn()}`, ((name: string) => { switch (name) { case "FOO": return FooEnum.FOO; case "BAR": return FooEnum.BAR; default: throw new Error(`Unknown value ${name} for enum AddressType!`); } }) as any ] ]) ); const input = null as any; const marshalledInput = new EnumStringValueBasedErraiObject(FooEnum.__fqcn(), input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should throw error", () => { const marshaller = new JavaEnumMarshaller(); const context = new UnmarshallingContext( new Map([ [ `${FooEnum.__fqcn()}`, ((name: string) => { switch (name) { case "FOO": return FooEnum.FOO; case "BAR": return FooEnum.BAR; default: throw new Error(`Unknown value ${name} for enum AddressType!`); } }) as any ] ]) ); const input = undefined as any; const marshalledInput = new EnumStringValueBasedErraiObject(FooEnum.__fqcn(), input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); class FooEnum extends JavaEnum { public static readonly FOO: FooEnum = new FooEnum("FOO"); public static readonly BAR: FooEnum = new FooEnum("BAR"); protected readonly _fqcn: string = FooEnum.__fqcn(); public static __fqcn(): string { return "com.app.my.AddressType"; } public static values() { return [FooEnum.FOO, FooEnum.BAR]; } } ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaFloatMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaFloat } from "../../../java-wrappers"; import { JavaFloatMarshaller } from "../JavaFloatMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { test("with regular float, should return the same value", () => { const input = new JavaFloat("2.1"); const output = new JavaFloatMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(2.1); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaFloatMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaFloatMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with number input, should return a JavaFloat instance", () => { const marshaller = new JavaFloatMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.1; const output = marshaller.notNullUnmarshall(input, context); expect(output).toEqual(new JavaFloat("1.1")); }); test("with ErraiObject regular input, should return a JavaFloat instance", () => { const marshaller = new JavaFloatMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.1; const marshalledInput = new NumValBasedErraiObject(JavaType.FLOAT, input).asErraiObject(); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output).toEqual(new JavaFloat("1.1")); }); test("with non float value, should throw error", () => { const marshaller = new JavaFloatMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new NumValBasedErraiObject(JavaType.FLOAT, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should throw error", () => { const marshaller = new JavaFloatMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new NumValBasedErraiObject(JavaType.FLOAT, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should throw error", () => { const marshaller = new JavaFloatMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new NumValBasedErraiObject(JavaType.FLOAT, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaHashMapMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallerProvider } from "../../MarshallerProvider"; import { JavaArrayList, JavaBigDecimal, JavaBigInteger, JavaBoolean, JavaByte, JavaDate, JavaDouble, JavaFloat, JavaHashMap, JavaHashSet, JavaInteger, JavaLong, JavaOptional, JavaShort, JavaString } from "../../../java-wrappers"; import { JavaHashMapMarshaller } from "../JavaHashMapMarshaller"; import { MarshallingContext } from "../../MarshallingContext"; import { ErraiObjectConstants } from "../../model/ErraiObjectConstants"; import { Portable } from "../../../marshalling/Portable"; import { DefaultMarshaller } from "../DefaultMarshaller"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { NumberUtils } from "../../../util/NumberUtils"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { ValueBasedErraiObject } from "../../model/ValueBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { const encodedType = ErraiObjectConstants.ENCODED_TYPE; const objectId = ErraiObjectConstants.OBJECT_ID; const value = ErraiObjectConstants.VALUE; const json = ErraiObjectConstants.JSON; beforeEach(() => { MarshallerProvider.initialize(); }); test("with empty map, should serialize normally", () => { const input = new JavaHashMap(new Map()); const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: {} }); }); test("with string key and value, should serialize normally", () => { const input = new JavaHashMap(new Map([["foo1", "bar1"], ["foo2", "bar2"]])); const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { foo1: "bar1", foo2: "bar2" } }); }); test("with JavaNumber key and value, should wrap key and value into an errai object", () => { const input = new JavaHashMap( new Map([[new JavaInteger("11"), new JavaInteger("12")], [new JavaInteger("21"), new JavaInteger("22")]]) ); const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext()); const expectedKey1 = `${json + JSON.stringify(new NumValBasedErraiObject(JavaType.INTEGER, 11).asErraiObject())}`; const expectedKey2 = `${json + JSON.stringify(new NumValBasedErraiObject(JavaType.INTEGER, 21).asErraiObject())}`; expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { [expectedKey1]: new NumValBasedErraiObject(JavaType.INTEGER, 12).asErraiObject(), [expectedKey2]: new NumValBasedErraiObject(JavaType.INTEGER, 22).asErraiObject() } }); }); test("with JavaBoolean key and value, should wrap key and value into an errai object", () => { const input = new JavaHashMap( new Map([[new JavaBoolean(true), new JavaBoolean(false)], [new JavaBoolean(false), new JavaBoolean(true)]]) ); const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext()); const expectedKey1 = `${json + JSON.stringify(new NumValBasedErraiObject(JavaType.BOOLEAN, true).asErraiObject())}`; const expectedKey2 = `${json + JSON.stringify(new NumValBasedErraiObject(JavaType.BOOLEAN, false).asErraiObject())}`; expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { [expectedKey1]: new NumValBasedErraiObject(JavaType.BOOLEAN, false).asErraiObject(), [expectedKey2]: new NumValBasedErraiObject(JavaType.BOOLEAN, true).asErraiObject() } }); }); test("with JavaBigNumber key and value, should wrap key and value into an errai object", () => { const input = new JavaHashMap( new Map([ [new JavaBigInteger("11"), new JavaBigInteger("12")], [new JavaBigInteger("21"), new JavaBigInteger("22")] ]) ); const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext())!; // need to assert the keys individually because since it's a string, can't use the regex matcher in the object id :/ const mapKeys = Object.keys(output[value]); expect(mapKeys.length).toBe(2); const key1Str = mapKeys[0]; const key2Str = mapKeys[1]; mapKeys.forEach(k => { // complex objects as map key uses a prefix to indicate that a json must be parsed in the map key expect(k.startsWith(json)).toBeTruthy(); }); const key1Obj = JSON.parse(key1Str.replace(json, "")); const key2Obj = JSON.parse(key2Str.replace(json, "")); expect(key1Obj).toStrictEqual({ [encodedType]: JavaType.BIG_INTEGER, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "11" }); expect(key2Obj).toStrictEqual({ [encodedType]: JavaType.BIG_INTEGER, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "21" }); // assert map values expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { [key1Str]: { [encodedType]: JavaType.BIG_INTEGER, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "12" }, [key2Str]: { [encodedType]: JavaType.BIG_INTEGER, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "22" } } }); }); test("with custom object key and value, should wrap key and value into an errai object", () => { const input = new JavaHashMap( new Map([ [new DummyPojo({ foo: "bar11" }), new DummyPojo({ foo: "bar12" })], [new DummyPojo({ foo: "bar21" }), new DummyPojo({ foo: "bar22" })] ]) ); const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext())!; // need to assert the keys individually because since it's a string, can't use the regex matcher in the object id :/ const mapKeys = Object.keys(output[value]); expect(mapKeys.length).toBe(2); const key1Str = mapKeys[0]; const key2Str = mapKeys[1]; mapKeys.forEach(k => { // complex objects as map key uses a prefix to indicate that a json must be parsed in the map key expect(k.startsWith(json)).toBeTruthy(); }); const key1Obj = JSON.parse(key1Str.replace(json, "")); const key2Obj = JSON.parse(key2Str.replace(json, "")); expect(key1Obj).toStrictEqual({ [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "bar11" }); expect(key2Obj).toStrictEqual({ [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "bar21" }); // assert map values expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { [key1Str]: { [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "bar12" }, [key2Str]: { [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "bar22" } } }); }); test("with undefined key and value, should set key as null reference and value as null", () => { const input = new JavaHashMap(new Map([[undefined, undefined]])); const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { [ErraiObjectConstants.NULL]: null } }); }); test("with custom pojo containing cached key, should reuse it and don't repeat data", () => { const repeatedPojo = new DummyPojo({ foo: "repeatedKey" }); const input = new ComplexPojo({ dummy: repeatedPojo, map: new Map([[repeatedPojo, "value1"], [new DummyPojo({ foo: "uniqueKey" }), "value2"]]) }); const context = new MarshallingContext(); const output = new DefaultMarshaller().marshall(input, context)!; // ===== assertions // 1) Assert map content const mapOutput = (output as any).map; const mapKeys = Object.keys(mapOutput[value]); expect(mapKeys.length).toBe(2); const key1Str = mapKeys[0]; const key2Str = mapKeys[1]; mapKeys.forEach(k => { // complex objects as map key uses a prefix to indicate that a json must be parsed in the map key expect(k.startsWith(json)).toBeTruthy(); }); const key1Obj = JSON.parse(key1Str.replace(json, "")); const key2Obj = JSON.parse(key2Str.replace(json, "")); // assert keys contents const key1ObjectId = key1Obj[objectId]; // this is the cached object's id expect(key1ObjectId).toMatch(NumberUtils.nonNegativeIntegerRegex); expect(key1Obj).toStrictEqual({ [encodedType]: "com.app.my.DummyPojo", [objectId]: key1ObjectId // without object's content }); expect(key2Obj).toStrictEqual({ [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "uniqueKey" }); // assert map values contents expect(mapOutput).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { [key1Str]: "value1", [key2Str]: "value2" } }); // 2) Assert full object content expect(output).toStrictEqual({ [encodedType]: "com.app.my.ComplexPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), dummy: { [encodedType]: "com.app.my.DummyPojo", [objectId]: key1ObjectId, // same object id than the one used as map key foo: "repeatedKey" }, map: mapOutput // already asserted }); // do not cache repeated object's data expect(context.getCached(repeatedPojo)).toStrictEqual({ [encodedType]: "com.app.my.DummyPojo", [objectId]: key1ObjectId }); }); test("with map containing repeated value, should reuse it and don't repeat data", () => { const repeatedValue = new DummyPojo({ foo: "repeatedValue" }); const uniqueValue = new DummyPojo({ foo: "uniqueValue" }); const input = new JavaHashMap(new Map([["key1", repeatedValue], ["key2", repeatedValue], ["key3", uniqueValue]])); const context = new MarshallingContext(); const output = new JavaHashMapMarshaller().marshall(input, context); expect(output).toStrictEqual({ [encodedType]: JavaType.HASH_MAP, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: { key1: { [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "repeatedValue" }, key2: { [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex) // missing data }, key3: { [encodedType]: "com.app.my.DummyPojo", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "uniqueValue" } } }); // same object id const repeatedObjIdFirstAppearance = (output as any)[value].key1[objectId]; const repeatedObjIdSecondAppearance = (output as any)[value].key2[objectId]; expect(repeatedObjIdFirstAppearance).toEqual(repeatedObjIdSecondAppearance); // do not cache repeated object's data expect(context.getCached(repeatedValue)).toStrictEqual({ [encodedType]: "com.app.my.DummyPojo", [objectId]: repeatedObjIdFirstAppearance }); }); test("with root null object, should serialize to null", () => { const input = null as any; const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("with root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaHashMapMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { beforeEach(() => { MarshallerProvider.initialize(); }); test("with empty map, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map()); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map()); }); test("with string key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const stringInput = new JavaHashMap(new Map([["foo1", "bar1"]])); const javaStringInput = new JavaHashMap(new Map([[new JavaString("foo1"), new JavaString("bar1")]])); [stringInput, javaStringInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([["foo1", "bar1"]])); }); }); test("with Array key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const arrayInput = new JavaHashMap(new Map([[["foo1"], ["bar1"]]])); const arrayListInput = new JavaHashMap(new Map([[new JavaArrayList(["foo1"]), new JavaArrayList(["bar1"])]])); [arrayInput, arrayListInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[["foo1"], ["bar1"]]])); }); }); test("with Set key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const setInput = new JavaHashMap(new Map([[new Set(["foo1"]), new Set(["bar1"])]])); const hashSetInput = new JavaHashMap( new Map([[new JavaHashSet(new Set(["foo1"])), new JavaHashSet(new Set(["bar1"]))]]) ); [setInput, hashSetInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new Set(["foo1"]), new Set(["bar1"])]])); }); }); test("with Map key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const mapInput = new JavaHashMap(new Map([[new Map([["kfoo1", "kbar1"]]), new Map([["vfoo1", "vbar1"]])]])); const hashMapInput = new JavaHashMap( new Map([[new JavaHashMap(new Map([["kfoo1", "kbar1"]])), new JavaHashMap(new Map([["vfoo1", "vbar1"]]))]]) ); [mapInput, hashMapInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new Map([["kfoo1", "kbar1"]]), new Map([["vfoo1", "vbar1"]])]])); }); }); test("with Date key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const baseDateKey = new Date(); const baseDateValue = new Date(); const dateInput = new JavaHashMap(new Map([[baseDateKey, baseDateValue]])); const javaDateInput = new JavaHashMap(new Map([[new JavaDate(baseDateKey), new JavaDate(baseDateValue)]])); [dateInput, javaDateInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[baseDateKey, baseDateValue]])); }); }); test("with Boolean key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const booleanInput = new JavaHashMap(new Map([[false, true]])); const javaBooleanInput = new JavaHashMap(new Map([[new JavaBoolean(false), new JavaBoolean(true)]])); [booleanInput, javaBooleanInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[false, true]])); }); }); test("with String key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const stringInput = new JavaHashMap(new Map([["foo", "bar"]])); const javaStringInput = new JavaHashMap(new Map([[new JavaString("foo"), new JavaString("bar")]])); [stringInput, javaStringInput].forEach(input => { const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([["foo", "bar"]])); }); }); test("with JavaOptional key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaOptional("foo"), new JavaOptional("bar")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaOptional("foo"), new JavaOptional("bar")]])); }); test("with JavaBigDecimal key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaBigDecimal("1.1"), new JavaBigDecimal("1.1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaBigDecimal("1.1"), new JavaBigDecimal("1.1")]])); }); test("with JavaBigInteger key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaBigInteger("1"), new JavaBigInteger("1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaBigInteger("1"), new JavaBigInteger("1")]])); }); test("with JavaLong key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaLong("1"), new JavaLong("1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaLong("1"), new JavaLong("1")]])); }); test("with JavaByte key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaByte("1"), new JavaByte("1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaByte("1"), new JavaByte("1")]])); }); test("with JavaDouble key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaDouble("1.1"), new JavaDouble("1.1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaDouble("1.1"), new JavaDouble("1.1")]])); }); test("with JavaFloat key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaFloat("1.1"), new JavaFloat("1.1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaFloat("1.1"), new JavaFloat("1.1")]])); }); test("with JavaInteger key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaInteger("1"), new JavaInteger("1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaInteger("1"), new JavaInteger("1")]])); }); test("with JavaShort key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaShort("1"), new JavaShort("1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaShort("1"), new JavaShort("1")]])); }); test("with JavaShort key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[new JavaShort("1"), new JavaShort("1")]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[new JavaShort("1"), new JavaShort("1")]])); }); test("with custom object key and value, should unmarshall correctly", () => { const oracle = new Map([["com.app.my.DummyPojo", () => new DummyPojo({} as any)]]); const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap( new Map([ [new DummyPojo({ foo: "bar11" }), new DummyPojo({ foo: "bar12" })], [new DummyPojo({ foo: "bar21" }), new DummyPojo({ foo: "bar22" })] ]) ); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(oracle)); expect(output).toEqual( new Map([ [new DummyPojo({ foo: "bar11" }), new DummyPojo({ foo: "bar12" })], [new DummyPojo({ foo: "bar21" }), new DummyPojo({ foo: "bar22" })] ]) ); }); test("with undefined key and value, should unmarshall correctly", () => { const marshaller = new JavaHashMapMarshaller(); const input = new JavaHashMap(new Map([[undefined, undefined]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(new Map([[undefined, undefined]])); }); test("with custom pojo containing cached key, should reuse cached objects and don't recreate data", () => { const marshaller = new DefaultMarshaller(); const oracle: Map Portable> = new Map([ ["com.app.my.DummyPojo", () => new DummyPojo({} as any) as any], ["com.app.my.ComplexPojo", () => new ComplexPojo({} as any) as any] ]); const repeatedPojo = new DummyPojo({ foo: "repeatedKey" }); const input = new ComplexPojo({ dummy: repeatedPojo, map: new Map([[repeatedPojo, "value1"], [new DummyPojo({ foo: "uniqueKey" }), "value2"]]) }); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(oracle))! as ComplexPojo; // ===== assertions // successfully unmarshalled expect(output).toEqual(input); // same object for the cached one const repeatedPojoFromKey = output.map.keys().next().value; expect(output.dummy).toBe(repeatedPojoFromKey); }); test("with map containing repeated value, should reuse cached objects and don't recreate data", () => { const marshaller = new JavaHashMapMarshaller(); const oracle: Map Portable> = new Map([ ["com.app.my.DummyPojo", () => new DummyPojo({} as any)] ]); const repeatedPojo = new DummyPojo({ foo: "repeatedKey" }); const input = new JavaHashMap(new Map([["k1", repeatedPojo], ["k2", repeatedPojo]])); const marshalledInput = marshaller.marshall(input, new MarshallingContext())!; const output = marshaller.unmarshall(marshalledInput, new UnmarshallingContext(oracle))!; // ===== assertions // successfully unmarshalled expect(output).toEqual(new Map([["k1", repeatedPojo], ["k2", repeatedPojo]])); // same objects for the values expect(output.get("k1")!).toBe(output.get("k2")!); }); test("with null inside ErraiObject's value, should throw error", () => { const context = new UnmarshallingContext(new Map()); const marshaller = new JavaHashMapMarshaller(); const marshalledInput = new ValueBasedErraiObject(JavaType.HASH_MAP, null as any).asErraiObject(); expect(() => marshaller.unmarshall(marshalledInput!, context)).toThrowError(); }); }); class DummyPojo implements Portable { private readonly _fqcn = "com.app.my.DummyPojo"; public readonly foo: string; constructor(self: { foo: string }) { Object.assign(this, self); } } class ComplexPojo implements Portable { private readonly _fqcn = "com.app.my.ComplexPojo"; public dummy: DummyPojo; public map: Map; constructor(self: { dummy: DummyPojo; map: Map }) { Object.assign(this, self); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaIntegerMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaInteger } from "../../../java-wrappers"; import { JavaIntegerMarshaller } from "../JavaIntegerMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { test("with regular integer, should return the same value", () => { const input = new JavaInteger("2"); const output = new JavaIntegerMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(2); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaIntegerMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaIntegerMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { describe("number input", () => { test("with integer, should return a JavaInteger instance", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1; const output = marshaller.notNullUnmarshall(input, context); expect(output).toEqual(new JavaInteger("1")); }); test("with float, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.2; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with string, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with null, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with undefined, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); }); describe("ErraiObject input", () => { test("with integer, should return a JavaInteger instance", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output).toEqual(new JavaInteger("1")); }); test("with float, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.2; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with string, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaLongMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaLong } from "../../../java-wrappers"; import { JavaLongMarshaller } from "../JavaLongMarshaller"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { JavaType } from "../../../java-wrappers/JavaType"; import { JavaIntegerMarshaller } from "../JavaIntegerMarshaller"; describe("marshall", () => { test("with regular long, should should serialize it normally", () => { const input = new JavaLong("2"); const output = new JavaLongMarshaller().marshall(input, new MarshallingContext()); const expected = new NumValBasedErraiObject(JavaType.LONG, "2").asErraiObject(); expect(output).toStrictEqual(expected); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaLongMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaLongMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with regular input, should return a JavaLong instance", () => { const marshaller = new JavaLongMarshaller(); const context = new UnmarshallingContext(new Map()); const input = new JavaLong("125"); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output.get()).toEqual(input.get()); }); test("with float string value, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "1.2"; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with non numeric string value, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null value, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined value, should throw error", () => { const marshaller = new JavaIntegerMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new NumValBasedErraiObject(JavaType.INTEGER, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaOptionalMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaArrayList, JavaBigDecimal, JavaBigInteger, JavaBoolean, JavaByte, JavaDate, JavaDouble, JavaFloat, JavaHashMap, JavaHashSet, JavaInteger, JavaLong, JavaOptional, JavaShort, JavaString } from "../../../java-wrappers"; import { ErraiObjectConstants } from "../../model/ErraiObjectConstants"; import { MarshallerProvider } from "../../MarshallerProvider"; import { Portable } from "../../Portable"; import { JavaOptionalMarshaller } from "../JavaOptionalMarshaller"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { ValueBasedErraiObject } from "../../model/ValueBasedErraiObject"; import { NumberUtils } from "../../../util/NumberUtils"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { const encodedType = ErraiObjectConstants.ENCODED_TYPE; const objectId = ErraiObjectConstants.OBJECT_ID; const value = ErraiObjectConstants.VALUE; let context: MarshallingContext; beforeEach(() => { MarshallerProvider.initialize(); context = new MarshallingContext(); }); test("with empty optional, should serialize normally", () => { const input = new JavaOptional(undefined); const output = new JavaOptionalMarshaller().marshall(input, context); expect(output).toStrictEqual(new ValueBasedErraiObject(JavaType.OPTIONAL, null).asErraiObject()); }); test("with JavaNumber optional, should wrap element into an errai object", () => { const input = new JavaOptional(new JavaInteger("1")); const output = new JavaOptionalMarshaller().marshall(input, context); expect(output).toStrictEqual( new ValueBasedErraiObject( JavaType.OPTIONAL, new NumValBasedErraiObject(JavaType.INTEGER, 1).asErraiObject() ).asErraiObject() ); }); test("with JavaBoolean optional, should wrap element into an errai object", () => { const input = new JavaOptional(new JavaBoolean(false)); const output = new JavaOptionalMarshaller().marshall(input, context); expect(output).toStrictEqual( new ValueBasedErraiObject( JavaType.OPTIONAL, new NumValBasedErraiObject(JavaType.BOOLEAN, false).asErraiObject() ).asErraiObject() ); }); test("with JavaBigNumber optional, should serialize element normally", () => { const input = new JavaOptional(new JavaBigInteger("1")); const output = new JavaOptionalMarshaller().marshall(input, context); expect(output).toStrictEqual({ [encodedType]: JavaType.OPTIONAL, [objectId]: "-1", [value]: { [encodedType]: JavaType.BIG_INTEGER, [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), [value]: "1" } }); }); test("with custom object optional, should serialize element normally", () => { const input = new JavaOptional(new MyPortable({ foo: "foo1", bar: "bar1" })); const output = new JavaOptionalMarshaller().marshall(input, context); expect(output).toStrictEqual({ [encodedType]: JavaType.OPTIONAL, [objectId]: "-1", [value]: { [encodedType]: "com.portable.my", [objectId]: expect.stringMatching(NumberUtils.nonNegativeIntegerRegex), foo: "foo1", bar: "bar1" } }); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaOptionalMarshaller().marshall(input, context); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaOptionalMarshaller().marshall(input, context); expect(output).toBeNull(); }); }); describe("unmarshall", () => { beforeEach(() => { MarshallerProvider.initialize(); }); test("with empty optional, should return an empty optional", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(undefined); const marshalledInput = marshaller.marshall(input, new MarshallingContext()); const output = marshaller.unmarshall(marshalledInput!, new UnmarshallingContext(new Map())); expect(output).toEqual(input); }); test("with Array input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const arrayInput = new JavaOptional(["str1", "str2"]); const arrayListInput = new JavaOptional>(new JavaArrayList(["str1", "str2"])); [arrayInput, arrayListInput].forEach(input => { const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(["str1", "str2"])); }); }); test("with Set input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const setInput = new JavaOptional>(new Set(["str1", "str2"])); const hashSetInput = new JavaOptional>(new JavaHashSet(new Set(["str1", "str2"]))); [setInput, hashSetInput].forEach(input => { const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new Set(["str1", "str2"]))); }); }); test("with Map input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const mapInput = new JavaOptional>(new Map([["str1", "str2"]])); const hashMapInput = new JavaOptional>(new JavaHashMap(new Map([["str1", "str2"]]))); [mapInput, hashMapInput].forEach(input => { const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new Map([["str1", "str2"]]))); }); }); test("with Date input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const baseDate = new Date(); const dateInput = new JavaOptional(new Date(baseDate)); const javaDateInput = new JavaOptional(new JavaDate(baseDate)); [dateInput, javaDateInput].forEach(input => { const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new Date(baseDate))); }); }); test("with Boolean input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const booleanInput = new JavaOptional(false); const javaBooleanInput = new JavaOptional(new JavaBoolean(false)); [booleanInput, javaBooleanInput].forEach(input => { const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(false)); }); }); test("with String input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const stringInput = new JavaOptional("foo"); const javaStringInput = new JavaOptional(new JavaString("foo")); [stringInput, javaStringInput].forEach(input => { const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional("foo")); }); }); test("with JavaOptional input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaOptional("foo")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaOptional("foo"))); }); test("with JavaBigDecimal input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaBigDecimal("1.1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaBigDecimal("1.1"))); }); test("with JavaBigInteger should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaBigInteger("1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaBigInteger("1"))); }); test("with JavaLong input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaLong("1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaLong("1"))); }); test("with JavaByte input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaByte("1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaByte("1"))); }); test("with JavaDouble input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaDouble("1.1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaDouble("1.1"))); }); test("with JavaFloat input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaFloat("1.1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaFloat("1.1"))); }); test("with JavaInteger input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaInteger("1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaInteger("1"))); }); test("with JavaShort input, should unmarshall correctly", () => { const marshaller = new JavaOptionalMarshaller(); const input = new JavaOptional(new JavaShort("1")); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual(new JavaOptional(new JavaShort("1"))); }); test("with custom object optional, should unmarshall correctly", () => { const oracle = new Map([["com.portable.my", () => new MyPortable({} as any)]]); const marshaller = new JavaOptionalMarshaller(); const pojoInput = new MyPortable({ foo: "foo1", bar: "bar1" }); const optionalInput = new JavaOptional(pojoInput); const marshalledInput = marshaller.notNullMarshall(optionalInput, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(oracle)); expect(output).toEqual(new JavaOptional(pojoInput)); }); test("with root null object, should unmarshall to null", () => { const input = null as any; const output = new JavaOptionalMarshaller().unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toBeUndefined(); }); test("with root undefined object, should unmarshall to undefined", () => { const input = undefined as any; const output = new JavaOptionalMarshaller().unmarshall(input, new UnmarshallingContext(new Map())); expect(output).toBeUndefined(); }); }); class MyPortable implements Portable { private readonly _fqcn = "com.portable.my"; public readonly foo: string; public readonly bar: string; constructor(self: { foo: string; bar: string }) { Object.assign(this, self); } } ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaShortMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaShort } from "../../../java-wrappers"; import { JavaShortMarshaller } from "../JavaShortMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; import { JavaType } from "../../../java-wrappers/JavaType"; describe("marshall", () => { test("with regular short, should return the same value", () => { const input = new JavaShort("2"); const output = new JavaShortMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual(2); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaShortMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaShortMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { describe("number input", () => { test("with short, should return a JavaShort instance", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1; const output = marshaller.notNullUnmarshall(input, context); expect(output).toEqual(new JavaShort("1")); }); test("with float, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.2; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with string, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with null, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); test("with undefined, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; expect(() => marshaller.notNullUnmarshall(input, context)).toThrowError(); }); }); describe("ErraiObject input", () => { test("with short, should return a JavaShort instance", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1; const marshalledInput = new NumValBasedErraiObject(JavaType.SHORT, input).asErraiObject(); const output = marshaller.notNullUnmarshall(marshalledInput, context); expect(output).toEqual(new JavaShort("1")); }); test("with float, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = 1.2; const marshalledInput = new NumValBasedErraiObject(JavaType.SHORT, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with string, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = "abc" as any; const marshalledInput = new NumValBasedErraiObject(JavaType.SHORT, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with null, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = null as any; const marshalledInput = new NumValBasedErraiObject(JavaType.SHORT, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); test("with undefined, should throw error", () => { const marshaller = new JavaShortMarshaller(); const context = new UnmarshallingContext(new Map()); const input = undefined as any; const marshalledInput = new NumValBasedErraiObject(JavaType.SHORT, input).asErraiObject(); expect(() => marshaller.notNullUnmarshall(marshalledInput, context)).toThrowError(); }); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/__tests__/JavaStringMarshaller.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MarshallingContext } from "../../MarshallingContext"; import { JavaString } from "../../../java-wrappers"; import { JavaStringMarshaller } from "../JavaStringMarshaller"; import { UnmarshallingContext } from "../../UnmarshallingContext"; describe("marshall", () => { test("with regular string, should return the same value", () => { const input = new JavaString("str"); const output = new JavaStringMarshaller().marshall(input, new MarshallingContext()); expect(output).toStrictEqual("str"); }); test("root null object, should serialize to null", () => { const input = null as any; const output = new JavaStringMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); test("root undefined object, should serialize to null", () => { const input = undefined as any; const output = new JavaStringMarshaller().marshall(input, new MarshallingContext()); expect(output).toBeNull(); }); }); describe("unmarshall", () => { test("with string value, should return same string", () => { const marshaller = new JavaStringMarshaller(); const input = new JavaString("foo"); const marshalledInput = marshaller.notNullMarshall(input, new MarshallingContext()); const output = marshaller.notNullUnmarshall(marshalledInput, new UnmarshallingContext(new Map())); expect(output).toEqual("foo"); }); test("with JavaString value, should return inner string", () => { const marshaller = new JavaStringMarshaller(); const input = new JavaString("foo"); const output = marshaller.notNullUnmarshall(input, new UnmarshallingContext(new Map())); expect(output).toEqual("foo"); }); }); ================================================ FILE: appformer-js/src/marshalling/marshallers/util/GenericsTypeMarshallingUtils.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NumberWrapper } from "../../../java-wrappers/NumberWrapper"; import { JavaBoolean } from "../../../java-wrappers"; import { Portable } from "../../../marshalling/Portable"; import { ErraiObject } from "../../model/ErraiObject"; import { MarshallingContext } from "../../MarshallingContext"; import { MarshallerProvider } from "../../MarshallerProvider"; import { JavaWrapperUtils } from "../../../java-wrappers/JavaWrapperUtils"; import { NumValBasedErraiObject } from "../../model/NumValBasedErraiObject"; export class GenericsTypeMarshallingUtils { private static shouldWrapAsGenericsType(value: Portable) { return value instanceof NumberWrapper || value instanceof JavaBoolean; } private static wrapGenericsTypeElement(value: Portable, marshalledValue: any): ErraiObject { // This is mandatory in order to comply with errai-marshalling protocol. // When marshalling numeric or boolean values, we use its raw value, without any ErraiObject envelope. // But, when the value is a generic type, we always wrap it inside an ErraiObject return new NumValBasedErraiObject((value as any)._fqcn, marshalledValue).asErraiObject(); } public static marshallGenericsTypeElement(value: any, ctx: MarshallingContext): ErraiObject { // apply automatic native types -> java types conversion const enhancedInput = JavaWrapperUtils.wrapIfNeeded(value); const marshaller = MarshallerProvider.getForObject(enhancedInput); const marshalledValue = marshaller.marshall(enhancedInput, ctx); if (this.shouldWrapAsGenericsType(enhancedInput)) { return this.wrapGenericsTypeElement(enhancedInput, marshalledValue)!; } return marshalledValue; } } ================================================ FILE: appformer-js/src/marshalling/marshallers/util/__tests__/GenericsTypeMarshallingUtils.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { JavaArrayList, JavaBigDecimal, JavaBigInteger, JavaBoolean, JavaByte, JavaDate, JavaDouble, JavaFloat, JavaHashMap, JavaHashSet, JavaInteger, JavaLong, JavaOptional, JavaShort, JavaString } from "../../../../java-wrappers"; import { GenericsTypeMarshallingUtils } from "../GenericsTypeMarshallingUtils"; import { MarshallingContext } from "../../../MarshallingContext"; import { JavaArrayListMarshaller, JavaHashSetMarshaller } from "../../JavaCollectionMarshaller"; import { ErraiObjectConstants } from "../../../model/ErraiObjectConstants"; import { MarshallerProvider } from "../../../MarshallerProvider"; import { JavaBigDecimalMarshaller } from "../../JavaBigDecimalMarshaller"; import { JavaBigIntegerMarshaller } from "../../JavaBigIntegerMarshaller"; import { JavaHashMapMarshaller } from "../../JavaHashMapMarshaller"; import { JavaLongMarshaller } from "../../JavaLongMarshaller"; import { JavaStringMarshaller } from "../../JavaStringMarshaller"; import { JavaDateMarshaller } from "../../JavaDateMarshaller"; import { DefaultMarshaller } from "../../DefaultMarshaller"; import { Portable } from "../../../Portable"; import { JavaOptionalMarshaller } from "../../JavaOptionalMarshaller"; import { NumValBasedErraiObject } from "../../../model/NumValBasedErraiObject"; import { JavaType } from "../../../../java-wrappers/JavaType"; describe("marshallGenericsTypeElement", () => { const objectId = ErraiObjectConstants.OBJECT_ID; beforeEach(() => { MarshallerProvider.initialize(); }); test("with array input, should marshall with regular marshalling", () => { const baseArray = ["str1", "str2"]; const arrayInput = { input: baseArray, inputAsJavaArrayList: new JavaArrayList(baseArray) }; const javaArrayListInput = { input: new JavaArrayList(baseArray), inputAsJavaArrayList: new JavaArrayList(baseArray) }; [arrayInput, javaArrayListInput].forEach(({ input, inputAsJavaArrayList }) => { const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaArrayListMarshaller().marshall(inputAsJavaArrayList, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); }); test("with Set input, should marshall with regular marshalling", () => { const baseSet = new Set(["str1", "str2"]); const setInput = { input: baseSet, inputAsJavaHashSet: new JavaHashSet(baseSet) }; const javaHashSetInput = { input: new JavaHashSet(baseSet), inputAsJavaHashSet: new JavaHashSet(baseSet) }; [setInput, javaHashSetInput].forEach(({ input, inputAsJavaHashSet }) => { const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaHashSetMarshaller().marshall(inputAsJavaHashSet, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); }); test("with JavaBigDecimal input, should marshall with regular marshalling", () => { const input = new JavaBigDecimal("1.1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaBigDecimalMarshaller().marshall(input, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); test("with JavaBigInteger input, should marshall with regular marshalling", () => { const input = new JavaBigInteger("1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaBigIntegerMarshaller().marshall(input, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); test("with map input, should marshall with regular marshalling", () => { const baseMap = new Map([["foo1", "bar1"], ["foo2", "bar2"]]); const mapInput = { input: baseMap, inputAsJavaHashMap: new JavaHashMap(baseMap) }; const javaHashMapInput = { input: new JavaHashMap(baseMap), inputAsJavaHashMap: new JavaHashMap(baseMap) }; [mapInput, javaHashMapInput].forEach(({ input, inputAsJavaHashMap }) => { const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaHashMapMarshaller().marshall(inputAsJavaHashMap, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); }); test("with JavaLong input, should marshall with regular marshalling", () => { const input = new JavaLong("1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaLongMarshaller().marshall(input, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); test("with string input, should marshall with regular marshalling", () => { const stringInput = { input: "str", inputAsJavaString: new JavaString("str") }; const javaStringInput = { input: new JavaString("str"), inputAsJavaString: new JavaString("str") }; [stringInput, javaStringInput].forEach(({ input, inputAsJavaString }) => { const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaStringMarshaller().marshall(inputAsJavaString, new MarshallingContext())!; expect(output).toStrictEqual(expected); }); }); test("with date input, should marshall with regular marshalling", () => { const baseDate = new Date(); const dateInput = { input: baseDate, inputAsJavaDate: new JavaDate(baseDate) }; const javaDateInput = { input: new JavaDate(baseDate), inputAsJavaDate: new JavaDate(baseDate) }; [dateInput, javaDateInput].forEach(({ input, inputAsJavaDate }) => { const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaDateMarshaller().marshall(inputAsJavaDate, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); }); test("with JavaOptional input, should marshall with regular marshalling", () => { const input = new JavaOptional("str"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new JavaOptionalMarshaller().marshall(input, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); test("with custom portable input, should marshall with regular marshalling", () => { const input = new Pojo("bar"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); const expected = new DefaultMarshaller().marshall(input, new MarshallingContext())!; // don't care about the ids delete output[objectId]; delete expected[objectId]; expect(output).toStrictEqual(expected); }); test("with boolean input, should return input wrapped as an ErraiObject", () => { const booleanInput = false; const javaBooleanInput = new JavaBoolean(false); [booleanInput, javaBooleanInput].forEach(input => { const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); expect(output).toStrictEqual(new NumValBasedErraiObject(JavaType.BOOLEAN, false).asErraiObject()); }); }); test("with JavaByte input, should return input wrapped as an ErraiObject", () => { const input = new JavaByte("1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); expect(output).toStrictEqual(new NumValBasedErraiObject(JavaType.BYTE, 1).asErraiObject()); }); test("with JavaDouble input, should return input wrapped as an ErraiObject", () => { const input = new JavaDouble("1.1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); expect(output).toStrictEqual(new NumValBasedErraiObject(JavaType.DOUBLE, 1.1).asErraiObject()); }); test("with JavaFloat input, should return input wrapped as an ErraiObject", () => { const input = new JavaFloat("1.1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); expect(output).toStrictEqual(new NumValBasedErraiObject(JavaType.FLOAT, 1.1).asErraiObject()); }); test("with JavaInteger input, should return input wrapped as an ErraiObject", () => { const input = new JavaInteger("1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); expect(output).toStrictEqual(new NumValBasedErraiObject(JavaType.INTEGER, 1).asErraiObject()); }); test("with JavaShort input, should return input wrapped as an ErraiObject", () => { const input = new JavaShort("1"); const output = GenericsTypeMarshallingUtils.marshallGenericsTypeElement(input, new MarshallingContext()); expect(output).toStrictEqual(new NumValBasedErraiObject(JavaType.SHORT, 1).asErraiObject()); }); class Pojo implements Portable { private readonly _fqcn = "com.app.my.Pojo"; public foo: string; constructor(foo: string) { this.foo = foo; } } }); ================================================ FILE: appformer-js/src/marshalling/model/EnumStringValueBasedErraiObject.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ErraiObject } from "./ErraiObject"; import { ErraiObjectConstants } from "./ErraiObjectConstants"; export class EnumStringValueBasedErraiObject { public readonly encodedType: string; public readonly enumValueName: string; constructor(encodedType: string, enumValueName: string) { this.encodedType = encodedType; this.enumValueName = enumValueName; } public asErraiObject(): ErraiObject { return { [ErraiObjectConstants.ENCODED_TYPE]: this.encodedType, [ErraiObjectConstants.ENUM_STRING_VALUE]: this.enumValueName }; } public static from(obj: ErraiObject): EnumStringValueBasedErraiObject { return new EnumStringValueBasedErraiObject( obj[ErraiObjectConstants.ENCODED_TYPE], obj[ErraiObjectConstants.ENUM_STRING_VALUE]! ); } } ================================================ FILE: appformer-js/src/marshalling/model/ErraiObject.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ErraiObjectConstants } from "./ErraiObjectConstants"; export interface ErraiObject { [ErraiObjectConstants.ENCODED_TYPE]: string; [ErraiObjectConstants.OBJECT_ID]?: string; [ErraiObjectConstants.NUM_VAL]?: string | number | boolean; [ErraiObjectConstants.VALUE]?: any; [ErraiObjectConstants.ENUM_STRING_VALUE]?: string; } ================================================ FILE: appformer-js/src/marshalling/model/ErraiObjectConstants.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export enum ErraiObjectConstants { ENCODED_TYPE = "^EncodedType", OBJECT_ID = "^ObjectID", NUM_VAL = "^NumVal", VALUE = "^Value", JSON = "^${$JSON$}$::", NULL = "^NullVal", ENUM_STRING_VALUE = "^EnumStringValue" } ================================================ FILE: appformer-js/src/marshalling/model/NumValBasedErraiObject.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ErraiObject } from "./ErraiObject"; import { ErraiObjectConstants } from "./ErraiObjectConstants"; export class NumValBasedErraiObject { public readonly encodedType: string; public readonly objId: string; public readonly numVal: number | boolean | string; constructor(encodedType: string, numVal: number | boolean | string, objectId: string = "-1") { this.encodedType = encodedType; this.numVal = numVal; this.objId = objectId; } public asErraiObject(): ErraiObject { return { [ErraiObjectConstants.ENCODED_TYPE]: this.encodedType, [ErraiObjectConstants.OBJECT_ID]: this.objId, [ErraiObjectConstants.NUM_VAL]: this.numVal }; } public static from(obj: ErraiObject): NumValBasedErraiObject { return new NumValBasedErraiObject( obj[ErraiObjectConstants.ENCODED_TYPE], obj[ErraiObjectConstants.NUM_VAL]!, obj[ErraiObjectConstants.OBJECT_ID] ); } } ================================================ FILE: appformer-js/src/marshalling/model/ValueBasedErraiObject.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ErraiObject } from "./ErraiObject"; import { ErraiObjectConstants } from "./ErraiObjectConstants"; export class ValueBasedErraiObject { public readonly encodedType: string; public readonly objId: string; public readonly value: any; constructor(encodedType: string, value: any, objectId: string = "-1") { this.encodedType = encodedType; this.value = value; this.objId = objectId; } public asErraiObject(): ErraiObject { return { [ErraiObjectConstants.ENCODED_TYPE]: this.encodedType, [ErraiObjectConstants.OBJECT_ID]: this.objId, [ErraiObjectConstants.VALUE]: this.value }; } public static from(obj: ErraiObject): ValueBasedErraiObject { return new ValueBasedErraiObject( obj[ErraiObjectConstants.ENCODED_TYPE], obj[ErraiObjectConstants.VALUE], obj[ErraiObjectConstants.OBJECT_ID] ); } } ================================================ FILE: appformer-js/src/marshalling/model/__tests__/EnumStringValueBasedErraiObject.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ErraiObjectConstants } from "../ErraiObjectConstants"; import { EnumStringValueBasedErraiObject } from "../EnumStringValueBasedErraiObject"; describe("asErraiObject", () => { test("with correct inputs, should return correct a well formed Errai Object", () => { const input = new EnumStringValueBasedErraiObject("com.app.my", "foo"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.ENUM_STRING_VALUE]: "foo" }); }); }); describe("from", () => { test("with well formed errai object instance, should retrieve its data correctly", () => { const input = { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.ENUM_STRING_VALUE]: "foo" }; const output = EnumStringValueBasedErraiObject.from(input); expect(output.encodedType).toEqual("com.app.my"); expect(output.enumValueName).toEqual("foo"); }); }); ================================================ FILE: appformer-js/src/marshalling/model/__tests__/NumValBasedErraiObject.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NumValBasedErraiObject } from "../NumValBasedErraiObject"; import { ErraiObjectConstants } from "../ErraiObjectConstants"; import { isBoolean, isNumber, isString } from "../../../util/TypeUtils"; describe("asErraiObject", () => { describe("with objectId filled", () => { test("with numeric numVal, should return correct a well formed Errai Object", () => { const input = new NumValBasedErraiObject("com.app.my", 120, "12"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "12", [ErraiObjectConstants.NUM_VAL]: 120 }); }); test("with boolean numVal, should return correct a well formed Errai Object", () => { const input = new NumValBasedErraiObject("com.app.my", false, "13"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "13", [ErraiObjectConstants.NUM_VAL]: false }); }); test("with string numVal, should return correct a well formed Errai Object", () => { const input = new NumValBasedErraiObject("com.app.my", "str", "14"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "14", [ErraiObjectConstants.NUM_VAL]: "str" }); }); }); describe("with objectId not filled", () => { test("with numeric numVal, should return correct a well formed Errai Object applying objId's default", () => { const input = new NumValBasedErraiObject("com.app.my", 120); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "-1", [ErraiObjectConstants.NUM_VAL]: 120 }); }); test("with boolean numVal, should return correct a well formed Errai Object applying objId's default", () => { const input = new NumValBasedErraiObject("com.app.my", false); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "-1", [ErraiObjectConstants.NUM_VAL]: false }); }); test("with string numVal, should return correct a well formed Errai Object applying objId's default", () => { const input = new NumValBasedErraiObject("com.app.my", "str"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "-1", [ErraiObjectConstants.NUM_VAL]: "str" }); }); }); }); describe("from", () => { test("with numeric NumVal based errai object instance, should retrieve its data correctly", () => { const input = { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "125", [ErraiObjectConstants.NUM_VAL]: 1 }; const output = NumValBasedErraiObject.from(input); expect(output.encodedType).toEqual("com.app.my"); expect(output.objId).toEqual("125"); expect(isNumber(output.numVal)).toBeTruthy(); expect(output.numVal).toBe(1); }); test("with boolean NumVal based errai object instance, should retrieve its data correctly", () => { const input = { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "125", [ErraiObjectConstants.NUM_VAL]: false }; const output = NumValBasedErraiObject.from(input); expect(output.encodedType).toEqual("com.app.my"); expect(output.objId).toEqual("125"); expect(isBoolean(output.numVal)).toBeTruthy(); expect(output.numVal).toBe(false); }); test("with string NumVal based errai object instance, should retrieve its data correctly", () => { const input = { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "125", [ErraiObjectConstants.NUM_VAL]: "str" }; const output = NumValBasedErraiObject.from(input); expect(output.encodedType).toEqual("com.app.my"); expect(output.objId).toEqual("125"); expect(isString(output.numVal)).toBeTruthy(); expect(output.numVal).toBe("str"); }); }); ================================================ FILE: appformer-js/src/marshalling/model/__tests__/ValueBasedErraiObject.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NumValBasedErraiObject } from "../NumValBasedErraiObject"; import { ErraiObjectConstants } from "../ErraiObjectConstants"; import { ValueBasedErraiObject } from "../ValueBasedErraiObject"; describe("asErraiObject", () => { describe("with objectId filled", () => { test("with string value, should return correct a well formed Errai Object", () => { const input = new ValueBasedErraiObject("com.app.my", "bla", "12"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "12", [ErraiObjectConstants.VALUE]: "bla" }); }); test("with ErraiObject value, should return correct a well formed Errai Object", () => { const innerVal = new NumValBasedErraiObject("com.app.my", false, "2").asErraiObject(); const input = new ValueBasedErraiObject("my.fqcn", innerVal, "13"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "my.fqcn", [ErraiObjectConstants.OBJECT_ID]: "13", [ErraiObjectConstants.VALUE]: { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "2", [ErraiObjectConstants.NUM_VAL]: false } }); }); }); describe("with objectId not filled", () => { test("with string value, should return correct a well formed Errai Object applying objId's default", () => { const input = new ValueBasedErraiObject("com.app.my", "bla"); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "-1", [ErraiObjectConstants.VALUE]: "bla" }); }); test("with ErraiObject value, should return correct a well formed Errai Object applying objId's default", () => { const innerVal = new NumValBasedErraiObject("com.app.my", false, "2").asErraiObject(); const input = new ValueBasedErraiObject("my.fqcn", innerVal); expect(input.asErraiObject()).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "my.fqcn", [ErraiObjectConstants.OBJECT_ID]: "-1", [ErraiObjectConstants.VALUE]: { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "2", [ErraiObjectConstants.NUM_VAL]: false } }); }); }); }); describe("from", () => { test("with string Value based errai object instance, should retrieve its data correctly", () => { const input = { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "125", [ErraiObjectConstants.VALUE]: "str" }; const output = ValueBasedErraiObject.from(input); expect(output.encodedType).toEqual("com.app.my"); expect(output.objId).toEqual("125"); expect(output.value).toBe("str"); }); test("with ErraiObject Value based errai object instance, should retrieve its data correctly", () => { const innerVal = new NumValBasedErraiObject("com.app.my", false, "2").asErraiObject(); const input = { [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "125", [ErraiObjectConstants.VALUE]: innerVal }; const output = ValueBasedErraiObject.from(input); expect(output.encodedType).toEqual("com.app.my"); expect(output.objId).toEqual("125"); expect(output.value).toStrictEqual({ [ErraiObjectConstants.ENCODED_TYPE]: "com.app.my", [ErraiObjectConstants.OBJECT_ID]: "2", [ErraiObjectConstants.NUM_VAL]: false }); }); }); ================================================ FILE: appformer-js/src/util/DomUtils.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export const AfComponentAttr = "af-js-component"; export function findChildContainers(container: HTMLElement): HTMLElement[] { const searchResult = searchChildren({ root: container, stopWhen: (elem: any) => Boolean(getAfComponentAttr(elem)), accept: (elem: any) => Boolean(getAfComponentAttr(elem)) }); return searchResult.accepted; } const flatten = (arr: T[][]) => ([] as T[]).concat(...arr); function searchParents(args: { accept: (elem: HTMLElement) => boolean; stop: (elem: HTMLElement) => boolean; element: HTMLElement; }) { let parent = args.element.parentElement; while (parent) { if (args.stop(parent)) { return args.accept(parent); } parent = parent.parentElement; } return false; } function searchChildren(args: { root: HTMLElement; stopWhen: (elem: HTMLElement) => boolean; accept: (elem: HTMLElement) => boolean; }) { const { root, stopWhen, accept } = args; let node: any; const stack = [root]; stack.push(root); const accepted = new Set(); const visited = new Set(); while (stack.length > 0) { node = stack.pop()!; if (node !== root && node instanceof HTMLElement && stopWhen(node)) { if (accept(node)) { accepted.add(node); } visited.add(node); } else if (node.children && node.children.length) { for (const child of node.children) { stack.push(child); } } } return { visited: Array.from(visited), accepted: Array.from(accepted) }; } function getAfComponentAttr(container: HTMLElement) { return container.getAttribute(AfComponentAttr); } ================================================ FILE: appformer-js/src/util/NumberUtils.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export class NumberUtils { public static readonly nonNegativeIntegerRegex = new RegExp(/^\d*$/); public static readonly integerNumberRegex = new RegExp(/^(-)?\d*$/); public static readonly floatNumberRegex = new RegExp(/^(-)?(\d*)(\.)?(\d*)$/); public static isNonNegativeIntegerString(str: string): boolean { return this.nonNegativeIntegerRegex.test(str); } public static isIntegerString(str: string): boolean { return this.integerNumberRegex.test(str); } public static isFloatString(str: string): boolean { return this.floatNumberRegex.test(str); } } ================================================ FILE: appformer-js/src/util/TypeUtils.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export function isString(obj: any): boolean { return typeof obj === "string" || obj instanceof String; } export function instanceOfString(obj: any): obj is string { return isString(obj); } export function isArray(obj: any): boolean { return obj instanceof Array; } export function instanceOfArray(obj: any): obj is T[] { return isArray(obj); } export function isSet(obj: any): boolean { return obj instanceof Set; } export function instanceOfSet(obj: any): obj is Set { return isSet(obj); } export function isMap(obj: any): boolean { return obj instanceof Map; } export function instanceOfMap(obj: any): obj is Map { return isMap(obj); } export function isBoolean(obj: any): boolean { return typeof obj === "boolean" || obj instanceof Boolean; } export function instanceOfBoolean(obj: any): obj is boolean { return isBoolean(obj); } export function isDate(obj: any): boolean { return obj instanceof Date; } export function instanceOfDate(obj: any): obj is Date { return isDate(obj); } export function isNumber(obj: any): boolean { return typeof obj === "number"; } export function instanceOfNumber(obj: any): obj is number { return isNumber(obj); } ================================================ FILE: appformer-js/src/util/__tests__/NumberUtils.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { NumberUtils } from "../NumberUtils"; describe("isNonNegativeIntegerString", () => { test("with non negative integer string, should return true", () => { const input = "1"; const output = NumberUtils.isNonNegativeIntegerString(input); expect(output).toBeTruthy(); }); test("with negative integer string, should return false", () => { const input = "-1"; const output = NumberUtils.isNonNegativeIntegerString(input); expect(output).toBeFalsy(); }); test("with non negative float string, should return false", () => { const input = "1.1"; const output = NumberUtils.isNonNegativeIntegerString(input); expect(output).toBeFalsy(); }); test("with non numeric string, should return false", () => { const input = "abc"; const output = NumberUtils.isNonNegativeIntegerString(input); expect(output).toBeFalsy(); }); }); describe("isIntegerString", () => { test("with non negative integer string, should return true", () => { const input = "1"; const output = NumberUtils.isIntegerString(input); expect(output).toBeTruthy(); }); test("with negative integer string, should return true", () => { const input = "-1"; const output = NumberUtils.isIntegerString(input); expect(output).toBeTruthy(); }); test("with non negative float string, should return false", () => { const input = "1.1"; const output = NumberUtils.isIntegerString(input); expect(output).toBeFalsy(); }); test("with negative float string, should return false", () => { const input = "-1.1"; const output = NumberUtils.isIntegerString(input); expect(output).toBeFalsy(); }); test("with non numeric string, should return false", () => { const input = "abc"; const output = NumberUtils.isIntegerString(input); expect(output).toBeFalsy(); }); }); describe("isFloatString", () => { test("with non negative integer string, should return true", () => { const input = "1"; const output = NumberUtils.isFloatString(input); expect(output).toBeTruthy(); }); test("with negative integer string, should return true", () => { const input = "-1"; const output = NumberUtils.isFloatString(input); expect(output).toBeTruthy(); }); test("with non negative float string, should return true", () => { const input = "1.1"; const output = NumberUtils.isFloatString(input); expect(output).toBeTruthy(); }); test("with negative float string, should return true", () => { const input = "-1.1"; const output = NumberUtils.isFloatString(input); expect(output).toBeTruthy(); }); test("with non numeric string, should return false", () => { const input = "abc"; const output = NumberUtils.isFloatString(input); expect(output).toBeFalsy(); }); }); ================================================ FILE: appformer-js/src/util/__tests__/TypeUtils.test.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { instanceOfArray, instanceOfBoolean, instanceOfDate, instanceOfMap, instanceOfNumber, instanceOfSet, instanceOfString, isArray, isBoolean, isDate, isMap, isNumber, isSet, isString } from "../TypeUtils"; describe("isString", () => { test("with direct assigned string, should return true", () => { const input = "str"; const output = isString(input); expect(output).toBeTruthy(); }); test("with string created via constructor, should return true", () => { const input = String("str"); const output = isString(input); expect(output).toBeTruthy(); }); test("with non-string input, should return false", () => { const input = 1; const output = isString(input); expect(output).toBeFalsy(); }); }); describe("instanceOfString", () => { test("with direct assigned string, should return true", () => { const input = "str"; const output = instanceOfString(input); expect(output).toBeTruthy(); }); test("with string created via constructor, should return true", () => { const input = String("str"); const output = instanceOfString(input); expect(output).toBeTruthy(); }); test("with non-string input, should return false", () => { const input = 1; const output = instanceOfString(input); expect(output).toBeFalsy(); }); }); describe("isArray", () => { test("with direct assigned array, should return true", () => { const input = [1, 2, 3]; const output = isArray(input); expect(output).toBeTruthy(); }); test("with array created via constructor, should return true", () => { const input = new Array(1, 2, 3); const output = isArray(input); expect(output).toBeTruthy(); }); test("with non-array input, should return false", () => { const input = 1; const output = isArray(input); expect(output).toBeFalsy(); }); }); describe("instanceOfArray", () => { test("with direct assigned array, should return true", () => { const input = [1, 2, 3]; const output = instanceOfArray(input); expect(output).toBeTruthy(); }); test("with array created via constructor, should return true", () => { const input = new Array(1, 2, 3); const output = instanceOfArray(input); expect(output).toBeTruthy(); }); test("with non-array input, should return false", () => { const input = 1; const output = instanceOfArray(input); expect(output).toBeFalsy(); }); }); describe("isSet", () => { test("with set created via constructor, should return true", () => { const input = new Set([1, 2, 3]); const output = isSet(input); expect(output).toBeTruthy(); }); test("with non-set input, should return false", () => { const input = 1; const output = isSet(input); expect(output).toBeFalsy(); }); }); describe("instanceOfSet", () => { test("with set created via constructor, should return true", () => { const input = new Set([1, 2, 3]); const output = instanceOfSet(input); expect(output).toBeTruthy(); }); test("with non-set input, should return false", () => { const input = 1; const output = instanceOfSet(input); expect(output).toBeFalsy(); }); }); describe("isMap", () => { test("with map created via constructor, should return true", () => { const input = new Map([[1, 2]]); const output = isMap(input); expect(output).toBeTruthy(); }); test("with non-set input, should return false", () => { const input = 1; const output = isMap(input); expect(output).toBeFalsy(); }); }); describe("instanceOfMap", () => { test("with map created via constructor, should return true", () => { const input = new Map([[1, 2]]); const output = instanceOfMap(input); expect(output).toBeTruthy(); }); test("with non-set input, should return false", () => { const input = 1; const output = instanceOfMap(input); expect(output).toBeFalsy(); }); }); describe("isBoolean", () => { test("with direct assigned boolean, should return true", () => { const input = false; const output = isBoolean(input); expect(output).toBeTruthy(); }); test("with boolean created via constructor, should return true", () => { const input = Boolean(false); const output = isBoolean(input); expect(output).toBeTruthy(); }); test("with non-boolean input, should return false", () => { const input = 1; const output = isBoolean(input); expect(output).toBeFalsy(); }); }); describe("instanceOfBoolean", () => { test("with direct assigned boolean, should return true", () => { const input = false; const output = instanceOfBoolean(input); expect(output).toBeTruthy(); }); test("with boolean created via constructor, should return true", () => { const input = Boolean(false); const output = instanceOfBoolean(input); expect(output).toBeTruthy(); }); test("with non-boolean input, should return false", () => { const input = 1; const output = instanceOfBoolean(input); expect(output).toBeFalsy(); }); }); describe("isDate", () => { test("with date created via constructor, should return true", () => { const input = new Date(); const output = isDate(input); expect(output).toBeTruthy(); }); test("with non-date input, should return false", () => { const input = 1; const output = isDate(input); expect(output).toBeFalsy(); }); }); describe("instanceOfDate", () => { test("with date created via constructor, should return true", () => { const input = new Date(); const output = instanceOfDate(input); expect(output).toBeTruthy(); }); test("with non-date input, should return false", () => { const input = 1; const output = instanceOfDate(input); expect(output).toBeFalsy(); }); }); describe("isNumber", () => { test("with direct assigned number, should return true", () => { const input = 1; const output = isNumber(input); expect(output).toBeTruthy(); }); test("with number created via constructor, should return true", () => { const input = Number(1); const output = isNumber(input); expect(output).toBeTruthy(); }); test("with non-number input, should return false", () => { const input = true; const output = isNumber(input); expect(output).toBeFalsy(); }); }); describe("instanceOfNumber", () => { test("with direct assigned number, should return true", () => { const input = 1; const output = instanceOfNumber(input); expect(output).toBeTruthy(); }); test("with number created via constructor, should return true", () => { const input = Number(1); const output = instanceOfNumber(input); expect(output).toBeTruthy(); }); test("with non-number input, should return false", () => { const input = true; const output = instanceOfNumber(input); expect(output).toBeFalsy(); }); }); ================================================ FILE: appformer-js/src/util/index.ts ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./DomUtils"; ================================================ FILE: appformer-js/tsconfig.json ================================================ { "exclude": [ "./node_modules" ], "include": [ "./src" ], "compilerOptions": { "outDir": "./", "lib": [ "es6", "dom" ], "target": "es5", "declaration": true, "sourceMap": true, "noImplicitAny": true, "strictNullChecks": true, "experimentalDecorators": true, "jsx": "react" } } ================================================ FILE: appformer-js/tsconfig.webpack.json ================================================ { "exclude": ["./node_modules", "./src/**/__tests__"], "extends": "./tsconfig.json" } ================================================ FILE: appformer-js/tslint.json ================================================ { "defaultSeverity": "error", "extends": [ "tslint:recommended", "tslint-react", "tslint-config-prettier" ], "jsRules": {}, "rules": { "jsx-no-multiline-js": false, "ordered-imports": false, "object-literal-sort-keys": false, "no-console": false, "interface-name": [ true, "never-prefix" ], "max-classes-per-file": false, "jsx-no-lambda": false, "member-ordering": [ true, { "order": [ "static-field", "instance-field", "constructor", "instance-method", "static-method" ] } ], "variable-name": [ true, "ban-keywords", "check-format", "allow-snake-case", "allow-pascal-case", "allow-leading-underscore" ], "comment-format": false }, "rulesDirectory": [] } ================================================ FILE: appformer-js/webpack.config.js ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require("path"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const CircularDependencyPlugin = require("circular-dependency-plugin"); module.exports = { mode: "development", entry: { "appformer-js": "./src/index.ts" }, output: { path: path.resolve(__dirname, "./dist"), filename: "appformer.js", library: "AppFormer", libraryTarget: "umd", umdNamedDefine: true }, externals: { react: { root: "React", //indicates global variable commonjs: "react", commonjs2: "react", amd: "react" }, "react-dom": { root: "ReactDOM", //indicates global variable commonjs: "react-dom", commonjs2: "react-dom", amd: "react-dom" } }, plugins: [ new CleanWebpackPlugin(["dist"]), new CircularDependencyPlugin({ exclude: /node_modules/, // exclude detection of files based on a RegExp failOnError: false, // add errors to webpack instead of warnings cwd: process.cwd() // set the current working directory for displaying module paths }) ], module: { rules: [ { test: /\.tsx?$/, loader: "ts-loader", options: { configFile: path.resolve("./tsconfig.webpack.json") } }, { test: /\.jsx?$/, exclude: /node_modules/, use: ["babel-loader"] } ] }, resolve: { extensions: [".tsx", ".ts", ".js", ".jsx"], modules: [path.resolve("../../node_modules"), path.resolve("./node_modules"), path.resolve("./src")] } }; ================================================ FILE: appformer-js-bridge/pom.xml ================================================ 4.0.0 org.uberfire uberfire-parent 7.75.0-SNAPSHOT ../pom.xml appformer-js-bridge jar AppFormer JS Bridge AppFormer JS Bridge com.google.elemental2 elemental2-dom provided com.google.elemental2 elemental2-core provided com.google.elemental2 elemental2-promise provided org.jboss.errai errai-ioc provided org.jboss.errai errai-bus provided org.jboss.errai errai-common provided org.jboss.errai errai-cdi-shared provided org.jboss.errai errai-ui provided com.google.guava guava provided org.jboss.errai errai-marshalling provided com.google.jsinterop base provided org.uberfire uberfire-backend-api provided org.uberfire uberfire-api provided org.uberfire uberfire-commons provided org.uberfire uberfire-client-api provided org.jboss.errai errai-cdi-client provided org.uberfire uberfire-workbench-client provided com.google.gwt gwt-user provided org.uberfire uberfire-workbench-processors provided org.uberfire uberfire-testing-utils test com.google.gwt.gwtmockito gwtmockito test org.uberfire appformer-js provided org.powermock powermock-api-mockito2 test org.powermock powermock-module-junit4 test org.apache.maven.plugins maven-dependency-plugin unpack-appformer-js process-resources unpack org.uberfire appformer-js jar true ${project.build.directory}/appformer-js **/appformer.js false true unpack-react process-resources unpack org.webjars.npm react ${version.org.webjars.npm.react} jar true ${project.build.directory}/react false true unpack-react-dom process-resources unpack org.webjars.npm react-dom ${version.org.webjars.npm.react-dom} jar true ${project.build.directory}/react-dom false true org.apache.maven.plugins maven-resources-plugin copy-appformer-js process-resources copy-resources ${project.build.outputDirectory}/org/uberfire/jsbridge/public ${project.build.directory}/appformer-js/META-INF/resources/webjars/appformer-js/${project.version} appformer.js copy-react process-resources copy-resources ${project.build.outputDirectory}/org/uberfire/jsbridge/public ${project.build.directory}/react/META-INF/resources/webjars/react/${version.org.webjars.npm.react}/umd react.production.min.js copy-react-dom process-resources copy-resources ${project.build.outputDirectory}/org/uberfire/jsbridge/public ${project.build.directory}/react-dom/META-INF/resources/webjars/react-dom/${version.org.webjars.npm.react-dom}/umd react-dom.production.min.js ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/AppFormerJsBridge.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client; import java.lang.annotation.Annotation; import java.util.function.Consumer; import java.util.function.Function; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.Callback; import com.google.gwt.core.client.ScriptInjector; import elemental2.dom.DomGlobal; import elemental2.promise.IThenable; import elemental2.promise.Promise; import org.jboss.errai.bus.client.ErraiBus; import org.jboss.errai.bus.client.api.base.MessageBuilder; import org.jboss.errai.enterprise.client.cdi.api.CDI; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.jboss.errai.marshalling.client.Marshalling; import org.jboss.errai.ui.client.local.spi.TranslationService; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.promise.Promises; import org.uberfire.client.workbench.Workbench; import org.uberfire.jsbridge.client.loading.AppFormerJsActivityLoader; import org.uberfire.mvp.impl.DefaultPlaceRequest; import static java.util.Arrays.stream; @Dependent public class AppFormerJsBridge { private final Workbench workbench; private final AppFormerJsActivityLoader appFormerJsLoader; private final Promises promises; @Inject public AppFormerJsBridge(final Workbench workbench, final AppFormerJsActivityLoader appFormerJsLoader, final Promises promises) { this.workbench = workbench; this.appFormerJsLoader = appFormerJsLoader; this.promises = promises; } public void init(final String gwtModuleName) { workbench.addStartupBlocker(AppFormerJsBridge.class); exposeBridgeAsNativeJs(); loadAppFormerJsAndReactScripts(gwtModuleName).then(i -> { try { appFormerJsLoader.init(gwtModuleName); } finally { workbench.removeStartupBlocker(AppFormerJsBridge.class); } return promises.resolve(); }).catch_(e -> { workbench.removeStartupBlocker(AppFormerJsBridge.class); return promises.resolve(); }); } public void exposeBridgeAsNativeJs() { exposeBridge(); } public Promise loadAppFormerJsAndReactScripts(final String gwtModuleName) { return promises.create((res, rej) -> { final Consumer onError = ex -> { workbench.removeStartupBlocker(AppFormerJsBridge.class); rej.onInvoke(null); }; final CallbackProducer callback = new CallbackProducer<>(onError); ScriptInjector.fromUrl(gwtModuleName + "/react.production.min.js") .setWindow(ScriptInjector.TOP_WINDOW) .setCallback(callback.withSuccess((v) -> ScriptInjector.fromUrl(gwtModuleName + "/react-dom.production.min.js") .setWindow(ScriptInjector.TOP_WINDOW) .setCallback(callback.withSuccess((v1) -> ScriptInjector.fromUrl(gwtModuleName + "/appformer.js") .setWindow(ScriptInjector.TOP_WINDOW) .setCallback(callback.withSuccess((v2) -> ScriptInjector.fromUrl(gwtModuleName + "/AppFormerComponentsRegistry.js") .setWindow(ScriptInjector.TOP_WINDOW) .setCallback(callback.withSuccess((v3) -> { res.onInvoke((IThenable) null); })) .inject())) .inject())) .inject())) .inject(); }); } private native void exposeBridge() /*-{ $wnd.appformerGwtBridge = { registerScreen: this.@org.uberfire.jsbridge.client.AppFormerJsBridge::registerScreen(Ljava/lang/Object;), registerPerspective: this.@org.uberfire.jsbridge.client.AppFormerJsBridge::registerPerspective(Ljava/lang/Object;), goTo: this.@org.uberfire.jsbridge.client.AppFormerJsBridge::goTo(Ljava/lang/String;), goToPath: this.@org.uberfire.jsbridge.client.AppFormerJsBridge::goToPath(Ljava/lang/String;), rpc: this.@org.uberfire.jsbridge.client.AppFormerJsBridge::rpc(Ljava/lang/String;[Ljava/lang/Object;), translate: this.@org.uberfire.jsbridge.client.AppFormerJsBridge::translate(Ljava/lang/String;[Ljava/lang/Object;), fireEvent: this.@org.uberfire.jsbridge.client.AppFormerJsBridge::fireEvent(Ljava/lang/String;), render: function (component, container, callback) { if (component instanceof HTMLElement) { container.innerHTML = ""; container.appendChild(component); callback(); } else if (typeof component === "string") { container.innerHTML = component; callback(); } else { $wnd.ReactDOM.render(component, container, callback); } } }; }-*/; public void fireEvent(final String eventJson) { CDI.fireEvent(Marshalling.fromJSON(eventJson)); } public void goTo(final String place) { final SyncBeanManager beanManager = IOC.getBeanManager(); final PlaceManager placeManager = beanManager.lookupBean(PlaceManager.class).getInstance(); placeManager.goTo(new DefaultPlaceRequest(place)); } public void goToPath(final String uri) { final SyncBeanManager beanManager = IOC.getBeanManager(); final PlaceManager placeManager = beanManager.lookupBean(PlaceManager.class).getInstance(); final PathFactory.PathImpl path = new PathFactory.PathImpl(uri.split("//")[uri.split("//").length - 1], uri); //TODO: Un-expose PathImpl constructor? placeManager.goTo(path); } public String translate(final String key, final Object[] args) { final SyncBeanManager beanManager = IOC.getBeanManager(); final TranslationService translationService = beanManager.lookupBean(TranslationService.class).getInstance(); return translationService.format(key, args); } public void registerPerspective(final Object jsObject) { final SyncBeanManager beanManager = IOC.getBeanManager(); final AppFormerJsActivityLoader jsLoader = beanManager.lookupBean(AppFormerJsActivityLoader.class).getInstance(); jsLoader.onComponentLoaded(jsObject); } public void registerScreen(final Object jsObject) { final SyncBeanManager beanManager = IOC.getBeanManager(); final AppFormerJsActivityLoader jsLoader = beanManager.lookupBean(AppFormerJsActivityLoader.class).getInstance(); jsLoader.onComponentLoaded(jsObject); } public Promise rpc(final String path, final Object[] params) { //TODO: Marshall/unmarshall is happening twice? final String[] parts = path.split("\\|"); final String serviceFqcn = parts[0]; final String method = parts[1]; final Annotation[] qualifiers = {}; //TODO: Support qualifiers? final Function jsonToGwt = object -> { try { return Marshalling.fromJSON((String) object); } catch (final Exception e) { DomGlobal.console.info("Error converting JS obj to GWT obj", e); throw e; } }; final Function gwtToJson = value -> value != null ? Marshalling.toJSON(value) : null; final Object[] gwtParams = stream(params).map(jsonToGwt).toArray(); return new Promise<>((res, rej) -> MessageBuilder.createCall() .call(serviceFqcn) .endpoint(method, qualifiers, gwtParams) .respondTo(Object.class, value -> res.onInvoke(gwtToJson.apply(value))) .errorsHandledBy((e, a) -> { rej.onInvoke(e); return true; }) .sendNowWith(ErraiBus.get())); } private static class CallbackProducer { private final Consumer onFailure; CallbackProducer(final Consumer onFailure) { this.onFailure = onFailure; } Callback withSuccess(final Consumer onSuccess) { return new Callback() { @Override public void onFailure(Exception e) { onFailure.accept(e); } @Override public void onSuccess(T t) { onSuccess.accept(t); } }; } } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/JsPlaceRequest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client; import java.util.HashMap; import java.util.Map; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONString; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; public class JsPlaceRequest extends JavaScriptObject { protected JsPlaceRequest() { } public static JsPlaceRequest fromPlaceRequest(PlaceRequest pr) { JsPlaceRequest jspr = newInstance(); jspr.setIdentifier(pr.getIdentifier()); JSONObject rawParams = new JSONObject(); for (String name : pr.getParameterNames()) { rawParams.put(name, new JSONString(pr.getParameters().get(name))); } jspr.setParams(rawParams.getJavaScriptObject()); return jspr; } public static native JsPlaceRequest newInstance() /*-{ return {identifier: '', params: {}}; }-*/; public final native String getIdentifier() /*-{ return this.identifier; }-*/; public final native void setIdentifier(final String newIdentifier) /*-{ this.identifier = newIdentifier; }-*/; public final native JavaScriptObject getParams() /*-{ return this.params; }-*/; public final native void setParams(final JavaScriptObject newParams) /*-{ this.params = newParams; }-*/; } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/cdi/EditorActivityBeanDefinition.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.cdi; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.Set; import java.util.function.Supplier; import javax.enterprise.context.Dependent; import org.jboss.errai.ioc.client.QualifierUtil; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.uberfire.client.mvp.Activity; import org.uberfire.client.mvp.WorkbenchEditorActivity; import org.uberfire.jsbridge.client.editor.JsWorkbenchEditorActivity; import static java.util.Arrays.asList; import static org.jboss.errai.ioc.client.QualifierUtil.DEFAULT_QUALIFIERS; public class EditorActivityBeanDefinition implements SyncBeanDef { private final Supplier factory; private final Set> assignableTypes = new HashSet<>(); public EditorActivityBeanDefinition(final Supplier factory) { this.factory = factory; assignableTypes.add(JsWorkbenchEditorActivity.class); assignableTypes.add(WorkbenchEditorActivity.class); assignableTypes.add(Activity.class); } @Override public Class getType() { return JsWorkbenchEditorActivity.class; } @Override public Class getBeanClass() { return JsWorkbenchEditorActivity.class; } @Override public Class getScope() { return Dependent.class; } @Override public JsWorkbenchEditorActivity getInstance() { return factory.get(); } @Override public JsWorkbenchEditorActivity newInstance() { throw new UnsupportedOperationException(); } @Override public Set getQualifiers() { return new HashSet<>(asList(DEFAULT_QUALIFIERS)); } @Override public boolean matches(final Set annotations) { return QualifierUtil.matches(annotations, getQualifiers()); } @Override public String getName() { return "JsWorkbenchEditorActivityBean"; } @Override public boolean isActivated() { return true; } @Override public boolean isAssignableTo(final Class type) { return assignableTypes.contains(type); } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/cdi/SingletonBeanDefinition.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.cdi; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.inject.Singleton; import org.jboss.errai.ioc.client.QualifierUtil; import org.jboss.errai.ioc.client.container.SyncBeanDef; public class SingletonBeanDefinition implements SyncBeanDef { private final B instance; private final Class type; private final Set qualifiers; private final String name; private final boolean activated; private final Set> assignableTypes = new HashSet<>(); public SingletonBeanDefinition(final B instance, final Class type, final Set qualifiers, final String name, final boolean activated, final Class... otherAssignableTypes) { this.instance = instance; this.type = type; this.qualifiers = qualifiers; this.name = name; this.activated = activated; assignableTypes.add(type); assignableTypes.addAll(Arrays.asList(otherAssignableTypes)); } @Override public Class getType() { return type; } @Override public Class getBeanClass() { return instance.getClass(); } @Override public Class getScope() { return Singleton.class; } @Override public T getInstance() { return instance; } @Override public T newInstance() { throw new UnsupportedOperationException(); } @Override public Set getQualifiers() { return qualifiers == null ? Collections.emptySet() : qualifiers; } @Override public boolean matches(final Set annotations) { return QualifierUtil.matches(annotations, getQualifiers()); } @Override public String getName() { return name; } @Override public boolean isActivated() { return activated; } @Override public boolean isAssignableTo(final Class type) { return assignableTypes.contains(type); } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/editor/JsNativeEditor.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.editor; import elemental2.dom.DomGlobal; import elemental2.dom.HTMLElement; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.mvp.PlaceRequest; public class JsNativeEditor { private final Object self; private final String componentId; private final HTMLElement container; public JsNativeEditor(final String componentId, final Object self) { this.componentId = componentId; this.self = self; this.container = (HTMLElement) DomGlobal.document.createElement("div"); } public String getComponentId() { return componentId; } public native boolean af_isDirty() /*-{ return this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_isDirty"](); }-*/; public native int af_priority() /*-{ return this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_priority"]; }-*/; public native String af_componentTitle() /*-{ return this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_componentTitle"]; }-*/; public native String[] af_resourceTypes() /*-{ return this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_resourceTypes"]; }-*/; public void af_onEditorStartup(final ObservablePath path, final PlaceRequest place) { this.native_af_onEditorStartup(path, place); } public native void native_af_onEditorStartup(final Object path, final Object place) /*-{ this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onEditorStartup"](path, place); }-*/; public void af_onOpen() { this.mount(); native_af_onOpen(); } public native void native_af_onOpen() /*-{ this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onOpen"](); }-*/; public native void af_onSave() /*-{ this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onSave"](); }-*/; public native void af_onFocus() /*-{ this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onFocus"](); }-*/; public native void af_onLostFocus() /*-{ this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onLostFocus"](); }-*/; public native boolean af_onMayClose() /*-{ return this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onMayClose"](); }-*/; public void af_onClose() { this.unmount(); native_af_onClose(); } public native void native_af_onClose() /*-{ this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onClose"](); }-*/; public native void af_onShutdown() /*-{ this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_onShutdown"](); }-*/; public native void mount() /*-{ $wnd.AppFormer.render( this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_componentRoot"](), this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::container); }-*/; public native void unmount() /*-{ if (this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::self["af_isReact"]) { $wnd.ReactDOM.unmountComponentAtNode(this.@org.uberfire.jsbridge.client.editor.JsNativeEditor::container); } }-*/; public HTMLElement getElement() { return container; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/editor/JsWorkbenchEditorActivity.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.editor; import java.util.function.Consumer; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.client.mvp.AbstractWorkbenchEditorActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.WorkbenchEditorActivity; import org.uberfire.jsbridge.client.loading.AppFormerJsActivityLoader; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; @AppFormerJsActivityLoader.Shadowed public class JsWorkbenchEditorActivity extends AbstractWorkbenchEditorActivity implements WorkbenchEditorActivity { private JsNativeEditor editor; @Inject public JsWorkbenchEditorActivity(final PlaceManager placeManager) { super(placeManager); } public JsWorkbenchEditorActivity withEditor(final JsNativeEditor editor) { this.editor = editor; return this; } // Lifecycle @Override public void onStartup(final ObservablePath path, final PlaceRequest place) { super.onStartup(path, place); editor.af_onEditorStartup(path, place); } @Override public void onOpen() { super.onOpen(); editor.af_onOpen(); } @Override public void onSave() { super.onSave(); editor.af_onSave(); } @Override public void onFocus() { super.onFocus(); editor.af_onFocus(); } @Override public void onLostFocus() { super.onLostFocus(); editor.af_onLostFocus(); } @Override public boolean onMayClose() { return super.onMayClose() && editor.af_onMayClose(); } @Override public void onClose() { super.onClose(); editor.af_onClose(); } @Override public void onShutdown() { super.onShutdown(); editor.af_onShutdown(); } // Properties @Override public boolean isDirty() { return super.isDirty() || editor.af_isDirty(); } @Override public String getTitle() { return editor.af_componentTitle(); } @Override public IsWidget getWidget() { return ElementWrapperWidget.getWidget(editor.getElement()); } @Override public void getMenus(final Consumer consumer) { consumer.accept(null); } @Override public ToolBar getToolBar() { return null; //TODO: Implement? } @Override public String getIdentifier() { return editor.getComponentId(); } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/loading/ActivityLazyLoaded.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import java.util.Objects; import org.uberfire.client.mvp.Activity; import org.uberfire.workbench.events.UberFireEvent; public class ActivityLazyLoaded implements UberFireEvent { private final String identifier; private final Activity activity; public ActivityLazyLoaded(final String identifier, final Activity activity) { this.identifier = identifier; this.activity = activity; } public String getIdentifier() { return identifier; } public Activity getActivity() { return activity; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ActivityLazyLoaded that = (ActivityLazyLoaded) o; return Objects.equals(identifier, that.identifier) && Objects.equals(activity, that.activity); } @Override public int hashCode() { return Objects.hash(identifier, activity); } @Override public String toString() { return "ActivityLazyLoaded{" + "identifier='" + identifier + '\'' + ", activity=" + activity + '}'; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/loading/AppFormerComponentsRegistry.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import java.util.HashMap; import java.util.Map; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.json.client.JSONObject; import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Optional.ofNullable; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; @ApplicationScoped public class AppFormerComponentsRegistry { public native String[] keys() /*-{ if (typeof $wnd.AppFormerComponentsRegistry === "undefined") { return []; } return Object.keys($wnd.AppFormerComponentsRegistry); }-*/; public native JavaScriptObject get(final String key) /*-{ if (typeof $wnd.AppFormerComponentsRegistry[key] === "undefined") { return null; } return $wnd.AppFormerComponentsRegistry[key]; }-*/; public static class Entry { private final String componentId; private final JavaScriptObject self; public Entry(final String componentId, final JavaScriptObject self) { checkNotNull(componentId); checkNotNull(self); this.componentId = componentId; this.self = self; } JavaScriptObject getSelf() { return self; } public String getComponentId() { return this.componentId; } public Entry.Type getType() { return Entry.Type.valueOf(((String) get("type")).toUpperCase()); } public String getSource() { return (String) get("source"); } public Map getParams() { final JavaScriptObject jsParams = (JavaScriptObject) get("params"); if (jsParams == null) { return new HashMap<>(); } final JSONObject json = new JSONObject(jsParams); return json.keySet().stream() .filter(k -> json.get(k) != null) .collect(toMap(identity(), k -> json.get(k).toString())); } private native Object get(final String key) /*-{ return this.@org.uberfire.jsbridge.client.loading.AppFormerComponentsRegistry.Entry::self[key]; }-*/; public boolean matches(final String uri) { final String matches = getParams().get("matches"); final String regex = matches.substring(1, matches.length() - 1); //FIXME: Temporary workaround to remove extra quotes return uri.matches(regex); } public enum Type { PERSPECTIVE, SCREEN, EDITOR, } public static class PerspectiveParams { private final Map params; public PerspectiveParams(final Map params) { this.params = params; } public Optional isDefault() { return ofNullable(this.params.get("is_default")).map(Boolean::valueOf); } } public static class EditorParams { private final Map params; public EditorParams(final Map params) { this.params = params; } public Optional matches() { return ofNullable(this.params.get("matches")); } } } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/loading/AppFormerJsActivityLoader.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import javax.enterprise.event.Event; import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.inject.Qualifier; import com.google.gwt.core.client.Callback; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.ScriptInjector; import elemental2.dom.DomGlobal; import elemental2.promise.Promise; import elemental2.promise.Promise.PromiseExecutorCallbackFn.RejectCallbackFn; import elemental2.promise.Promise.PromiseExecutorCallbackFn.ResolveCallbackFn; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.backend.vfs.Path; import org.uberfire.client.mvp.Activity; import org.uberfire.client.mvp.ActivityBeansCache; import org.uberfire.client.mvp.ActivityManager; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.PlaceManagerImpl; import org.uberfire.client.mvp.WorkbenchEditorActivity; import org.uberfire.client.mvp.WorkbenchScreenActivity; import org.uberfire.client.mvp.jsbridge.JsWorkbenchLazyActivity; import org.uberfire.client.promise.Promises; import org.uberfire.jsbridge.client.cdi.EditorActivityBeanDefinition; import org.uberfire.jsbridge.client.cdi.SingletonBeanDefinition; import org.uberfire.jsbridge.client.editor.JsNativeEditor; import org.uberfire.jsbridge.client.editor.JsWorkbenchEditorActivity; import org.uberfire.jsbridge.client.screen.JsNativeScreen; import org.uberfire.jsbridge.client.screen.JsWorkbenchScreenActivity; import org.uberfire.mvp.impl.DefaultPlaceRequest; import static com.google.gwt.core.client.ScriptInjector.TOP_WINDOW; import static java.util.Arrays.stream; import static java.util.Optional.ofNullable; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toList; import static org.jboss.errai.ioc.client.QualifierUtil.DEFAULT_QUALIFIERS; @EntryPoint public class AppFormerJsActivityLoader implements PlaceManagerImpl.AppFormerActivityLoader { private final Promises promises; private final ActivityManager activityManager; private final ActivityBeansCache activityBeansCache; private final PlaceManager placeManager; private final LazyLoadingScreen lazyLoadingScreen; private final Event activityLazyLoadedEvent; private final Instance jsWorkbenchEditorActivityInstance; private final AppFormerComponentsRegistry appFormerComponentsRegistry; private final Map components = new HashMap<>(); private final Set loadedScripts = new HashSet<>(); final Map editors = new HashMap<>(); private String gwtModuleName; @Inject public AppFormerJsActivityLoader(final Promises promises, final ActivityManager activityManager, final ActivityBeansCache activityBeansCache, final PlaceManager placeManager, final LazyLoadingScreen lazyLoadingScreen, final Event activityLazyLoadedEvent, final @Shadowed Instance jsWorkbenchEditorActivityInstance, final AppFormerComponentsRegistry appFormerComponentsRegistry) { this.promises = promises; this.activityManager = activityManager; this.activityBeansCache = activityBeansCache; this.placeManager = placeManager; this.lazyLoadingScreen = lazyLoadingScreen; this.activityLazyLoadedEvent = activityLazyLoadedEvent; this.jsWorkbenchEditorActivityInstance = jsWorkbenchEditorActivityInstance; this.appFormerComponentsRegistry = appFormerComponentsRegistry; } public void init(final String gwtModuleName) { this.gwtModuleName = gwtModuleName; stream(appFormerComponentsRegistry.keys()) .map(this::newRegistryEntry) .forEach(this::registerComponent); } AppFormerComponentsRegistry.Entry newRegistryEntry(final String componentId) { return new AppFormerComponentsRegistry.Entry(componentId, appFormerComponentsRegistry.get(componentId)); } public void onComponentLoaded(final Object jsObject) { final String componentId = extractComponentId(jsObject); if (editors.containsKey(componentId)) { registerEditor(jsObject, componentId); return; } if (!components.containsKey(componentId)) { throw new IllegalArgumentException("Cannot find component " + componentId); } final Activity activity = updateRealContent((JavaScriptObject) jsObject, componentId); activityLazyLoadedEvent.fire(new ActivityLazyLoaded(componentId, activity)); } Activity updateRealContent(final JavaScriptObject jsObject, final String componentId) { //FIXME: Get activity bean from BeanManager to prevent onStartup to be invoked. final Activity activity = activityManager.getActivity(new DefaultPlaceRequest(componentId)); final JsWorkbenchLazyActivity lazyActivity = (JsWorkbenchLazyActivity) activity; lazyActivity.updateRealContent(jsObject); return activity; } public native String extractComponentId(final Object object) /*-{ return object['af_componentId']; }-*/; Promise loadScriptFor(final String componentId) { final Optional scriptFilename = getScriptFileName(componentId); //Script not found if (!scriptFilename.isPresent()) { throw new RuntimeException("No script found for " + componentId); } //Already loaded if (loadedScripts.contains(scriptFilename.get())) { return promises.resolve(); } loadedScripts.add(scriptFilename.get()); return loadScript(gwtModuleName + "/" + scriptFilename.get()).catch_(e -> { DomGlobal.console.info("Error loading script for " + componentId); loadedScripts.remove(scriptFilename.get()); return promises.reject(e); }); } Optional getScriptFileName(final String componentId) { final Optional editorScriptUrl = ofNullable(editors.get(componentId)) .map(AppFormerComponentsRegistry.Entry::getSource); return editorScriptUrl.isPresent() ? editorScriptUrl : ofNullable(components.get(componentId)); } Promise loadScript(final String scriptUrl) { return promises.create((res, rej) -> ScriptInjector.fromUrl(scriptUrl) .setWindow(TOP_WINDOW) .setCallback(getScriptInjectionCallback(res, rej)) .inject()); } private Callback getScriptInjectionCallback(final ResolveCallbackFn res, final RejectCallbackFn rej) { return new Callback() { @Override public void onFailure(final Exception e1) { rej.onInvoke(e1); } @Override public void onSuccess(final Void v) { res.onInvoke(v); } }; } void registerComponent(final AppFormerComponentsRegistry.Entry registryEntry) { switch (registryEntry.getType()) { case PERSPECTIVE: registerPerspective(registryEntry); components.put(registryEntry.getComponentId(), registryEntry.getSource()); break; case SCREEN: registerScreen(registryEntry); components.put(registryEntry.getComponentId(), registryEntry.getSource()); break; case EDITOR: registerEditor(registryEntry); break; } } public boolean triggerLoadOfMatchingEditors(final Path path, final Runnable successCallback) { if (path == null || path.toURI() == null) { return false; } final List> loadingMatchingEditors = loadMatchingEditors(path.toURI()); if (loadingMatchingEditors.size() <= 0) { return false; } finishLoadingMatchingEditors(loadingMatchingEditors, successCallback); return true; } List> loadMatchingEditors(final String uri) { return editors.values().stream() .filter(e -> e.matches(uri)) .filter(e -> !loadedScripts.contains(e.getSource())) .map(e -> this.loadScriptFor(e.getComponentId())) .collect(toList()); } protected void finishLoadingMatchingEditors(final List> loadingMatchingEditors, final Runnable successCallback) { this.promises.resolve().then(i -> promises.all(loadingMatchingEditors, identity()).then(s -> { successCallback.run(); return this.promises.resolve(); })).catch_(e -> { //If something goes wrong, it's a no-op. return this.promises.resolve(); }); } void registerEditor(final AppFormerComponentsRegistry.Entry registryEntry) { this.editors.put(registryEntry.getComponentId(), registryEntry); } @SuppressWarnings("unchecked") void registerScreen(final AppFormerComponentsRegistry.Entry registryEntry) { final JsNativeScreen newScreen = new JsNativeScreen(registryEntry.getComponentId(), this::loadScriptFor, lazyLoadingScreen); final JsWorkbenchScreenActivity activity = new JsWorkbenchScreenActivity(newScreen, placeManager); //FIXME: Check if this bean is being registered correctly. Startup/Shutdown is begin called as if they were Open/Close. final SingletonBeanDefinition activityBean = new SingletonBeanDefinition<>( activity, JsWorkbenchScreenActivity.class, new HashSet<>(Arrays.asList(DEFAULT_QUALIFIERS)), activity.getIdentifier(), true, WorkbenchScreenActivity.class, JsWorkbenchLazyActivity.class, Activity.class); activityBeansCache.addNewScreenActivity(activityBean); final SyncBeanManager beanManager = IOC.getBeanManager(); beanManager.registerBean(activityBean); beanManager.registerBeanTypeAlias(activityBean, WorkbenchScreenActivity.class); beanManager.registerBeanTypeAlias(activityBean, JsWorkbenchLazyActivity.class); beanManager.registerBeanTypeAlias(activityBean, Activity.class); } @SuppressWarnings("unchecked") void registerPerspective(final AppFormerComponentsRegistry.Entry registryEntry) { final SyncBeanManager beanManager = IOC.getBeanManager(); final ActivityBeansCache activityBeansCache = beanManager.lookupBean(ActivityBeansCache.class).getInstance(); final PlaceManager placeManager = beanManager.lookupBean(PlaceManager.class).getInstance(); final ActivityManager activityManager = beanManager.lookupBean(ActivityManager.class).getInstance(); final JsWorkbenchLazyPerspectiveActivity activity = new JsWorkbenchLazyPerspectiveActivity(registryEntry, placeManager, activityManager, this::loadScriptFor); final SingletonBeanDefinition activityBean = new SingletonBeanDefinition<>( activity, JsWorkbenchLazyPerspectiveActivity.class, new HashSet<>(Arrays.asList(DEFAULT_QUALIFIERS)), activity.getIdentifier(), true, PerspectiveActivity.class, JsWorkbenchLazyActivity.class, Activity.class); beanManager.registerBean(activityBean); beanManager.registerBeanTypeAlias(activityBean, PerspectiveActivity.class); beanManager.registerBeanTypeAlias(activityBean, JsWorkbenchLazyActivity.class); beanManager.registerBeanTypeAlias(activityBean, Activity.class); activityBeansCache.addNewPerspectiveActivity(beanManager.lookupBeans(((PerspectiveActivity) activity).getIdentifier()).iterator().next()); } @Qualifier public @interface Shadowed { } @SuppressWarnings("unchecked") void registerEditor(final Object jsObject, final String componentId) { final JsNativeEditor editor = new JsNativeEditor(componentId, jsObject); final SyncBeanManager beanManager = IOC.getBeanManager(); final EditorActivityBeanDefinition activityBean = new EditorActivityBeanDefinition<>( () -> jsWorkbenchEditorActivityInstance.get().withEditor(new JsNativeEditor(componentId, jsObject)) ); beanManager.registerBean(activityBean); beanManager.registerBeanTypeAlias(activityBean, WorkbenchEditorActivity.class); beanManager.registerBeanTypeAlias(activityBean, Activity.class); activityBeansCache.addNewEditorActivity(activityBean, editor.af_priority(), Arrays.asList(editor.af_resourceTypes())); } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/loading/JsWorkbenchLazyPerspectiveActivity.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import java.util.function.Consumer; import com.google.gwt.core.client.JavaScriptObject; import org.uberfire.client.mvp.AbstractWorkbenchPerspectiveActivity; import org.uberfire.client.mvp.ActivityManager; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.jsbridge.JsWorkbenchLazyPerspective; import org.uberfire.client.workbench.panels.impl.ImmutableWorkbenchPanelPresenter; import org.uberfire.jsbridge.client.loading.AppFormerComponentsRegistry.Entry.PerspectiveParams; import org.uberfire.jsbridge.client.perspective.JsWorkbenchPerspectiveActivity; import org.uberfire.jsbridge.client.perspective.JsWorkbenchTemplatedPerspectiveActivity; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.mvp.impl.ForcedPlaceRequest; import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; public class JsWorkbenchLazyPerspectiveActivity extends AbstractWorkbenchPerspectiveActivity implements JsWorkbenchLazyPerspective { private final ActivityManager activityManager; private final String backedPerspectiveId; private final boolean configuredIsDefault; PerspectiveActivity backedPerspective; private boolean loaded; private final Consumer lazyLoadingParentScript; public JsWorkbenchLazyPerspectiveActivity(final AppFormerComponentsRegistry.Entry registryEntry, final PlaceManager placeManager, final ActivityManager activityManager, final Consumer lazyLoadingParentScript) { super(placeManager); this.activityManager = activityManager; this.backedPerspectiveId = registryEntry.getComponentId(); this.lazyLoadingParentScript = lazyLoadingParentScript; this.configuredIsDefault = new PerspectiveParams(registryEntry.getParams()).isDefault().orElse(super.isDefault()); this.loaded = false; } @Override public void updateRealContent(final JavaScriptObject backedPerspectiveJsObject) { this.loaded = true; backedPerspective = getBackedPerspective(backedPerspectiveJsObject); if (activityManager.isStarted(this)) { // current activity is started, need to move the backed perspective to started state getBackedPerspective().onStartup(place); } if (open) { // lazy perspective is opened, need to move the backed perspective to open state and refresh the page getBackedPerspective().onOpen(); placeManager.goTo(new ForcedPlaceRequest(backedPerspectiveId)); } } PerspectiveActivity getBackedPerspective(final JavaScriptObject backedPerspectiveJsObject) { final JsNativePerspective jsPerspective = new JsNativePerspective(backedPerspectiveJsObject); if (isPerspectiveTemplated(jsPerspective)) { return new JsWorkbenchTemplatedPerspectiveActivity(getIdentifier(), isDefault(), jsPerspective, placeManager); } else { return new JsWorkbenchPerspectiveActivity(jsPerspective, placeManager, isDefault()); } } public boolean isPerspectiveTemplated(final JsNativePerspective jsPerspective) { return jsPerspective.isTemplated(); } @Override public PerspectiveActivity get() { if (isPerspectiveLoaded()) { return getBackedPerspective(); } return this; } // Lifecycle @Override public void onStartup(final PlaceRequest place) { this.place = place; if (isPerspectiveLoaded()) { getBackedPerspective().onStartup(place); return; } super.onStartup(place); } @Override public void onOpen() { if (isPerspectiveLoaded()) { getBackedPerspective().onOpen(); } else { super.onOpen(); onLoaded(); // trigger backed perspective loading } placeManager.executeOnOpenCallbacks(place); } @Override public void onClose() { if (isPerspectiveLoaded()) { getBackedPerspective().onClose(); } else { super.onClose(); } placeManager.executeOnCloseCallbacks(place); } @Override public void onShutdown() { if (isPerspectiveLoaded()) { getBackedPerspective().onShutdown(); return; } super.onShutdown(); } void onLoaded() { lazyLoadingParentScript.accept(backedPerspectiveId); } // Properties PerspectiveActivity getBackedPerspective() { return backedPerspective; } @Override public ResourceType getResourceType() { return ActivityResourceType.PERSPECTIVE; } @Override public String getIdentifier() { return backedPerspectiveId; } @Override public boolean isDefault() { // we ignore the isDefault() property of the backed perspective. return configuredIsDefault; } @Override public boolean isTransient() { if (isPerspectiveLoaded()) { return getBackedPerspective().isTransient(); } // lazy perspectives are always transient. // We don't want to propagate the changes made while the real perspective was loading. return true; } @Override public void getMenus(final Consumer consumer) { if (isPerspectiveLoaded()) { getBackedPerspective().getMenus(consumer); } else { super.getMenus(consumer); } } @Override public ToolBar getToolBar() { if (isPerspectiveLoaded()) { return getBackedPerspective().getToolBar(); } return super.getToolBar(); } @Override public PerspectiveDefinition getDefaultPerspectiveLayout() { if (isPerspectiveLoaded()) { return getBackedPerspective().getDefaultPerspectiveLayout(); } return buildEmptyDefinition(); } boolean isPerspectiveLoaded() { return loaded; } private PerspectiveDefinition buildEmptyDefinition() { final PerspectiveDefinition def = new PerspectiveDefinitionImpl(ImmutableWorkbenchPanelPresenter.class.getName()); def.setName(getIdentifier()); // perspective not loaded yet, we don't know its name def.getRoot().addPart(new PartDefinitionImpl(new DefaultPlaceRequest(LazyLoadingScreen.IDENTIFIER))); return def; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/loading/LazyLoadingScreen.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import javax.annotation.PostConstruct; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Label; import org.jboss.errai.ui.client.local.api.elemental2.IsElement; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartTitleDecoration; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.workbench.model.menu.Menus; @Templated("lazy-loading.html") @WorkbenchScreen(identifier = LazyLoadingScreen.IDENTIFIER) public class LazyLoadingScreen implements IsElement { public static final String IDENTIFIER = "LazyLoadingScreen"; private Label title; @PostConstruct public void init() { this.title = new Label(getTitle()); } @WorkbenchPartTitle public String getTitle() { return "Lazy Loading Screen"; } @WorkbenchPartTitleDecoration public IsWidget getTitleDecoration() { return title; } @WorkbenchPartView public org.jboss.errai.common.client.api.elemental2.IsElement getView() { return this; } @WorkbenchMenu public Menus getMenu() { return null; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/loading/lazy-loading.html ================================================

Please wait

Component is loading...
================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/JsWorkbenchPanelConverter.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativeContextDisplay; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativePanel; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.impl.ContextDefinitionImpl; import org.uberfire.workbench.model.impl.PanelDefinitionImpl; public class JsWorkbenchPanelConverter { private final JsNativePanel nativePanel; public JsWorkbenchPanelConverter(final JsNativePanel nativePanel) { this.nativePanel = nativePanel; } public PanelDefinition toPanelDefinition() { final PanelDefinition newPanel = new PanelDefinitionImpl(nativePanel.panelType()); newPanel.setPosition(nativePanel.position()); final JsNativeContextDisplay contextDisplay = nativePanel.contextDisplay(); newPanel.setContextDisplayMode(contextDisplay.mode()); if (contextDisplay.contextId() != null) { newPanel.setContextDefinition(new ContextDefinitionImpl(new DefaultPlaceRequest(contextDisplay.contextId()))); } if (nativePanel.width() > 0) { newPanel.setWidth(nativePanel.width()); } if (nativePanel.minWidth() > 0) { newPanel.setMinWidth(nativePanel.minWidth()); } if (nativePanel.height() > 0) { newPanel.setHeight(nativePanel.height()); } if (nativePanel.minHeight() > 0) { newPanel.setHeight(nativePanel.minHeight()); } nativePanel.view().parts().stream() .map(part -> new JsWorkbenchPartConverter(part).toPartDefinition()) .forEach(newPanel::addPart); nativePanel.view().panels().stream() .map(panel -> new JsWorkbenchPanelConverter(panel).toPanelDefinition()) .forEach(panel -> newPanel.insertChild(panel.getPosition(), panel)); return newPanel; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/JsWorkbenchPartConverter.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativeContextDisplay; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativePart; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PartDefinition; import org.uberfire.workbench.model.impl.ContextDefinitionImpl; import org.uberfire.workbench.model.impl.PartDefinitionImpl; public class JsWorkbenchPartConverter { private final JsNativePart nativePart; public JsWorkbenchPartConverter(final JsNativePart nativePart) { this.nativePart = nativePart; } public PartDefinition toPartDefinition() { final PlaceRequest placeRequest = new DefaultPlaceRequest(nativePart.placeName(), nativePart.parameters()); final PartDefinition partDefinition = new PartDefinitionImpl(placeRequest); final JsNativeContextDisplay contextDisplay = nativePart.contextDisplay(); partDefinition.setContextDisplayMode(contextDisplay.mode()); if (contextDisplay.contextId() != null) { partDefinition.setContextDefinition(new ContextDefinitionImpl(new DefaultPlaceRequest(contextDisplay.contextId()))); } return partDefinition; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/JsWorkbenchPerspectiveActivity.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective; import java.util.function.Consumer; import org.uberfire.client.mvp.AbstractWorkbenchPerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativeContextDisplay; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.ContextDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; public class JsWorkbenchPerspectiveActivity extends AbstractWorkbenchPerspectiveActivity { private JsNativePerspective realPerspective; private final boolean isDefault; public JsWorkbenchPerspectiveActivity(final JsNativePerspective realPerspective, final PlaceManager placeManager, final boolean isDefault) { super(placeManager); this.realPerspective = realPerspective; this.isDefault = isDefault; } // TODO: CDI Event subscriptions? /** * This method is called when this perspective is instantiated * @param place */ @Override public void onStartup(final PlaceRequest place) { super.onStartup(place); this.place = place; this.realPerspective.onStartup(); } @Override public void onOpen() { super.onOpen(); this.realPerspective.onOpen(); placeManager.executeOnOpenCallbacks(place); } @Override public void onClose() { super.onClose(); this.realPerspective.onClose(); placeManager.executeOnCloseCallbacks(place); } @Override public void onShutdown() { super.onShutdown(); this.realPerspective.onShutdown(); } @Override public ResourceType getResourceType() { return ActivityResourceType.PERSPECTIVE; } @Override public String getIdentifier() { return realPerspective.componentId(); } @Override public boolean isDefault() { return this.isDefault; } @Override public boolean isTransient() { return realPerspective.isTransient(); } @Override public void getMenus(final Consumer consumer) { consumer.accept(realPerspective.menus()); } @Override public ToolBar getToolBar() { return realPerspective.toolbar(); } @Override public PerspectiveDefinition getDefaultPerspectiveLayout() { final PerspectiveDefinition def = new PerspectiveDefinitionImpl(realPerspective.defaultPanelType()); def.setName(realPerspective.name()); final JsNativeContextDisplay contextDisplay = this.realPerspective.contextDisplay(); def.setContextDisplayMode(contextDisplay.mode()); if (contextDisplay.contextId() != null) { def.setContextDefinition(new ContextDefinitionImpl(new DefaultPlaceRequest(contextDisplay.contextId()))); } final PanelDefinition rootPanel = def.getRoot(); realPerspective.view().parts().stream() .map(part -> new JsWorkbenchPartConverter(part).toPartDefinition()) .forEach(rootPanel::addPart); realPerspective.view().panels().stream() .map(panel -> new JsWorkbenchPanelConverter(panel).toPanelDefinition()) .forEach(panel -> rootPanel.insertChild(panel.getPosition(), panel)); return def; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/JsWorkbenchTemplatedPerspectiveActivity.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; import elemental2.dom.Attr; import elemental2.dom.DomGlobal; import elemental2.dom.HTMLElement; import elemental2.dom.Node; import jsinterop.base.Js; import org.uberfire.client.mvp.AbstractWorkbenchPerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.TemplatedActivity; import org.uberfire.client.workbench.panels.impl.TemplatedWorkbenchPanelPresenter; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.NamedPosition; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PanelDefinitionImpl; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; import static java.util.stream.Collectors.toMap; import static org.uberfire.workbench.model.PanelDefinition.PARENT_CHOOSES_TYPE; public class JsWorkbenchTemplatedPerspectiveActivity extends AbstractWorkbenchPerspectiveActivity implements TemplatedActivity { private static final String UF_PERSPECTIVE_COMPONENT = "uf-perspective-component"; private static final String UF_PERSPECTIVE_CONTAINER = "uf-perspective-container"; private static final String STARTUP_PARAM_ATTR = "data-startup-"; private final String componentId; private final boolean isDefault; private final HTMLElement container; private final JsNativePerspective realPerspective; private Map componentContainersById; public JsWorkbenchTemplatedPerspectiveActivity(final String componentId, final boolean isDefault, final JsNativePerspective realPerspective, final PlaceManager placeManager) { super(placeManager); this.componentId = componentId; this.isDefault = isDefault; this.realPerspective = realPerspective; this.container = (HTMLElement) DomGlobal.document.createElement("div"); this.container.classList.add(UF_PERSPECTIVE_CONTAINER); this.componentContainersById = new HashMap<>(); } // Lifecycle @Override public void onStartup(final PlaceRequest place) { this.place = place; super.onStartup(place); realPerspective.onStartup(); } @Override public void onOpen() { super.onOpen(); // update local references to the DOM elements realPerspective.renderNative(container); componentContainersById = loadTemplateComponents(container); realPerspective.onOpen(); placeManager.executeOnOpenCallbacks(place); } @Override public void onClose() { super.onClose(); realPerspective.onClose(container); placeManager.executeOnCloseCallbacks(place); } @Override public void onShutdown() { super.onShutdown(); this.realPerspective.onShutdown(); } // Properties @Override public ResourceType getResourceType() { return ActivityResourceType.PERSPECTIVE; } @Override public String getIdentifier() { return componentId; } @Override public boolean isDefault() { return isDefault; } @Override public boolean isTransient() { return realPerspective.isTransient(); } @Override public void getMenus(final Consumer consumer) { consumer.accept(realPerspective.menus()); } @Override public ToolBar getToolBar() { return realPerspective.toolbar(); } @Override public PerspectiveDefinition getDefaultPerspectiveLayout() { final PerspectiveDefinition perspectiveDefinition = new PerspectiveDefinitionImpl(TemplatedWorkbenchPanelPresenter.class.getName()); perspectiveDefinition.setName(realPerspective.name()); componentContainersById.forEach((key, value) -> { final Map placeParams = retrieveStartUpParams(value); final PanelDefinition panelDefinition = new PanelDefinitionImpl(PARENT_CHOOSES_TYPE); panelDefinition.addPart(new PartDefinitionImpl(new DefaultPlaceRequest(key, placeParams))); perspectiveDefinition.getRoot().appendChild(new NamedPosition(key), panelDefinition); }); return perspectiveDefinition; } // Templated interface methods @Override public org.jboss.errai.common.client.dom.HTMLElement resolvePosition(final NamedPosition namedPosition) { final String fieldName = namedPosition.getName(); final HTMLElement element = componentContainersById.get(fieldName); return element == null ? null : Js.cast(element); } @Override public org.jboss.errai.common.client.dom.HTMLElement getRootElement() { return Js.cast(container); } private Map loadTemplateComponents(final HTMLElement container) { final Map templateComponents = realPerspective.getContainerComponents(container) .stream() .collect(toMap(e -> e.getAttribute("af-js-component"), e -> e)); templateComponents.values().forEach(component -> this.recursivelyMarkComponentContainers(container, component)); return templateComponents; } private void recursivelyMarkComponentContainers(final Node root, final Node leaf) { // Run through every node between the root container and the component node marking it as an uf-perspective-component. // This is needed to make the TemplatedPresenter display the correct elements in the screen when it opens. if (!(leaf instanceof HTMLElement)) { return; } if (leaf == root) { return; } final HTMLElement htmlElement = (HTMLElement) leaf; if (!htmlElement.classList.contains(UF_PERSPECTIVE_COMPONENT)) { htmlElement.classList.add(UF_PERSPECTIVE_COMPONENT); } recursivelyMarkComponentContainers(root, leaf.parentNode); } private Map retrieveStartUpParams(final HTMLElement component) { final Map params = new HashMap<>(); for (int i = 0; i < component.attributes.length; i++) { final Attr attr = component.attributes.getAt(i); if (!attr.name.startsWith(STARTUP_PARAM_ATTR)) { continue; } final String key = attr.name.replaceFirst(STARTUP_PARAM_ATTR, ""); if (key.length() > 0) { params.put(key, attr.value); } } return params; } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/jsnative/JsNativeContextDisplay.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective.jsnative; import com.google.gwt.core.client.JavaScriptObject; import org.uberfire.workbench.model.ContextDisplayMode; public class JsNativeContextDisplay { private final JavaScriptObject self; private final String displayInfoFieldName; public JsNativeContextDisplay(final JavaScriptObject self, final String displayInfoFieldName) { this.self = self; this.displayInfoFieldName = displayInfoFieldName; } public ContextDisplayMode mode() { return ContextDisplayMode.valueOf(contextDisplayModeString(displayInfoFieldName)); } public String contextId() { return contextId(displayInfoFieldName); } private native String contextId(final String displayInfoField) /*-{ var contextDisplay = this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativeContextDisplay::self[displayInfoField]; return contextDisplay && contextDisplay["contextId"]; }-*/; private native String contextDisplayModeString(final String displayInfoField) /*-{ var contextDisplay = this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativeContextDisplay::self[displayInfoField]; return contextDisplay && contextDisplay["contextDisplayMode"]; }-*/; } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/jsnative/JsNativePanel.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective.jsnative; import com.google.gwt.core.client.JavaScriptObject; import org.uberfire.workbench.model.CompassPosition; import org.uberfire.workbench.model.Position; public class JsNativePanel { private final JavaScriptObject self; private final JsNativeContextDisplay contextDisplay; private final JsNativeView view; public JsNativePanel(final JavaScriptObject self) { this.self = self; this.contextDisplay = new JsNativeContextDisplay(self, "displayInfo"); this.view = new JsNativeView(self, "parts", "children"); } public String panelType() { return (String) get("panelType"); } public Position position() { return CompassPosition.valueOf((String) get("position")); } public int width() { return ((Number) get("width")).intValue(); } public int minWidth() { return ((Number) get("minWidth")).intValue(); } public int height() { return ((Number) get("height")).intValue(); } public int minHeight() { return ((Number) get("minHeight")).intValue(); } public JsNativeView view() { return this.view; } public JsNativeContextDisplay contextDisplay() { return contextDisplay; } private native Object get(final String fieldToInvoke) /*-{ return this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativePanel::self[fieldToInvoke]; }-*/; } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/jsnative/JsNativePart.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective.jsnative; import java.util.HashMap; import java.util.Map; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.json.client.JSONObject; import org.uberfire.commons.data.Pair; import static java.util.stream.Collectors.toMap; public class JsNativePart { private final JavaScriptObject self; private final JsNativeContextDisplay contextDisplay; public JsNativePart(final JavaScriptObject self) { this.self = self; this.contextDisplay = new JsNativeContextDisplay(self, "displayInfo"); } public String placeName() { return (String) get("placeName"); } public Map parameters() { final JavaScriptObject jsParameters = (JavaScriptObject) get("parameters"); if (jsParameters == null) { return new HashMap<>(); } final JSONObject parametersJson = new JSONObject(jsParameters); return parametersJson.keySet().stream() .map(key -> new Pair<>(key, parametersJson.get(key).isString().stringValue())) .collect(toMap(Pair::getK1, Pair::getK2)); } public JsNativeContextDisplay contextDisplay() { return contextDisplay; } private native Object get(final String fieldToInvoke) /*-{ return this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativePart::self[fieldToInvoke]; }-*/; } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/jsnative/JsNativePerspective.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective.jsnative; import java.util.HashSet; import java.util.Set; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import elemental2.dom.HTMLElement; import jsinterop.base.Js; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; public class JsNativePerspective { private final JavaScriptObject self; private final JsNativeContextDisplay contextDisplay; private final JsNativeView view; public JsNativePerspective(final JavaScriptObject self) { this.self = self; this.contextDisplay = new JsNativeContextDisplay(self, "af_displayInfo"); this.view = new JsNativeView(self, "af_parts", "af_panels"); } public String componentId() { return (String) get("af_componentId"); } public String name() { return (String) get("af_name"); } public boolean isDefault() { return (boolean) get("af_isDefault"); } public boolean isTransient() { return (boolean) get("af_isTransient"); } public boolean isTemplated() { return (boolean) get("af_isTemplated"); } public Menus menus() { return (Menus) get("af_menus"); } public ToolBar toolbar() { return (ToolBar) get("af_toolbar"); } public String defaultPanelType() { return (String) get("af_defaultPanelType"); } public JsNativeView view() { return this.view; } public JsNativeContextDisplay contextDisplay() { return this.contextDisplay; } public void onStartup() { run("af_onStartup"); } public void onOpen() { run("af_onOpen"); } public Set getContainerComponents(final HTMLElement container) { final JsArray jsComponents = nativeGetAfComponents(container); final Set components = new HashSet<>(); for (int i = 0; i < jsComponents.length(); i++) { components.add(Js.cast(jsComponents.get(i))); } return components; } public void onClose() { run("af_onClose"); } public void onClose(final HTMLElement container) { onClose(); unmount(container); } public void onShutdown() { run("af_onShutdown"); } private native void unmount(final HTMLElement container) /*-{ if (this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective::self.af_isReact) { $wnd.ReactDOM.unmountComponentAtNode(container); } }-*/; private native JsArray nativeGetAfComponents(final HTMLElement container) /*-{ return $wnd._AppFormerUtils.findChildContainers(container); }-*/; public native void renderNative(final HTMLElement container) /*-{ $wnd.AppFormer.render( this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective::self.af_componentRoot(), container); }-*/; private native Object get(final String fieldToInvoke) /*-{ return this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective::self[fieldToInvoke]; }-*/; private native Object run(final String method) /*-{ return this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective::self[method](); }-*/; } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/perspective/jsnative/JsNativeView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.perspective.jsnative; import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; public class JsNativeView { private final JavaScriptObject self; private final String partsFieldName; private final String panelsFieldName; public JsNativeView(final JavaScriptObject self, final String partsFieldName, final String panelsFieldName) { this.self = self; this.partsFieldName = partsFieldName; this.panelsFieldName = panelsFieldName; } public List parts() { final List parts = new ArrayList<>(); final JsArray jsParts = nativeParts(partsFieldName); for (int i = 0; i < jsParts.length(); i++) { parts.add(new JsNativePart(jsParts.get(i))); } return parts; } public List panels() { final List panels = new ArrayList<>(); final JsArray jsPanels = nativePanels(panelsFieldName); for (int i = 0; i < jsPanels.length(); i++) { panels.add(new JsNativePanel(jsPanels.get(i))); } return panels; } private native JsArray nativeParts(final String partsField) /*-{ return this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativeView::self[partsField]; }-*/; private native JsArray nativePanels(final String panelsField) /*-{ return this.@org.uberfire.jsbridge.client.perspective.jsnative.JsNativeView::self[panelsField]; }-*/; } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/screen/InvocationPostponer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.screen; import java.util.Stack; class InvocationPostponer { private final Stack invocations; InvocationPostponer() { invocations = new Stack<>(); } void postpone(final Runnable invocation) { invocations.push(invocation); } void executeAll() { while (!invocations.isEmpty()) { invocations.pop().run(); } } void clear() { this.invocations.clear(); } } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/screen/JsNativeScreen.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.screen; import java.util.function.Consumer; import com.google.gwt.core.client.JavaScriptObject; import elemental2.dom.DomGlobal; import elemental2.dom.HTMLElement; import jsinterop.base.Js; import org.jboss.errai.common.client.dom.elemental2.Elemental2DomUtil; import org.uberfire.jsbridge.client.JsPlaceRequest; import org.uberfire.jsbridge.client.loading.LazyLoadingScreen; public class JsNativeScreen { private JavaScriptObject self; private final String componentId; private final HTMLElement container; private final Consumer lazyLoadParentScript; private boolean loaded; private final Elemental2DomUtil elemental2DomUtil; public JsNativeScreen(final String componentId, final Consumer lazyLoadParentScript, final LazyLoadingScreen lazyScreen) { this.loaded = false; this.componentId = componentId; this.elemental2DomUtil = new Elemental2DomUtil(); this.container = createContainerForLoadingScreen(lazyScreen.getElement()); this.lazyLoadParentScript = lazyLoadParentScript; } public void updateRealContent(final JavaScriptObject jsObject) { loaded = true; self = jsObject; // reset container content's, removing the loading content elemental2DomUtil.removeAllElementChildren(container); } public HTMLElement getElement() { //This is just a placeholder. This empty div will passed to the JS component so it knows where to render at. return container; } public void render() { if (screenLoaded()) { renderNative(); } else { lazyLoadParentScript.accept(componentId); } } public boolean screenLoaded() { return loaded; } private HTMLElement createContainerForLoadingScreen(final HTMLElement loadingWidget) { final HTMLElement container = (HTMLElement) DomGlobal.document.createElement("div"); container.classList.add("js-screen-container"); // while loading, this screen will render the loadingWidget's content container.appendChild(loadingWidget); return container; } // Properties public String componentTitle() { final String title = (String) get("af_componentTitle"); return title != null ? title : getComponentId(); } public String componentContextId() { return (String) get("af_componentContextId"); } public elemental2.core.JsMap subscriptions() { return Js.cast(get("af_subscriptions")); } public String getComponentId() { return componentId; } // Lifecycle public void onStartup(final JsPlaceRequest placeRequest) { run("af_onStartup", placeRequest); } public void onOpen() { run("af_onOpen"); } public void onClose() { run("af_onClose"); unmount(); } public boolean onMayClose() { return !defines("af_onMayClose") || (boolean) run("af_onMayClose"); } public void onShutdown() { run("af_onShutdown"); } public void onFocus() { run("af_onFocus"); } public void onLostFocus() { run("af_onLostFocus"); } private Object get(final String property) { if (!screenLoaded()) { return null; } return getNative(property); } private Object run(final String functionName) { if (!screenLoaded()) { return null; } return runNative(functionName); } private Object run(final String functionName, final Object arg1) { if (!screenLoaded()) { return null; } return runNative(functionName, arg1); } public boolean defines(final String property) { if (!screenLoaded()) { return false; } return definesNative(property); } private native Object getNative(final String property) /*-{ return this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self[property]; }-*/; private native Object runNative(final String functionName) /*-{ return this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self[functionName] && this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self[functionName](); }-*/; private native Object runNative(final String functionName, final Object arg1) /*-{ return this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self[functionName] && this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self[functionName](arg1); }-*/; private native boolean definesNative(final String property) /*-{ return this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self[property] !== undefined; }-*/; public native void renderNative() /*-{ $wnd.AppFormer.render( this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self.af_componentRoot(), this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::container); }-*/; private native void unmount() /*-{ if (this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::self.af_isReact) { $wnd.ReactDOM.unmountComponentAtNode(this.@org.uberfire.jsbridge.client.screen.JsNativeScreen::container); } }-*/; } ================================================ FILE: appformer-js-bridge/src/main/java/org/uberfire/jsbridge/client/screen/JsWorkbenchScreenActivity.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.screen; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.user.client.ui.IsWidget; import org.jboss.errai.bus.client.ErraiBus; import org.jboss.errai.bus.client.api.Subscription; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.jboss.errai.enterprise.client.cdi.AbstractCDIEventCallback; import org.jboss.errai.enterprise.client.cdi.api.CDI; import org.jboss.errai.marshalling.client.Marshalling; import org.uberfire.client.mvp.AbstractWorkbenchScreenActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.jsbridge.JsWorkbenchLazyActivity; import org.uberfire.jsbridge.client.JsPlaceRequest; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.model.CompassPosition; import org.uberfire.workbench.model.Position; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; public class JsWorkbenchScreenActivity extends AbstractWorkbenchScreenActivity implements JsWorkbenchLazyActivity { private InvocationPostponer invocationsPostponer; private PlaceRequest place; private JsNativeScreen screen; List subscriptions; public JsWorkbenchScreenActivity(final JsNativeScreen screen, final PlaceManager placeManager) { super(placeManager); this.screen = screen; this.subscriptions = new ArrayList<>(); this.invocationsPostponer = new InvocationPostponer(); } @Override public void updateRealContent(final JavaScriptObject jsObject) { this.screen.updateRealContent(jsObject); this.invocationsPostponer.executeAll(); } // Lifecycle @Override public void onStartup(final PlaceRequest place) { this.place = place; if (!isScreenLoaded()) { invocationsPostponer.postpone(() -> this.onStartup(place)); return; } this.registerSubscriptions(); screen.onStartup(JsPlaceRequest.fromPlaceRequest(place)); } public boolean isScreenLoaded() { return screen.screenLoaded(); } @Override public void onOpen() { // render no matter if the script was loaded or not, even if the call results in a blank screen being rendered. screen.render(); if (!isScreenLoaded()) { invocationsPostponer.postpone(this::onOpen); return; } screen.onOpen(); placeManager.executeOnOpenCallbacks(place); } @Override public void onClose() { if (isScreenLoaded()) { screen.onClose(); } placeManager.executeOnCloseCallbacks(place); } @Override public boolean onMayClose() { if (isScreenLoaded()) { return screen.onMayClose(); } return true; } @Override public void onShutdown() { this.invocationsPostponer.clear(); if (isScreenLoaded()) { this.unsubscribeFromAllEvents(); screen.onShutdown(); } } @Override public void onFocus() { if (isScreenLoaded()) { screen.onFocus(); } } @Override public void onLostFocus() { if (isScreenLoaded()) { screen.onLostFocus(); } } // Properties @Override public String getTitle() { return screen.componentTitle(); } @Override public Position getDefaultPosition() { return CompassPosition.ROOT; } @Override public PlaceRequest getPlace() { return place; } @Override public String getIdentifier() { return screen.getComponentId(); } @Override public IsWidget getTitleDecoration() { return null; } @Override public void getMenus(final Consumer consumer) { consumer.accept(null); } @Override public ToolBar getToolBar() { return null; } @Override public PlaceRequest getOwningPlace() { return null; } @Override public IsWidget getWidget() { return ElementWrapperWidget.getWidget(screen.getElement()); } @Override public String contextId() { return screen.componentContextId(); } @Override public int preferredHeight() { return -1; } @Override public int preferredWidth() { return -1; } // CDI Events Subscriptions void registerSubscriptions() { screen.subscriptions().forEach(this::registerSubscription); } //TODO: Parent classes of "eventFqcn" should be subscribed to as well? //FIXME: Marshall/unmarshall is happening twice Void registerSubscription(final Object callback, final String eventFqcn, final Object obj) { subscriptions.add(getSubscription(callback, eventFqcn)); subscribeOnErraiBus(eventFqcn); return null; } void subscribeOnErraiBus(final String eventFqcn) { ErraiBus.get().subscribe("cdi.event:" + eventFqcn, CDI.ROUTING_CALLBACK); } Subscription getSubscription(final Object callback, final String eventFqcn) { return CDI.subscribe(eventFqcn, new AbstractCDIEventCallback() { public void fireEvent(final Object event) { callWithParsedJsonObject(callback, Marshalling.toJSON(event)); } }); } public native void callWithParsedJsonObject(final Object func, final String jsonArg) /*-{ func(JSON.parse(jsonArg)); }-*/; private void unsubscribeFromAllEvents() { this.subscriptions.forEach(Subscription::remove); this.subscriptions = new ArrayList<>(); } } ================================================ FILE: appformer-js-bridge/src/main/resources/org/uberfire/jsbridge/AppFormerJsBridge.gwt.xml ================================================ ================================================ FILE: appformer-js-bridge/src/test/java/org/uberfire/jsbridge/client/loading/AppFormerJsActivityLoaderTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import javax.enterprise.inject.Instance; import com.google.gwt.core.client.JavaScriptObject; import elemental2.promise.Promise; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.client.mvp.Activity; import org.uberfire.client.mvp.ActivityBeansCache; import org.uberfire.client.mvp.ActivityManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.jsbridge.JsWorkbenchLazyActivity; import org.uberfire.jsbridge.client.screen.JsWorkbenchScreenActivity; import org.uberfire.mocks.EventSourceMock; import org.uberfire.promise.SyncPromises; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; 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 static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.internal.verification.VerificationModeFactory.times; import static org.uberfire.jsbridge.client.loading.AppFormerComponentsRegistry.Entry.Type.EDITOR; import static org.uberfire.jsbridge.client.loading.AppFormerComponentsRegistry.Entry.Type.SCREEN; @RunWith(MockitoJUnitRunner.class) public class AppFormerJsActivityLoaderTest { private AppFormerJsActivityLoader appFormerJsActivityLoader; @Mock private AppFormerComponentsRegistry appFormerComponentsRegistry; @Mock private ActivityManager activityManager; @Mock private EventSourceMock activityLazyLoadedEvent; private SyncPromises promises = new SyncPromises(); @Before @SuppressWarnings("unchecked") public void before() { appFormerJsActivityLoader = spy(new AppFormerJsActivityLoader( promises, activityManager, mock(ActivityBeansCache.class), mock(PlaceManager.class), mock(LazyLoadingScreen.class), activityLazyLoadedEvent, mock(Instance.class), appFormerComponentsRegistry)); } @Test public void registerComponentPerspective() { doNothing().when(appFormerJsActivityLoader).registerPerspective(any()); AppFormerComponentsRegistry.Entry entry = getEntry("a-perspective", AppFormerComponentsRegistry.Entry.Type.PERSPECTIVE, "bar.js"); appFormerJsActivityLoader.registerComponent(entry); verify(appFormerJsActivityLoader).registerPerspective(entry); } @Test public void registerComponentScreen() { doNothing().when(appFormerJsActivityLoader).registerScreen(any()); AppFormerComponentsRegistry.Entry entry = getEntry("a-screen", SCREEN, "bar.js"); appFormerJsActivityLoader.registerComponent(entry); verify(appFormerJsActivityLoader).registerScreen(entry); } @Test public void registerComponentEditor() { doNothing().when(appFormerJsActivityLoader).registerEditor(any()); AppFormerComponentsRegistry.Entry entry = getEntry("an-editor", EDITOR, "bar.js"); appFormerJsActivityLoader.registerComponent(entry); verify(appFormerJsActivityLoader).registerEditor(entry); } private AppFormerComponentsRegistry.Entry getEntry(final String componentId, final AppFormerComponentsRegistry.Entry.Type type, final String scriptFileName) { final AppFormerComponentsRegistry.Entry entry = spy(new AppFormerComponentsRegistry.Entry(componentId, mock(JavaScriptObject.class))); doReturn(type).when(entry).getType(); doReturn(scriptFileName).when(entry).getSource(); return entry; } @Test public void init() { doReturn(new String[]{"foo", "bar"}).when(appFormerComponentsRegistry).keys(); doReturn(mock(JavaScriptObject.class)).when(appFormerComponentsRegistry).get(anyString()); doNothing().when(appFormerJsActivityLoader).registerComponent(any()); appFormerJsActivityLoader.init("my-module"); verify(appFormerJsActivityLoader, times(2)).registerComponent(any()); } @Test(expected = IllegalArgumentException.class) public void onComponentLoaded_unregistered() { final JavaScriptObject jsObject = mock(JavaScriptObject.class); doReturn("my-component-id").when(appFormerJsActivityLoader).extractComponentId(jsObject); appFormerJsActivityLoader.onComponentLoaded(jsObject); } @Test public void onComponentLoaded_registeredEditor() { final AppFormerComponentsRegistry.Entry entry = getEntry("my-component-id", EDITOR, "foo.js"); doReturn("my-component-id").when(appFormerJsActivityLoader).extractComponentId(any()); doNothing().when(appFormerJsActivityLoader).registerEditor(any(), eq("my-component-id")); appFormerJsActivityLoader.registerEditor(entry); appFormerJsActivityLoader.onComponentLoaded(entry.getSelf()); verify(appFormerJsActivityLoader).registerEditor(entry.getSelf(), entry.getComponentId()); } @Test public void onComponentLoaded_registeredComponent() { final AppFormerComponentsRegistry.Entry entry = getEntry("my-component-id", SCREEN, "foo.js"); doReturn("my-component-id").when(appFormerJsActivityLoader).extractComponentId(any()); doNothing().when(appFormerJsActivityLoader).registerScreen(entry); doReturn(mock(Activity.class)).when(appFormerJsActivityLoader).updateRealContent(any(), eq("my-component-id")); appFormerJsActivityLoader.registerComponent(entry); appFormerJsActivityLoader.onComponentLoaded(entry.getSelf()); verify(appFormerJsActivityLoader).updateRealContent(entry.getSelf(), entry.getComponentId()); verify(activityLazyLoadedEvent).fire(any()); } @Test(expected = RuntimeException.class) public void loadScriptFor_noScript() { doReturn(Optional.empty()).when(appFormerJsActivityLoader.getScriptFileName("my-component-id")); appFormerJsActivityLoader.loadScriptFor("my-component-id"); } @Test public void loadScriptFor_unloaded() { init(); doReturn(Optional.of("a-script-path.js")).when(appFormerJsActivityLoader).getScriptFileName("my-component-id"); doReturn(promises.resolve()).when(appFormerJsActivityLoader).loadScript("my-module/a-script-path.js"); appFormerJsActivityLoader.loadScriptFor("my-component-id").catch_(e -> { fail("Promise should've been resolved!"); return promises.resolve(); }); } @Test public void loadScriptFor_loaded() { loadScriptFor_unloaded(); verify(appFormerJsActivityLoader).loadScript(any()); //Invoked once on first load appFormerJsActivityLoader.loadScriptFor("my-component-id").catch_(e -> { fail("Promise should've been resolved!"); return promises.resolve(); }); verify(appFormerJsActivityLoader).loadScript(any()); //Still only invoked once } @Test public void updateRealContent() { final JavaScriptObject jsObject = mock(JavaScriptObject.class); final JsWorkbenchScreenActivity activity = mock(JsWorkbenchScreenActivity.class); doReturn(activity).when(activityManager).getActivity(any()); final Activity foo = appFormerJsActivityLoader.updateRealContent(jsObject, "foo"); assertEquals(foo, activity); verify((JsWorkbenchLazyActivity) foo).updateRealContent(jsObject); } @Test public void getScriptFileName_unexistent() { assertEquals(Optional.empty(), appFormerJsActivityLoader.getScriptFileName("my-component")); } @Test public void getScriptFileName_editor() { appFormerJsActivityLoader.registerEditor(getEntry("my-component", EDITOR, "foo.js")); final Optional scriptFileName = appFormerJsActivityLoader.getScriptFileName("my-component"); assertTrue(scriptFileName.isPresent()); assertEquals("foo.js", scriptFileName.get()); } @Test public void getScriptFileName_component() { doNothing().when(appFormerJsActivityLoader).registerScreen(any()); appFormerJsActivityLoader.registerComponent(getEntry("my-component", SCREEN, "foo.js")); final Optional scriptFileName = appFormerJsActivityLoader.getScriptFileName("my-component"); assertTrue(scriptFileName.isPresent()); assertEquals("foo.js", scriptFileName.get()); } @Test public void triggerLoadOfMatchingEditors_nullPath() { assertFalse(appFormerJsActivityLoader.triggerLoadOfMatchingEditors(null, null)); } @Test public void triggerLoadOfMatchingEditors_nullPathURI() { assertFalse(appFormerJsActivityLoader.triggerLoadOfMatchingEditors(new PathFactory.PathImpl("foo.txt", null), null)); } @Test public void triggerLoadOfMatchingEditors_noMatchingEditors() { doReturn(new ArrayList<>()).when(appFormerJsActivityLoader).loadMatchingEditors("default://foo.txt"); assertFalse(appFormerJsActivityLoader.triggerLoadOfMatchingEditors(new PathFactory.PathImpl("foo.txt", "default://foo.txt"), null)); } @Test public void triggerLoadOfMatchingEditors_moreThanZeroMatchingEditors() { final List> loadingEditors = singletonList(promises.resolve()); doReturn(loadingEditors).when(appFormerJsActivityLoader).loadMatchingEditors("default://foo.txt"); doNothing().when(appFormerJsActivityLoader).finishLoadingMatchingEditors(any(), any()); assertTrue(appFormerJsActivityLoader.triggerLoadOfMatchingEditors(new PathFactory.PathImpl("foo.txt", "default://foo.txt"), null)); verify(appFormerJsActivityLoader).finishLoadingMatchingEditors(loadingEditors, null); } @Test public void finishLoadingMatchingEditors_success() { final List> ps = asList(promises.resolve(), promises.resolve()); final AtomicBoolean pass = new AtomicBoolean(false); appFormerJsActivityLoader.finishLoadingMatchingEditors(ps, () -> pass.set(true)); assertTrue(pass.get()); } @Test public void finishLoadingMatchingEditors_failure() { final List> ps = asList(promises.resolve(), promises.reject(null)); appFormerJsActivityLoader.finishLoadingMatchingEditors(ps, Assert::fail); } @Test public void loadMatchingEditors_matches() { AppFormerComponentsRegistry.Entry entry1 = getEntry("my-editor", EDITOR, "foo.js"); doReturn(true).when(entry1).matches("my-asset.txt"); appFormerJsActivityLoader.registerEditor(entry1); AppFormerComponentsRegistry.Entry entry2 = getEntry("my-other-editor", EDITOR, "foo.js"); doReturn(true).when(entry2).matches("my-asset.txt"); appFormerJsActivityLoader.registerEditor(entry2); final Promise p1 = promises.resolve(); doReturn(p1).when(appFormerJsActivityLoader).loadScriptFor("my-editor"); final Promise p2 = promises.resolve(); doReturn(p2).when(appFormerJsActivityLoader).loadScriptFor("my-other-editor"); final List> promises = appFormerJsActivityLoader.loadMatchingEditors("my-asset.txt"); assertEquals(2, promises.size()); assertSame(p1, promises.get(0)); assertSame(p2, promises.get(1)); } @Test public void loadMatchingEditors_doesntMatch() { AppFormerComponentsRegistry.Entry entry1 = getEntry("my-editor", EDITOR, "foo.js"); doReturn(false).when(entry1).matches("my-asset.txt"); appFormerJsActivityLoader.registerEditor(entry1); AppFormerComponentsRegistry.Entry entry2 = getEntry("my-other-editor", EDITOR, "foo.js"); doReturn(true).when(entry2).matches("my-asset.txt"); appFormerJsActivityLoader.registerEditor(entry2); final Promise p2 = promises.resolve(); doReturn(p2).when(appFormerJsActivityLoader).loadScriptFor("my-other-editor"); final List> promises = appFormerJsActivityLoader.loadMatchingEditors("my-asset.txt"); assertEquals(1, promises.size()); assertSame(p2, promises.get(0)); } } ================================================ FILE: appformer-js-bridge/src/test/java/org/uberfire/jsbridge/client/loading/AppFormerJsLifecycleIT.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import com.google.gwt.core.client.JavaScriptObject; import elemental2.dom.DOMTokenList; import elemental2.dom.DomGlobal; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLDocument; import org.jboss.errai.enterprise.client.cdi.api.CDI; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.jboss.errai.marshalling.client.Marshalling; import org.jboss.errai.ui.client.local.spi.TranslationService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.uberfire.backend.vfs.Path; import org.uberfire.client.mvp.Activity; import org.uberfire.client.mvp.ActivityBeansCache; import org.uberfire.client.mvp.ActivityManager; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.WorkbenchScreenActivity; import org.uberfire.client.mvp.jsbridge.JsWorkbenchLazyActivity; import org.uberfire.client.workbench.Workbench; import org.uberfire.jsbridge.client.AppFormerJsBridge; import org.uberfire.jsbridge.client.cdi.SingletonBeanDefinition; import org.uberfire.jsbridge.client.screen.JsWorkbenchScreenActivity; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.PlaceRequest; import org.uberfire.promise.SyncPromises; import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.internal.verification.VerificationModeFactory.times; import static org.uberfire.jsbridge.client.loading.AppFormerComponentsRegistry.Entry.Type.EDITOR; import static org.uberfire.jsbridge.client.loading.AppFormerComponentsRegistry.Entry.Type.PERSPECTIVE; import static org.uberfire.jsbridge.client.loading.AppFormerComponentsRegistry.Entry.Type.SCREEN; @RunWith(PowerMockRunner.class) @PrepareForTest({IOC.class, CDI.class, Marshalling.class}) public class AppFormerJsLifecycleIT { @Mock private ActivityManager activityManager; @Mock private ActivityBeansCache activityBeansCache; @Mock private PlaceManager placeManager; @Mock private TranslationService translationService; @Mock private LazyLoadingScreen lazyLoadingScreen; @Mock private EventSourceMock eventSourceMock; @Mock private Workbench workbench; private SyncPromises promises = new SyncPromises(); private AppFormerComponentsRegistry registry = spy(new AppFormerComponentsRegistry()); private AppFormerJsActivityLoader appFormerJsActivityLoader; private AppFormerJsBridge appFormerJsBridge; @Before public void before() { appFormerJsActivityLoader = spy(new AppFormerJsActivityLoader( promises, activityManager, activityBeansCache, placeManager, lazyLoadingScreen, eventSourceMock, null, registry)); appFormerJsBridge = spy(new AppFormerJsBridge(workbench, appFormerJsActivityLoader, promises)); } @Test public void testGoTo() { doNothing().when(placeManager).goTo((PlaceRequest) any()); final SyncBeanManager beanManager = ensureSetupBeanManager(); ensureBeanManagerHas(beanManager, PlaceManager.class, placeManager); appFormerJsBridge.goTo("SomePlace"); verify(placeManager).goTo((PlaceRequest) any()); } @Test public void testGoToPath() { doNothing().when(placeManager).goTo((Path) any()); final SyncBeanManager beanManager = ensureSetupBeanManager(); ensureBeanManagerHas(beanManager, PlaceManager.class, placeManager); appFormerJsBridge.goToPath("SomeUri"); verify(placeManager).goTo((Path) any()); } @Test public void testFireEvent() { PowerMockito.mockStatic(CDI.class); PowerMockito.doNothing().when(CDI.class); CDI.fireEvent(any()); PowerMockito.mockStatic(Marshalling.class); PowerMockito.when(Marshalling.fromJSON((String) any())).thenReturn("MarshalledEvent"); appFormerJsBridge.fireEvent("{\"foo\": \"bar\"}"); PowerMockito.verifyStatic(Marshalling.class); Marshalling.fromJSON("{\"foo\": \"bar\"}"); PowerMockito.verifyStatic(CDI.class); CDI.fireEvent("MarshalledEvent"); } @Test public void testTranslate() { doReturn("translated!").when(translationService).format("key"); final SyncBeanManager beanManager = ensureSetupBeanManager(); ensureBeanManagerHas(beanManager, TranslationService.class, translationService); final String translated = appFormerJsBridge.translate("key", new String[]{}); assertEquals("translated!", translated); verify(translationService).format("key"); } @Test public void testInitWithErrorWhileLoadingScripts() { ensureBridgeWillBeExposed(); ensureScriptWontLoadForModule("ModuleWithError"); appFormerJsBridge.init("ModuleWithError"); verify(workbench).addStartupBlocker(AppFormerJsBridge.class); verify(appFormerJsActivityLoader, never()).init(anyString()); verify(workbench).removeStartupBlocker(AppFormerJsBridge.class); } @Test @SuppressWarnings("unchecked") public void testScreenLifecycle() { final ArgumentCaptor captor = ArgumentCaptor.forClass(SingletonBeanDefinition.class); //Init ensureComponentIsInAppFormerComponentsRegistry("foo-screen", SCREEN); ensureDomGlobalCanCreateDivs(); ensureScriptsWillLoadForModule("ScreenTestModule"); ensureBridgeWillBeExposed(); final SyncBeanManager beanManager = ensureSetupBeanManager(); appFormerJsBridge.init("ScreenTestModule"); verify(workbench).addStartupBlocker(AppFormerJsBridge.class); verify(appFormerJsActivityLoader).init("ScreenTestModule"); verify(appFormerJsActivityLoader).registerScreen(any()); verify(activityBeansCache).addNewScreenActivity(any()); verify(beanManager).registerBean(captor.capture()); verify(beanManager).registerBeanTypeAlias(any(), eq(WorkbenchScreenActivity.class)); verify(beanManager).registerBeanTypeAlias(any(), eq(JsWorkbenchLazyActivity.class)); verify(beanManager).registerBeanTypeAlias(any(), eq(Activity.class)); verify(workbench).removeStartupBlocker(AppFormerJsBridge.class); //Register Screen final JsWorkbenchScreenActivity activity = (JsWorkbenchScreenActivity) spy(captor.getValue().getInstance()); final JavaScriptObject screenJsObject = ensureActivityRepresentsRegisteredComponent(activity, "foo-screen"); ensureBeanManagerHas(beanManager, AppFormerJsActivityLoader.class, appFormerJsActivityLoader); appFormerJsBridge.registerScreen(screenJsObject); verify(appFormerJsActivityLoader).onComponentLoaded(screenJsObject); verify(activity).updateRealContent(screenJsObject); assertTrue(activity.isScreenLoaded()); } @Test @SuppressWarnings("unchecked") public void testPerspectiveLifecycle() { final ArgumentCaptor captor = ArgumentCaptor.forClass(SingletonBeanDefinition.class); //Init ensureComponentIsInAppFormerComponentsRegistry("foo-perspective", PERSPECTIVE); ensureDomGlobalCanCreateDivs(); ensureScriptsWillLoadForModule("PerspectiveTestModule"); ensureBridgeWillBeExposed(); final SyncBeanManager beanManager = ensureSetupBeanManager(); ensureBeanManagerHas(beanManager, ActivityBeansCache.class, activityBeansCache); ensureBeanManagerHas(beanManager, PlaceManager.class, placeManager); ensureBeanManagerHas(beanManager, ActivityManager.class, activityManager); ensureBeanManagerHasBeansForName(beanManager, "foo-perspective"); appFormerJsBridge.init("PerspectiveTestModule"); verify(workbench).addStartupBlocker(AppFormerJsBridge.class); verify(appFormerJsActivityLoader).init("PerspectiveTestModule"); verify(appFormerJsActivityLoader).registerPerspective(any()); verify(beanManager).registerBean(captor.capture()); verify(beanManager).registerBeanTypeAlias(any(), eq(PerspectiveActivity.class)); verify(beanManager).registerBeanTypeAlias(any(), eq(JsWorkbenchLazyActivity.class)); verify(beanManager).registerBeanTypeAlias(any(), eq(Activity.class)); verify(activityBeansCache).addNewPerspectiveActivity(any()); verify(workbench).removeStartupBlocker(AppFormerJsBridge.class); //Register Perspective final JsWorkbenchLazyPerspectiveActivity activity = (JsWorkbenchLazyPerspectiveActivity) spy(captor.getValue().getInstance()); final JavaScriptObject screenJsObject = ensureActivityRepresentsRegisteredComponent(activity, "foo-perspective"); ensureBeanManagerHas(beanManager, AppFormerJsActivityLoader.class, appFormerJsActivityLoader); ensurePerspectiveIsNotTemplated(activity); appFormerJsBridge.registerPerspective(screenJsObject); verify(appFormerJsActivityLoader).onComponentLoaded(screenJsObject); verify(activity).updateRealContent(screenJsObject); assertTrue(activity.isPerspectiveLoaded()); } @Test public void registerEditor() { //Init ensureComponentIsInAppFormerComponentsRegistry("foo-editor", EDITOR); ensureDomGlobalCanCreateDivs(); ensureScriptsWillLoadForModule("EditorTestModule"); ensureBridgeWillBeExposed(); appFormerJsBridge.init("EditorTestModule"); verify(workbench).addStartupBlocker(AppFormerJsBridge.class); verify(appFormerJsActivityLoader).init("EditorTestModule"); verify(appFormerJsActivityLoader).registerEditor(any()); assertTrue(appFormerJsActivityLoader.editors.containsKey("foo-editor")); verify(workbench).removeStartupBlocker(AppFormerJsBridge.class); //Registering Editor is still not supported, see https://issues.jboss.org/browse/AF-1882 } private void ensurePerspectiveIsNotTemplated(JsWorkbenchLazyPerspectiveActivity activity) { doReturn(false).when(activity).isPerspectiveTemplated(any()); } private void ensureBeanManagerHasBeansForName(final SyncBeanManager beanManager, final String name) { doReturn(singletonList(mock(SyncBeanDef.class))).when(beanManager).lookupBeans(name); } private void ensureBridgeWillBeExposed() { doNothing().when(appFormerJsBridge).exposeBridgeAsNativeJs(); } private void ensureScriptsWillLoadForModule(final String module) { doReturn(promises.resolve()).when(appFormerJsBridge).loadAppFormerJsAndReactScripts(module); } private void ensureScriptWontLoadForModule(final String module) { doReturn(promises.reject(null)).when(appFormerJsBridge).loadAppFormerJsAndReactScripts(module); } private JavaScriptObject ensureActivityRepresentsRegisteredComponent(final Activity activity, final String id) { final JavaScriptObject screenJsObject = mock(JavaScriptObject.class); doReturn(id).when(appFormerJsActivityLoader).extractComponentId(screenJsObject); doReturn(activity).when(activityManager).getActivity(any()); return screenJsObject; } private void ensureBeanManagerHas(final SyncBeanManager beanManager, final Class clazz, final Object bean) { final SyncBeanDef syncBeanDef = mock(SyncBeanDef.class); doReturn(bean).when(syncBeanDef).getInstance(); doReturn(syncBeanDef).when(beanManager).lookupBean(clazz); } private void ensureDomGlobalCanCreateDivs() { doReturn(nativeScreenContainerDiv()).when(mockDomGlobalDocument()).createElement(any()); } private SyncBeanManager ensureSetupBeanManager() { PowerMockito.mockStatic(IOC.class); SyncBeanManager beanManager = mock(SyncBeanManager.class); PowerMockito.when(IOC.getBeanManager()).thenReturn(beanManager); doNothing().when(beanManager).registerBean(any()); doNothing().when(beanManager).registerBeanTypeAlias(any(), any()); return beanManager; } private void ensureComponentIsInAppFormerComponentsRegistry(final String id, final AppFormerComponentsRegistry.Entry.Type type) { doReturn(new String[]{id}).when(registry).keys(); final AppFormerComponentsRegistry.Entry entry = spy(new AppFormerComponentsRegistry.Entry(id, mock(JavaScriptObject.class))); doReturn(type).when(entry).getType(); doReturn("").when(entry).getSource(); doReturn(new HashMap<>()).when(entry).getParams(); doReturn(entry).when(appFormerJsActivityLoader).newRegistryEntry(eq(id)); } private HTMLDivElement nativeScreenContainerDiv() { final HTMLDivElement div = mock(HTMLDivElement.class); div.classList = mock(DOMTokenList.class); return div; } private HTMLDocument mockDomGlobalDocument() { try { final Field document = DomGlobal.class.getDeclaredField("document"); document.setAccessible(true); final Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(document, document.getModifiers() & ~Modifier.FINAL); final HTMLDocument mock = mock(HTMLDocument.class); document.set(null, mock); return mock; } catch (final Exception e) { throw new RuntimeException(e); } } } ================================================ FILE: appformer-js-bridge/src/test/java/org/uberfire/jsbridge/client/loading/JsWorkbenchLazyPerspectiveActivityTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.loading; import java.util.function.Consumer; import com.google.gwt.core.client.JavaScriptObject; import org.junit.Before; import org.junit.Test; import org.uberfire.client.mvp.ActivityManager; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.jsbridge.client.perspective.JsWorkbenchPerspectiveActivity; import org.uberfire.jsbridge.client.perspective.jsnative.JsNativePerspective; import org.uberfire.mvp.PlaceRequest; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class JsWorkbenchLazyPerspectiveActivityTest { private JsWorkbenchLazyPerspectiveActivity jsWorkbenchLazyPerspectiveActivity; private PlaceManager placeManager; private AppFormerComponentsRegistry.Entry entry; private ActivityManager activityManager; private Consumer lazyLoadingParentScript; @Before public void before() { placeManager = mock(PlaceManager.class); entry = mock(AppFormerComponentsRegistry.Entry.class); activityManager = mock(ActivityManager.class); lazyLoadingParentScript = s -> { }; jsWorkbenchLazyPerspectiveActivity = spy(new JsWorkbenchLazyPerspectiveActivity( entry, placeManager, activityManager, lazyLoadingParentScript)); } @Test public void getNotLoaded() { when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(mock(JsWorkbenchPerspectiveActivity.class)); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(false); assertEquals(jsWorkbenchLazyPerspectiveActivity, jsWorkbenchLazyPerspectiveActivity.get()); } @Test public void getLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(true); assertEquals(backedPerspective, jsWorkbenchLazyPerspectiveActivity.get()); } @Test public void onStartupLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(true); final PlaceRequest placeRequest = mock(PlaceRequest.class); jsWorkbenchLazyPerspectiveActivity.onStartup(placeRequest); verify(backedPerspective).onStartup(placeRequest); } @Test public void onStartupNotLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(false); final PlaceRequest placeRequest = mock(PlaceRequest.class); jsWorkbenchLazyPerspectiveActivity.onStartup(placeRequest); verify(backedPerspective, never()).onStartup(placeRequest); } @Test public void onOpenLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(true); jsWorkbenchLazyPerspectiveActivity.onOpen(); verify(backedPerspective).onOpen(); verify(placeManager).executeOnOpenCallbacks(any()); verify(jsWorkbenchLazyPerspectiveActivity, never()).onLoaded(); } @Test public void onOpenNotLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(false); jsWorkbenchLazyPerspectiveActivity.onStartup(mock(PlaceRequest.class)); jsWorkbenchLazyPerspectiveActivity.onOpen(); verify(backedPerspective, never()).onOpen(); verify(placeManager, times(2)).executeOnOpenCallbacks(any()); verify(jsWorkbenchLazyPerspectiveActivity).onLoaded(); } @Test public void onCloseLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(true); jsWorkbenchLazyPerspectiveActivity.onStartup(mock(PlaceRequest.class)); jsWorkbenchLazyPerspectiveActivity.onClose(); verify(backedPerspective).onClose(); verify(placeManager).executeOnCloseCallbacks(any()); } @Test public void onCloseNotLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(false); jsWorkbenchLazyPerspectiveActivity.onStartup(mock(PlaceRequest.class)); jsWorkbenchLazyPerspectiveActivity.onOpen(); jsWorkbenchLazyPerspectiveActivity.onClose(); verify(backedPerspective, never()).onClose(); verify(placeManager, times(2)).executeOnCloseCallbacks(any()); } @Test public void onShutdownLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(true); jsWorkbenchLazyPerspectiveActivity.onStartup(mock(PlaceRequest.class)); jsWorkbenchLazyPerspectiveActivity.onOpen(); jsWorkbenchLazyPerspectiveActivity.onShutdown(); verify(backedPerspective).onShutdown(); } @Test public void onShutdownNotLoaded() { JsWorkbenchPerspectiveActivity backedPerspective = mock(JsWorkbenchPerspectiveActivity.class); when(jsWorkbenchLazyPerspectiveActivity.getBackedPerspective()).thenReturn(backedPerspective); when(jsWorkbenchLazyPerspectiveActivity.isPerspectiveLoaded()).thenReturn(false); jsWorkbenchLazyPerspectiveActivity.onStartup(mock(PlaceRequest.class)); jsWorkbenchLazyPerspectiveActivity.onOpen(); jsWorkbenchLazyPerspectiveActivity.onClose(); jsWorkbenchLazyPerspectiveActivity.onShutdown(); verify(backedPerspective, never()).onShutdown(); } @Test public void updateRealContent() { jsWorkbenchLazyPerspectiveActivity.onStartup(mock(PlaceRequest.class)); jsWorkbenchLazyPerspectiveActivity.onOpen(); final PerspectiveActivity perspectiveActivity = mock(PerspectiveActivity.class); doReturn(perspectiveActivity).when(jsWorkbenchLazyPerspectiveActivity).getBackedPerspective(any()); doReturn(true).when(activityManager).isStarted(any()); jsWorkbenchLazyPerspectiveActivity.updateRealContent(mock(JavaScriptObject.class)); assertEquals(perspectiveActivity, jsWorkbenchLazyPerspectiveActivity.backedPerspective); verify(perspectiveActivity).onStartup(any()); verify(perspectiveActivity).onOpen(); verify(placeManager).goTo((PlaceRequest) any()); } @Test public void updateRealContent_notStarted() { jsWorkbenchLazyPerspectiveActivity.onStartup(mock(PlaceRequest.class)); jsWorkbenchLazyPerspectiveActivity.onOpen(); final PerspectiveActivity perspectiveActivity = mock(PerspectiveActivity.class); doReturn(perspectiveActivity).when(jsWorkbenchLazyPerspectiveActivity).getBackedPerspective(any()); doReturn(false).when(activityManager).isStarted(any()); jsWorkbenchLazyPerspectiveActivity.updateRealContent(mock(JavaScriptObject.class)); assertEquals(perspectiveActivity, jsWorkbenchLazyPerspectiveActivity.backedPerspective); verify(perspectiveActivity, never()).onStartup(any()); verify(perspectiveActivity).onOpen(); verify(placeManager).goTo((PlaceRequest) any()); } @Test public void updateRealContent_notOpen() { final PerspectiveActivity perspectiveActivity = mock(PerspectiveActivity.class); doReturn(perspectiveActivity).when(jsWorkbenchLazyPerspectiveActivity).getBackedPerspective(any()); doReturn(false).when(activityManager).isStarted(any()); jsWorkbenchLazyPerspectiveActivity.updateRealContent(mock(JavaScriptObject.class)); assertEquals(perspectiveActivity, jsWorkbenchLazyPerspectiveActivity.backedPerspective); verify(perspectiveActivity, never()).onStartup(any()); verify(perspectiveActivity, never()).onOpen(); verify(placeManager, never()).goTo((PlaceRequest) any()); } } ================================================ FILE: appformer-js-bridge/src/test/java/org/uberfire/jsbridge/client/screen/JsWorkbenchScreenActivityTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.jsbridge.client.screen; import org.jboss.errai.bus.client.api.Subscription; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.mvp.PlaceManager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class JsWorkbenchScreenActivityTest { private JsWorkbenchScreenActivity jsWorkbenchScreenActivity; @Mock private JsNativeScreen jsNativeScreen; @Before public void before() { jsWorkbenchScreenActivity = spy(new JsWorkbenchScreenActivity(jsNativeScreen, mock(PlaceManager.class))); } @Test public void registerSubscription() { final Object callback = mock(Object.class); final String eventFqcn = "foo"; doReturn(mock(Subscription.class)).when(jsWorkbenchScreenActivity).getSubscription(callback, eventFqcn); doNothing().when(jsWorkbenchScreenActivity).subscribeOnErraiBus(eventFqcn); final Void nullReturn = jsWorkbenchScreenActivity.registerSubscription(callback, eventFqcn, null); assertNull(nullReturn); assertEquals(1, jsWorkbenchScreenActivity.subscriptions.size()); verify(jsWorkbenchScreenActivity).subscribeOnErraiBus(eventFqcn); } } ================================================ FILE: appformer-js-monaco/.gitignore ================================================ node_modules/ dist/ coverage/ target/ ================================================ FILE: appformer-js-monaco/package.json ================================================ { "name": "appformer-js-monaco", "version": "0.0.0", "description": "Single-file build of monaco-editor.", "main": "dist/monaco.min.js", "files": ["dist"], "scripts": { "init": "yarn install --force", "clean": "rimraf dist", "build": "yarn clean && webpack" }, "devDependencies": { "@kiegroup/monaco-editor": "1.0.0", "babel-loader": "7.1.4", "webpack": "4.25.1", "webpack-cli": "3.1.2", "copy-webpack-plugin": "5.1.0" }, "dependencies": {}, "keywords": ["monaco"] } ================================================ FILE: appformer-js-monaco/pom.xml ================================================ 4.0.0 org.uberfire uberfire-parent 7.75.0-SNAPSHOT ../pom.xml jar appformer-js-monaco 7.75.0-SNAPSHOT AppFormer.js :: Monaco Editor AppFormer.js Monaco Editor org.uberfire appformer-js provided com.github.eirslett frontend-maven-plugin ${project.build.directory} install yarn install-node-and-yarn install node and npm initialize install-node-and-npm lock-treatment-tool execution initialize npm exec @kie/lock-treatment-tool@${version.lock-treatment-tool} -- yarn run init yarn run init yarn run build yarn run build maven-resources-plugin 3.1.0 copy-resources prepare-package copy-resources ${project.build.outputDirectory}/META-INF/resources/webjars/${project.artifactId}/${project.version}/ dist/ false . package.json ================================================ FILE: appformer-js-monaco/prettier.config.js ================================================ module.exports = { printWidth: 120 }; ================================================ FILE: appformer-js-monaco/src/index.ts ================================================ ================================================ FILE: appformer-js-monaco/tsconfig.json ================================================ { "exclude": [ "./node_modules" ], "include": [ "./src" ], "compilerOptions": { "outDir": "./", "lib": [ "es6", "dom" ], "target": "es5", "declaration": true, "sourceMap": true, "noImplicitAny": true, "strictNullChecks": true, "experimentalDecorators": true, "jsx": "react" } } ================================================ FILE: appformer-js-monaco/tsconfig.webpack.json ================================================ { "exclude": ["./node_modules", "./src/**/__tests__"], "extends": "./tsconfig.json" } ================================================ FILE: appformer-js-monaco/tslint.json ================================================ { "defaultSeverity": "error", "extends": [ "tslint:recommended", "tslint-react", "tslint-config-prettier" ], "jsRules": {}, "rules": { "jsx-no-multiline-js": false, "ordered-imports": false, "object-literal-sort-keys": false, "no-console": false, "interface-name": [ true, "never-prefix" ], "max-classes-per-file": false, "jsx-no-lambda": false, "member-ordering": [ true, { "order": [ "static-field", "instance-field", "constructor", "instance-method", "static-method" ] } ], "variable-name": [ true, "ban-keywords", "check-format", "allow-snake-case", "allow-pascal-case", "allow-leading-underscore" ], "comment-format": false }, "rulesDirectory": [] } ================================================ FILE: appformer-js-monaco/webpack.config.js ================================================ const CopyPlugin = require("copy-webpack-plugin"); module.exports = { mode: 'production', entry: { index: "./src/index.ts" }, plugins: [ new CopyPlugin([ { from: "node_modules/@kiegroup/monaco-editor/dist/standalone/monaco.min.js", to: "./monaco-editor" } ]) ] } ================================================ FILE: dashbuilder/README.md ================================================ Dashbuilder =========== Dashbuilder is a general purpose dashboard and reporting web app which allows for: * Visual configuration and personalization of dashboards * Support for different types of visualizations using several charting libraries * Full featured editor for the definition of chart visualizations * Definition of interactive report tables * Data extraction from external systems, through different protocols * Support for both analytics and real-time dashboards Licensed under the Apache License, Version 2.0 For further information, please visit the project web site dashbuilder.org Upcoming features ================= * New renderers based on D3 JS, Lienzo GWT & Chart JS * Hierarchical (nested group) displayer types: Tree & Pie * Support for multiple dynamic data series * Rich mobility support * Alerts and SLA configuration * RESTful API Architecture ================= * Not tied to any chart rendering technology. Pluggable renderers. * No tied to any data storage. * Ability to read data from: CSV files, Databases or Java generators. * Decoupled client & server layers. Ability to build pure lightweight client dashboards. * Ability to push & handle data sets on client for better performance. * Based on Uberfire, a framework for building rich workbench styled apps on the web. Change log ========== 0.6.0.Final * New perspective for the authoring of new application pages and configuring the navigation menus. (Content Management Perspective => [https://issues.jboss.org/browse/DASHBUILDE-166](https://issues.jboss.org/browse/DASHBUILDE-166)) 0.4.0.Final * User interface upgraded to Bootstrap3/PatternFly * MonetDB support added to the SQL provider. (the provider has been tested under the MonetDB 11.21.5 release) * MariaDB support added to the SQL provider. (the provider has been tested under the MariaDB 10.1.10 release) * New data set filtering functions "IN" and "NOT IN" * Data Set Core API available as an embeddable java library (further details [here](https://github.com/dgutierr/datasets-sample-project)) 0.3.0.Final * New provider for the definition of data sets stored into SQL databases. The following is the list of tested and supported DBs: - MySQL 5.5 - Postgres 9.2 - H2 1.3.168+ - Oracle 12c and 11gR2 - IBM DB2 9.7 and 10.5 - Sybase ASE 15.7 * New provider for the retrieval of data stored into Elastic Search nodes. The provider has been tested under Elastic Search 1.7.1 release. * New data set editor UI module: - Creation of SQL, Bean, CSV and Elastic Search data set definitions - Data set retrieval testing and preview - Filter, sort and export the data previews * New displayer for showing single value metrics. * Added new displayer subtypes: bar (stacked), pie (3d, donut), line (smooth) * Support for real-time dashboards. Displayer refresh settings. * Displayer editor data set lookup enhancements: - Filter editor for retrieving only a data subset. - Time frame function for the retrieval of time series data in real-time. - Different strategies for grouping time series data. - Ability to add/remove the columns/series to display. 0.2.0.Final * Data set definition files: Support for CSV & Bean generated data sets * Displayer Editor widget for the creation of displayer definitions * Perspective editor integration which allows the creation of dashboards by drag&drop 0.1.1.Final * Notify clients about data set registration/removal events * Assign an HTML identifier to every Displayer instance (useful for testing purposes) 0.1.0.Final Main goal of this very first release is to make it possible the creation of composite dashboards using an straightforward API. Feature set: * Shared API for defining and registering data sets * Shared operation engine for executing filter, group & sort operations over a data set * Client API & widgets for defining Displayer instances * Uberfire wrapper screen for the Displayer widget * Showcase App. providing a built-in displayer gallery plus some dashboard samples * Default renderer based on the Google Visualization library * Additional table renderer based on the Uberfire PagedTable widget * JBoss AS 7 distribution provided Build & run =========== Prerequisites ------------- * Git client * Maven 3.2.5+ * Java 1.6+ First steps ----------- Clone the project git clone git@github.com:dashbuilder/dashbuilder.git Now you can build & run the project in development or production mode. Development mode ---------------- Development mode allows a user to develop with the framework by compiling classes and client assets on runtime, which decreases the development time. There are more implications such as browser compatibilities, language support, etc. It's useful for developing and testing the application. Dashbuilder is currently built using GWT 2.7, so you are forced to use [SuperDevMode](http://www.gwtproject.org/articles/superdevmode.html) to run the application. Super development mode is the new way to work in GWT since version 2.5 (Native support & the default mode in GWT 2.7). It works in most new browsers and it's based on [Source Map](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?hl=en_US&pli=1&pli=1) spec. It's faster and more efficient than the old hosted mode. There are lots of benefits and other important reasons to use it, you can find more information [here](http://www.gwtproject.org/articles/superdevmode.html). Dashbuilder supports and it's configured by default to use SuperDevMode. Using it means running two servers, one for the web application and one for the Code Server that compiles classes for SDM when the compile button is pushed on the web page or in the bookmark. To build the application: cd dashbuilder mvn clean install -DskipTests To run it: cd dashbuilder-webapp mvn gwt:run Login: admin / admin (If you are an IntelliJ fan, we also provide a setup for running the application under this fantastic IDE. Details [here](https://groups.google.com/forum/#!topic/dashbuilder-development/tRa6AAMb8fM)) Production mode --------------- Production mode is used to build & package the application for a production environment. The application is compiled and the javascript assets are build using all permutations (browser support), all languages, etc. In order to build the production mode: cd dashbuilder mvn clean install -DskipTests -Dfull Once build is finished, you'll find the WAR distribution for Wildfly in dashbuilder/dashbuilder-distros/target/. Just deploy the WAR file into your application server! ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-backend 7.75.0-SNAPSHOT dashbuilder-dataset-cdi jar Dashbuilder Dataset Core CDI support org.slf4j slf4j-api provided jakarta.enterprise jakarta.enterprise.cdi-api provided org.apache.commons commons-lang3 commons-collections commons-collections org.jboss.errai errai-config commons-io commons-io org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-dataset-core org.kie.soup kie-soup-dataset-shared org.kie.soup kie-soup-dataset-csv org.kie.soup kie-soup-dataset-sql org.kie.soup kie-soup-dataset-prometheus org.kie.soup kie-soup-dataset-kafka org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-nio2-api org.uberfire uberfire-nio2-model org.uberfire uberfire-backend-api org.uberfire uberfire-backend-server org.uberfire uberfire-api org.uberfire uberfire-io org.kie.soup kie-soup-dataset-api test-jar test org.kie.soup kie-soup-dataset-core test-jar test org.jboss.weld weld-spi test org.jboss.weld.se weld-se-core test org.jboss.arquillian.junit arquillian-junit-container test org.jboss.arquillian.container arquillian-weld-se-embedded-1.1 test org.jboss.shrinkwrap.resolver shrinkwrap-resolver-depchain pom test javax.inject javax.inject javax.enterprise cdi-api org.slf4j slf4j-simple test ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/Bootstrap.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataprovider.BeanDataSetProviderCDI; import org.dashbuilder.dataprovider.DataSetProviderRegistryCDI; import org.dashbuilder.dataprovider.StaticDataSetProviderCDI; import org.dashbuilder.dataset.DataSetDefDeployerCDI; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.DataSetManagerCDI; import org.dashbuilder.scheduler.SchedulerCDI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; /** * Class in charge of bootstrapping the core subsystems using CDI. * *

It boots right before any regular {@link Startup} beans in order to ensure that any reference to a dataset * subsystem has been properly initialized.

*/ @ApplicationScoped @Startup(StartupType.BOOTSTRAP) public class Bootstrap { protected static Logger log = LoggerFactory.getLogger(Bootstrap.class); @Inject protected SchedulerCDI scheduler; @Inject protected StaticDataSetProviderCDI staticDataSetProvider; @Inject protected BeanDataSetProviderCDI beanDataSetProvider; @Inject protected DataSetProviderRegistryCDI providerRegistry; @Inject protected DataSetDefRegistryCDI dataSetDefRegistry; @Inject protected DataSetDefDeployerCDI dataSetDefDeployer; @Inject protected DataSetManagerCDI dataSetManager; @PostConstruct public void init() { // IMPORTANT: DO NOT alter the initialization order in order to not breaking the component inter dependencies DataSetCore dataSetCore = DataSetCore.get(); dataSetCore.setDataSetProviderRegistry(providerRegistry); dataSetCore.setDataSetDefRegistry(dataSetDefRegistry); dataSetCore.setScheduler(scheduler); dataSetCore.setStaticDataSetProvider(staticDataSetProvider); dataSetCore.setBeanDataSetProvider(beanDataSetProvider); dataSetCore.setDataSetDefDeployer(dataSetDefDeployer); dataSetCore.setDataSetManager(dataSetManager); log.info("Core subsystems initialized"); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/config/Config.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.config; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.enterprise.util.Nonbinding; import javax.inject.Qualifier; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) public @interface Config { @Nonbinding String value() default ""; } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/config/ConfigReader.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.config; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.Annotated; import javax.enterprise.inject.spi.InjectionPoint; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Producer class for primitive fields annotated with @Config */ @ApplicationScoped public class ConfigReader { private static Logger log = LoggerFactory.getLogger(ConfigReader.class); private volatile Properties globalProperties; private volatile Map beanPropertyMap; public static final String beansConfigFile ="META-INF/beans.config"; @PostConstruct public void init() { try { globalProperties = new Properties(); beanPropertyMap = new HashMap(); InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(beansConfigFile); if (is != null) globalProperties.load(is); } catch (IOException ex) { throw new RuntimeException(ex); } } public @Produces @Config String readConfig(InjectionPoint p) { // Read from specific bean String beanKey = p.getMember().getDeclaringClass().getName(); Properties beanProperties = beanPropertyMap.get(beanKey); if (beanProperties == null) { beanPropertyMap.put(beanKey, beanProperties = new Properties()); try { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/" + beanKey + ".config"); if (is != null) beanProperties.load(is); } catch (IOException ex) { throw new RuntimeException(ex); } } // Read from the bean config String configKey = p.getMember().getName(); String configValue = beanProperties.getProperty(configKey); if (configValue != null) return configValue; // Read from global - by the fully qualified class name and field name for (Type type : p.getBean().getTypes()) { configKey = ((Class)type).getName() + "." + p.getMember().getName(); configValue = globalProperties.getProperty(configKey); if (configValue != null) return configValue; // Try class name from System.properties configValue = System.getProperty(configKey); if (configValue != null) { log.info(String.format("System property: %s=%s", configKey, configValue)); return configValue; } // Try class simple name from System.properties configKey = ((Class)type).getSimpleName() + "." + p.getMember().getName(); configValue = System.getProperty(configKey); if (configValue != null) { log.info(String.format("System property: %s=%s", configKey, configValue)); return configValue; } } // Read from global - only by the field name configKey = p.getMember().getName(); configValue = globalProperties.getProperty(configKey); if (configValue != null) return configValue; // Return the default value if any. Annotated annotated = p.getAnnotated(); Config config = annotated.getAnnotation(Config.class); if (config != null) return config.value(); return null; } public @Produces @Config byte readPrimitiveByte(InjectionPoint p) { String val= readConfig(p); return Byte.parseByte(val); } public @Produces @Config short readPrimitiveShort(InjectionPoint p) { String val= readConfig(p); return Short.parseShort(val); } public @Produces @Config int readPrimitiveInt(InjectionPoint p) { String val= readConfig(p); return Integer.parseInt(val); } public @Produces @Config long readPrimitiveLong(InjectionPoint p) { String val= readConfig(p); return Long.parseLong(val); } public @Produces @Config boolean readPrimitiveBoolean(InjectionPoint p) { String val= readConfig(p); return Boolean.parseBoolean(val); } public @Produces @Config float readPrimitiveFloat(InjectionPoint p) { String val= readConfig(p); return Float.parseFloat(val); } public @Produces @Config double readPrimitiveDouble(InjectionPoint p) { String val= readConfig(p); return Double.parseDouble(val); } public @Produces @Config String[] readStringArray(InjectionPoint p) { String val = readConfig(p); String[] result = StringUtils.split(val, ","); for (int i = 0; i < result.length; i++) { result[i] = result[i].trim(); } return result; } public @Produces @Config java.util.List readStringList(InjectionPoint p) { String val = readConfig(p); String[] array = StringUtils.split(val, ","); List list = new ArrayList(); for (int i = 0; i < array.length; i++) { list.add(array[i].trim()); } return list; } public @Produces @Config Map readStringMap(InjectionPoint p) { String val = readConfig(p); Map results = new HashMap(); String[] rows = StringUtils.split(val, ","); for (int i = 0; i < rows.length; i++) { String row = rows[i].trim(); final String[] rowSplit = row.split("="); if (rowSplit.length != 2) throw new IllegalArgumentException("Illegal map entry '" + row + "'"); results.put(rowSplit[0].trim(), rowSplit[1].trim()); } return results; } public @Produces @Config Properties readProperties(InjectionPoint p) { String val = readConfig(p); Properties results = new Properties(); String[] rows = StringUtils.split(val, ","); for (int i = 0; i < rows.length; i++) { String row = rows[i].trim(); final String[] rowSplit = row.split("="); if (rowSplit.length != 2) throw new IllegalArgumentException("Illegal property entry '" + row + "'"); results.put(rowSplit[0].trim(), rowSplit[1].trim()); } return results; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/BeanDataSetProviderCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import org.dashbuilder.dataset.DataSetGenerator; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; @ApplicationScoped public class BeanDataSetProviderCDI extends BeanDataSetProvider { protected BeanManager beanManager; protected Map generatorMap = new HashMap<>(); public BeanDataSetProviderCDI() { super(); } @Inject public BeanDataSetProviderCDI(StaticDataSetProviderCDI staticDataSetProvider, BeanManager beanManager) { super(staticDataSetProvider); this.beanManager = beanManager; } @PostConstruct protected void init() { Set> beans = beanManager.getBeans(DataSetGenerator.class); for (Bean bean : beans) { CreationalContext ctx = beanManager.createCreationalContext(bean); DataSetGenerator generator = (DataSetGenerator) beanManager.getReference(bean, DataSetGenerator.class, ctx); generatorMap.put(bean.getBeanClass().getName(), generator); } } public DataSetGenerator lookupGenerator(DataSetDef def) { BeanDataSetDef beanDef = (BeanDataSetDef) def; String beanName = beanDef.getGeneratorClass(); DataSetGenerator generator = generatorMap.get(beanName); if (generator != null ) { return generator; } else { throw new IllegalArgumentException("Data set generator class not found: " + beanName); } } // Listen to changes on the data set definition registry protected void onDataSetStaleEvent(@Observes DataSetStaleEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.BEAN.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.BEAN.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { DataSetDef def = event.getOldDataSetDef(); if (DataSetProviderType.BEAN.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/CSVDataSetProviderCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.dataprovider.csv.CSVDataSetProvider; import org.dashbuilder.dataprovider.csv.CSVFileStorage; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; @ApplicationScoped public class CSVDataSetProviderCDI extends CSVDataSetProvider { public CSVDataSetProviderCDI() { } @Inject public CSVDataSetProviderCDI(StaticDataSetProviderCDI staticDataSetProvider, CSVFileStorage csvStorage) { super(staticDataSetProvider, csvStorage); } // Listen to changes on the data set definition registry protected void onDataSetStaleEvent(@Observes DataSetStaleEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.CSV.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.CSV.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { DataSetDef def = event.getOldDataSetDef(); if (DataSetProviderType.CSV.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/DataSetProviderRegistryCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import java.util.Iterator; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.dashbuilder.DataSetCore; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; @ApplicationScoped public class DataSetProviderRegistryCDI extends DataSetProviderRegistryImpl { @Inject private StaticDataSetProviderCDI staticDataSetProviderCDI; @Inject private BeanDataSetProviderCDI beanDataSetProviderCDI; @Inject private CSVDataSetProviderCDI csvDataSetProviderCDI; @Inject private SQLDataSetProviderCDI sqlDataSetProviderCDI; @Inject private PrometheusDataSetProviderCDI prometheusDataSetProviderCDI; @Inject private KafkaDataSetProviderCDI kafkaDataSetProviderCDI; @Inject private Instance providerSet; protected DataSetDefJSONMarshaller dataSetDefJSONMarshaller = new DataSetDefJSONMarshaller(this); @PostConstruct public void init() { DataSetCore.get().setDataSetDefJSONMarshaller(dataSetDefJSONMarshaller); // Register all the providers available in classpath Iterator it = providerSet.iterator(); while (it.hasNext()) { DataSetProvider provider = it.next(); super.registerDataProvider(provider); } // Register the core providers super.registerDataProvider(staticDataSetProviderCDI); super.registerDataProvider(beanDataSetProviderCDI); super.registerDataProvider(csvDataSetProviderCDI); super.registerDataProvider(sqlDataSetProviderCDI); super.registerDataProvider(prometheusDataSetProviderCDI); super.registerDataProvider(kafkaDataSetProviderCDI); } public StaticDataSetProviderCDI getStaticDataSetProviderCDI() { return staticDataSetProviderCDI; } public BeanDataSetProviderCDI getBeanDataSetProviderCDI() { return beanDataSetProviderCDI; } public CSVDataSetProviderCDI getCsvDataSetProviderCDI() { return csvDataSetProviderCDI; } public SQLDataSetProviderCDI getSqlDataSetProviderCDI() { return sqlDataSetProviderCDI; } public PrometheusDataSetProviderCDI getPrometheusDataSetProviderCDI() { return prometheusDataSetProviderCDI; } public KafkaDataSetProviderCDI getKafkaDataSetProviderCDI() { return kafkaDataSetProviderCDI; } public DataSetDefJSONMarshaller getDataSetDefJSONMarshaller() { return dataSetDefJSONMarshaller; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/KafkaDataSetProviderCDI.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.dataprovider.kafka.KafkaDataSetProvider; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; @ApplicationScoped public class KafkaDataSetProviderCDI extends KafkaDataSetProvider { public KafkaDataSetProviderCDI() { // empty } @Inject public KafkaDataSetProviderCDI(StaticDataSetProviderCDI staticDataSetProvider) { super(staticDataSetProvider); } protected void onDataSetStaleEvent(@Observes DataSetStaleEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.KAFKA.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.KAFKA.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { DataSetDef def = event.getOldDataSetDef(); if (DataSetProviderType.KAFKA.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/PrometheusDataSetProviderCDI.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.dataprovider.prometheus.PrometheusDataSetProvider; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; @ApplicationScoped public class PrometheusDataSetProviderCDI extends PrometheusDataSetProvider { public PrometheusDataSetProviderCDI() { // empty } @Inject public PrometheusDataSetProviderCDI(StaticDataSetProviderCDI staticDataSetProvider) { super(staticDataSetProvider); } protected void onDataSetStaleEvent(@Observes DataSetStaleEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.PROMETHEUS.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.PROMETHEUS.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } protected void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { DataSetDef def = event.getOldDataSetDef(); if (DataSetProviderType.PROMETHEUS.equals(def.getProvider())) { staticDataSetProvider.removeDataSet(def.getUUID()); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/SQLDataSetProviderCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.DataSetCore; import org.dashbuilder.dataprovider.sql.SQLDataSetProvider; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; @ApplicationScoped public class SQLDataSetProviderCDI extends SQLDataSetProvider { public SQLDataSetProviderCDI() { } @Inject public SQLDataSetProviderCDI(StaticDataSetProviderCDI staticDataSetProvider, SQLDataSourceLocatorCDI sqlDataSourceLocator) { super(staticDataSetProvider, DataSetCore.get().getIntervalBuilderLocator(), DataSetCore.get().getIntervalBuilderDynamicDate(), DataSetCore.get().getSharedDataSetOpEngine()); super.setDataSourceLocator(sqlDataSourceLocator); } // Listen to changes on the data set definition registry protected void onDataSetStaleEvent(@Observes DataSetStaleEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.SQL.equals(def.getProvider())) { String uuid = def.getUUID(); staticDataSetProvider.removeDataSet(uuid); } } protected void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { DataSetDef def = event.getDataSetDef(); if (DataSetProviderType.SQL.equals(def.getProvider())) { String uuid = def.getUUID(); _metadataMap.remove(uuid); staticDataSetProvider.removeDataSet(uuid); } } protected void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { DataSetDef def = event.getOldDataSetDef(); if (DataSetProviderType.SQL.equals(def.getProvider())) { String uuid = def.getUUID(); _metadataMap.remove(uuid); staticDataSetProvider.removeDataSet(uuid); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/SQLDataSourceLocatorCDI.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.naming.InitialContext; import javax.sql.DataSource; import org.dashbuilder.dataprovider.sql.JDBCUtils; import org.dashbuilder.dataprovider.sql.SQLDataSourceLocator; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.def.SQLDataSourceDef; @ApplicationScoped public class SQLDataSourceLocatorCDI implements SQLDataSourceLocator { @Override public DataSource lookup(SQLDataSetDef def) throws Exception { InitialContext ctx = new InitialContext(); return (DataSource) ctx.lookup(def.getDataSource()); } @Override public List list() { return JDBCUtils.listDatasourceDefs(); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataprovider/StaticDataSetProviderCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataprovider; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.DataSetCore; @ApplicationScoped public class StaticDataSetProviderCDI extends StaticDataSetProvider { public StaticDataSetProviderCDI() { super(DataSetCore.get().getSharedDataSetOpEngine()); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataset/DataSetDefDeployerCDI.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.dashbuilder.DataSetCore; import org.dashbuilder.config.Config; @ApplicationScoped public class DataSetDefDeployerCDI extends DataSetDefDeployer { @Inject @Config("") String directory; @Inject @Config("3000") int scanIntervalInMillis; @Inject DataSetDefRegistryCDI dataSetDefRegistry; @PostConstruct public void init() { super.setJsonMarshaller(DataSetCore.get().getDataSetDefJSONMarshaller()); super.setDataSetDefRegistry(dataSetDefRegistry); super.setScanIntervalInMillis(scanIntervalInMillis); if (!StringUtils.isBlank(directory)) { deploy(directory); } } @PreDestroy public synchronized void stop() { super.stop(); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataset/DataSetDefRegistryCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.dashbuilder.DataSetCore; import org.dashbuilder.config.Config; import org.dashbuilder.dataprovider.DataSetProviderRegistryCDI; import org.dashbuilder.dataprovider.csv.CSVFileStorage; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; import org.dashbuilder.dataset.uuid.UUIDGenerator; import org.dashbuilder.exception.ExceptionManager; import org.dashbuilder.scheduler.SchedulerCDI; import org.uberfire.backend.server.util.Paths; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.base.options.CommentedOption; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileVisitResult; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.SimpleFileVisitor; import org.uberfire.java.nio.file.StandardDeleteOption; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.uberfire.java.nio.file.Files.walkFileTree; /** * Data set definition registry implementation which stores data sets under GIT *

It's provided as an extension to the default in-memory based registry and it's * also the default CDI implementation available.

*/ @ApplicationScoped public class DataSetDefRegistryCDI extends DataSetDefRegistryImpl implements CSVFileStorage { public static final String DATASET_EXT = ".dset"; public static final String CSV_EXT = ".csv"; protected int maxCsvLength; protected IOService ioService; protected ExceptionManager exceptionManager; protected UUIDGenerator uuidGenerator; protected Event dataSetDefModifiedEvent; protected Event dataSetDefRegisteredEvent; protected Event dataSetDefRemovedEvent; protected Event dataSetStaleEvent; protected FileSystem fileSystem; protected Path root; public DataSetDefRegistryCDI() { super(); } @Inject public DataSetDefRegistryCDI(@Config("10485760" /* 10 Mb */) int maxCsvLength, @Named("ioStrategy") IOService ioService, @Named("datasetsFS") FileSystem fileSystem, DataSetProviderRegistryCDI dataSetProviderRegistry, SchedulerCDI scheduler, ExceptionManager exceptionManager, Event dataSetDefModifiedEvent, Event dataSetDefRegisteredEvent, Event dataSetDefRemovedEvent, Event dataSetStaleEvent) { super(dataSetProviderRegistry, scheduler); this.uuidGenerator = DataSetCore.get().getUuidGenerator(); this.maxCsvLength = maxCsvLength; this.ioService = ioService; this.fileSystem = fileSystem; this.exceptionManager = exceptionManager; this.dataSetDefModifiedEvent = dataSetDefModifiedEvent; this.dataSetDefRegisteredEvent = dataSetDefRegisteredEvent; this.dataSetDefRemovedEvent = dataSetDefRemovedEvent; this.dataSetStaleEvent = dataSetStaleEvent; } @PostConstruct public void init() { initFileSystem(); deleteTempFiles(); registerDataSetDefs(); } public DataSetDefJSONMarshaller getDataSetDefJsonMarshaller() { return DataSetCore.get().getDataSetDefJSONMarshaller(); } @Override protected void onDataSetDefStale(DataSetDef def) { dataSetStaleEvent.fire(new DataSetStaleEvent(def)); } @Override protected void onDataSetDefModified(DataSetDef olDef, DataSetDef newDef) { dataSetDefModifiedEvent.fire(new DataSetDefModifiedEvent(olDef, newDef)); } @Override protected void onDataSetDefRegistered(DataSetDef newDef) { dataSetDefRegisteredEvent.fire(new DataSetDefRegisteredEvent(newDef)); } @Override protected void onDataSetDefRemoved(DataSetDef oldDef) { dataSetDefRemovedEvent.fire(new DataSetDefRemovedEvent(oldDef)); } protected void initFileSystem() { root = fileSystem.getRootDirectories().iterator().next(); } protected void registerDataSetDefs() { for (DataSetDef def : listDataSetDefs()) { super.dataSetDefMap.put(def.getUUID(), new DataSetDefEntry(def)); } } public org.uberfire.backend.vfs.Path resolveVfsPath(DataSetDef def) { return convert(resolveNioPath(def)); } protected Path resolveNioPath(DataSetDef def) { return getDataSetsPath().resolve(def.getUUID() + DATASET_EXT); } @Override public void registerDataSetDef(DataSetDef def, String subjectId, String message) { if (def.getUUID() == null) { final String uuid = uuidGenerator.newUuid(); def.setUUID(uuid); } if (subjectId == null || message == null) { ioService.startBatch(fileSystem); } else { ioService.startBatch(fileSystem, new CommentedOption(subjectId, message)); } try { String defJson = getDataSetDefJsonMarshaller().toJsonString(def); Path defPath = resolveNioPath(def); ioService.write(defPath, defJson); // CSV specific if (def instanceof CSVDataSetDef) { saveCSVFile((CSVDataSetDef) def); } super.registerDataSetDef(def, subjectId, message); } catch (Exception e) { throw exceptionManager.handleException( new Exception("Can't register the data set definition\n" + def, e)); } finally { ioService.endBatch(); } } @Override public DataSetDef removeDataSetDef(String uuid, String subjectId, String message) { DataSetDef def = getDataSetDef(uuid); if (def == null) { return null; } return removeDataSetDef(def, subjectId, message); } public void removeDataSetDef(org.uberfire.backend.vfs.Path path, String subjectId, String comment) { DataSetDef def = loadDataSetDef(path); if (def != null) { removeDataSetDef(def, subjectId, comment); } } public DataSetDef removeDataSetDef(DataSetDef def, String subjectId, String message) { Path defPath = resolveNioPath(def); if (ioService.exists(defPath)) { if (subjectId == null || message == null) { ioService.startBatch(fileSystem); } else { ioService.startBatch(fileSystem, new CommentedOption(subjectId, message)); } try { ioService.deleteIfExists(defPath, StandardDeleteOption.NON_EMPTY_DIRECTORIES); // CSV specific if (def instanceof CSVDataSetDef) { deleteCSVFile((CSVDataSetDef) def); } } finally { ioService.endBatch(); } } return super.removeDataSetDef(def.getUUID(), subjectId, message); } public Collection listDataSetDefs() { final Collection result = new ArrayList<>(); if (ioService.exists(root)) { walkFileTree(checkNotNull("root", root), new SimpleFileVisitor() { @Override public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { try { checkNotNull("file", file); checkNotNull("attrs", attrs); if (file.getFileName().toString().endsWith(DATASET_EXT) && attrs.isRegularFile()) { String json = ioService.readAllString(file); DataSetDef def = getDataSetDefJsonMarshaller().fromJson(json); result.add(def); } } catch (final Exception e) { log.error("Data set definition read error: " + file.getFileName(), e); return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; } }); } return result; } public DataSetDef loadDataSetDef(org.uberfire.backend.vfs.Path path) { Path nioPath = convert(path); if (ioService.exists(nioPath)) { try { String json = ioService.readAllString(nioPath); DataSetDef def = getDataSetDefJsonMarshaller().fromJson(json); return def; } catch (Exception e) { String msg = "Error parsing data set JSON definition: " + path.getFileName(); throw exceptionManager.handleException(new Exception(msg, e)); } } return null; } public DataSetDef copyDataSetDef(DataSetDef def, String newName, String subjectId, String message) { DataSetDef clone = def.clone(); clone.setUUID(uuidGenerator.newUuid()); clone.setName(newName); if (subjectId == null || message == null) { ioService.startBatch(fileSystem); } else { ioService.startBatch(fileSystem, new CommentedOption(subjectId, message)); } try { // CSV specific if (def instanceof CSVDataSetDef) { CSVDataSetDef csvDef = (CSVDataSetDef) def; CSVDataSetDef csvCloneDef = (CSVDataSetDef) clone; Path csvPath = resolveCsvPath(csvDef); Path cloneCsvPath = resolveCsvPath(csvCloneDef); ioService.copy(csvPath, cloneCsvPath); csvCloneDef.setFilePath(convert(cloneCsvPath).toURI()); } String defJson = getDataSetDefJsonMarshaller().toJsonString(clone); Path clonePath = resolveNioPath(clone); ioService.write(clonePath, defJson); super.registerDataSetDef(clone, subjectId, message); return clone; } catch (Exception e) { throw exceptionManager.handleException( new Exception("Can't register the data set definition\n" + def, e)); } finally { ioService.endBatch(); } } public Path createTempFile(String fileName) { Path tempPath = resolveTempPath(fileName); return tempPath; } public void deleteTempFiles() { Path tempPath = getTempPath(); if (ioService.exists(tempPath)) { ioService.startBatch(fileSystem, new CommentedOption("system", "Delete temporal files")); try { walkFileTree(tempPath, new SimpleFileVisitor() { @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } }); } finally { ioService.endBatch(); } } } protected Path getDataSetsPath() { return root.resolve("definitions"); } protected Path getTempPath() { return root.resolve("tmp"); } protected Path resolveTempPath(String fileName) { return getTempPath().resolve(fileName); } protected org.uberfire.backend.vfs.Path convert(Path path) { return Paths.convert(path); } protected Path convert(org.uberfire.backend.vfs.Path path) { return Paths.convert(path); } // // CSV files storage // @Override public String getCSVString(CSVDataSetDef def) { Path nioPath = resolveCsvPath(def); if (ioService.exists(nioPath)) { return ioService.readAllString(nioPath); } return null; } @Override public InputStream getCSVInputStream(CSVDataSetDef def) { Path nioPath = resolveCsvTempPath(def); if (ioService.exists(nioPath)) { // In edition process ... return ioService.newInputStream(nioPath); } nioPath = resolveCsvPath(def); if (ioService.exists(nioPath)) { // Already created & persisted return ioService.newInputStream(nioPath); } return null; } @Override public void deleteCSVFile(CSVDataSetDef def) { Path csvPath = resolveCsvPath(def); if (ioService.exists(csvPath)) { ioService.deleteIfExists(csvPath, StandardDeleteOption.NON_EMPTY_DIRECTORIES); } } @Override public void saveCSVFile(CSVDataSetDef def) { String path = def.getFilePath(); if (StringUtils.isBlank(path)) { return; } // The CSV file was uploaded from UI to the temp directory => move the file to the definitions directory Path csvTempPath = resolveCsvTempPath(def); if (ioService.exists(csvTempPath)) { Path csvPath = resolveCsvPath(def); if (ioService.exists(csvPath)) { // Avoid FileAlreadyExistsException on call to move (see below) ioService.delete(csvPath); } ioService.move(csvTempPath, csvPath); return; } // The CSV was registered or deployed via API => Copy the file contents to the definitions directory File csvFile = new File(path); if (csvFile.exists()) { if (csvFile.length() > maxCsvLength) { String msg = "CSV file length exceeds the maximum allowed: " + maxCsvLength / 1024 + " Kb"; throw exceptionManager.handleException(new Exception(msg)); } try { Path defPath = resolveCsvPath(def); String csvContent = FileUtils.readFileToString(csvFile); ioService.write(defPath, csvContent); } catch (Exception e) { String msg = "Error saving CSV file: " + csvFile; throw exceptionManager.handleException(new Exception(msg, e)); } } } protected Path resolveCsvPath(CSVDataSetDef def) { return getDataSetsPath().resolve(def.getUUID() + CSV_EXT); } protected Path resolveCsvTempPath(CSVDataSetDef def) { return resolveTempPath(def.getUUID() + CSV_EXT); } void onDataSetDefRegisteredEvent(@Observes DataSetDefRegisteredEvent event) { DataSetDef def = event.getDataSetDef(); dataSetDefMap.put( def.getUUID(), new DataSetDefEntry(def)); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/dataset/DataSetManagerCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.DataSetCore; import org.dashbuilder.config.Config; import org.dashbuilder.dataprovider.DataSetProviderRegistryCDI; import org.dashbuilder.dataprovider.StaticDataSetProviderCDI; @ApplicationScoped public class DataSetManagerCDI extends DataSetManagerImpl { public DataSetManagerCDI(){ } @Inject public DataSetManagerCDI(StaticDataSetProviderCDI staticDataSetProvider, DataSetDefRegistryCDI dataSetDefRegistry, DataSetProviderRegistryCDI dataSetProviderRegistry, @Config("true") boolean dataSetPushEnabled, @Config("1024") int dataSetPushMaxSize) { super(dataSetDefRegistry, dataSetProviderRegistry, staticDataSetProvider, dataSetPushEnabled, dataSetPushMaxSize); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/exception/ExceptionManager.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.exception; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.jboss.errai.config.rebind.EnvUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** *

Handles backend exceptions.

* * @since 0.3.0 */ @ApplicationScoped public class ExceptionManager { private static Logger log = LoggerFactory.getLogger(ExceptionManager.class); /** *

Return a @Portable RuntimeException that can be captured by client side widgets.

* * @param e The exception that caused the error. * @return The portable exception to send to the client side. */ public RuntimeException handleException(final Exception e) { log.error(e.getMessage(), e); if (e instanceof RuntimeException && EnvUtil.isPortableType(e.getClass()) ) { return (RuntimeException) e; } return new GenericPortableException( e.getMessage(), e ); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/exception/GenericPortableException.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.exception; import java.io.Serializable; /** *

Root of all portable Exceptions resulting from server-side errors that need to be sent to the client.

* @since 0.3.0 */ public class GenericPortableException extends RuntimeException implements Serializable { public GenericPortableException() { } public GenericPortableException( final String message ) { super( message ); } public GenericPortableException( final String message, Exception e ) { super( message, e ); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/java/org/dashbuilder/scheduler/SchedulerCDI.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.scheduler; import javax.annotation.PreDestroy; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.config.Config; @ApplicationScoped public class SchedulerCDI extends Scheduler { public SchedulerCDI() { } @Inject public SchedulerCDI(@Config("10") int maxThreadPoolSize) { super.init(maxThreadPoolSize); } @PreDestroy public void shutdown() { super.shutdown(); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/BootstrapTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import javax.inject.Inject; import org.dashbuilder.Bootstrap; import org.dashbuilder.DataSetCore; import org.dashbuilder.dataprovider.DataSetProviderRegistry; import org.dashbuilder.dataprovider.DataSetProviderRegistryCDI; import org.dashbuilder.dataset.DataSetDefDeployer; import org.dashbuilder.dataset.DataSetDefDeployerCDI; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.def.DataSetDefRegistry; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; import org.dashbuilder.test.BaseCDITest; import org.jboss.arquillian.junit.Arquillian; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(Arquillian.class) @Ignore("see https://issues.jboss.org/browse/RHPAM-832") public class BootstrapTest extends BaseCDITest { public static final String CSV_JSON = "{\n" + " \"uuid\": \"expenseReports\",\n" + " \"name\": \"Expense Reports\",\n" + " \"provider\": \"CSV\",\n" + "}"; @Inject Bootstrap bootstrap; @Inject DataSetProviderRegistryCDI providerRegistryCDI; @Inject DataSetDefRegistryCDI dataSetDefRegistryCDI; @Inject DataSetDefDeployerCDI dataSetDefDeployerCDI; @Before public void setUp() throws Exception { bootstrap.init(); } @Test public void testStartupAnnotation() throws Exception { Startup startup = Bootstrap.class.getAnnotation(Startup.class); assertNotNull(startup); assertEquals(startup.value(), StartupType.BOOTSTRAP); } @Test public void testProviderRegistryInit() throws Exception { bootstrap.init(); DataSetProviderRegistry dataSetProviderRegistry = DataSetCore.get().getDataSetProviderRegistry(); assertEquals(dataSetProviderRegistry, providerRegistryCDI); assertEquals(dataSetProviderRegistry.getAvailableTypes().size(), 6); DataSetDefJSONMarshaller jsonMarshaller = DataSetCore.get().getDataSetDefJSONMarshaller(); jsonMarshaller.fromJson(CSV_JSON); // No exception } @Test public void testDataSetDefRegistryInit() throws Exception { DataSetProviderRegistry providerRegistry = dataSetDefRegistryCDI.getDataSetProviderRegistry(); DataSetDefJSONMarshaller jsonMarshaller = dataSetDefRegistryCDI.getDataSetDefJsonMarshaller(); assertNotNull(providerRegistry); assertNotNull(jsonMarshaller); assertEquals(jsonMarshaller, providerRegistryCDI.getDataSetDefJSONMarshaller()); } @Test public void testDataSetDeployerInit() throws Exception { DataSetDefDeployer dataSetDefDeployer = DataSetCore.get().getDataSetDefDeployer(); assertNotNull(dataSetDefDeployer); assertEquals(dataSetDefDeployer, dataSetDefDeployerCDI); } @Test public void testNoListenerRegistration() throws Exception { assertEquals(dataSetDefRegistryCDI.getListeners().size(), 0); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/config/ConfigAnnotationTest.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.config; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Named; import org.dashbuilder.test.BaseCDITest; import org.dashbuilder.test.ShrinkWrapHelper; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.dashbuilder.pojo.Bean; import org.dashbuilder.pojo.BeanExt; import static org.assertj.core.api.Assertions.assertThat; @RunWith(Arquillian.class) @Ignore("see https://issues.jboss.org/browse/RHPAM-832") public class ConfigAnnotationTest extends BaseCDITest { @Inject protected Bean bean; @Test public void checkBean() { assertThat(bean.propString1).isEqualTo("From class"); assertThat(bean.propString2).isEqualTo("From beans.config"); assertThat(bean.propString3).isEqualTo("From Bean.config"); assertThat(((BeanExt) bean).propString4).isEqualTo("From class"); assertThat(((BeanExt) bean).propString5).isEqualTo("From beans.config"); assertThat(((BeanExt) bean).propString6).isEqualTo("From BeanExt.config"); assertThat(bean.propMap4.size()).isEqualTo(3); assertThat(bean.propMap4.get("a")).isEqualTo("1"); assertThat(bean.propMap4.get("b")).isEqualTo("2"); assertThat(bean.propMap4.get("c")).isEqualTo("3"); assertThat(bean.props5.size()).isEqualTo(3); assertThat(bean.props5.getProperty("a")).isEqualTo("1"); assertThat(bean.props5.getProperty("b")).isEqualTo("2"); assertThat(bean.props5.getProperty("c")).isEqualTo("3"); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/dataset/DataSetDefRegistryCDITest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import javax.enterprise.event.Event; import org.dashbuilder.dataprovider.DataSetProviderRegistryCDI; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.def.DataSetDefFactory; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; import org.dashbuilder.exception.ExceptionManager; import org.dashbuilder.scheduler.SchedulerCDI; import org.dashbuilder.test.BaseCDITest; import org.jboss.arquillian.junit.Arquillian; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.StandardDeleteOption; import org.uberfire.java.nio.file.FileSystem; import static org.mockito.Mockito.*; @RunWith(Arquillian.class) @Ignore("see https://issues.jboss.org/browse/RHPAM-832") public class DataSetDefRegistryCDITest extends BaseCDITest { @Mock DataSetProviderRegistryCDI dataSetProviderRegistry; @Mock SchedulerCDI scheduler; @Mock ExceptionManager exceptionManager; @Mock Event dataSetDefModifiedEvent; @Mock Event dataSetDefRegisteredEvent; @Mock Event dataSetDefRemovedEvent; @Mock Event dataSetStaleEvent; @Mock(name = "datasetsFS") FileSystem fileSystem; DataSetDefRegistryCDI dataSetDefRegistry; public DataSetDef dataSetDef = DataSetDefFactory .newCSVDataSetDef() .uuid("testDset") .buildDef(); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); dataSetDefRegistry = spy(new DataSetDefRegistryCDI( 10485760, mockIOService(), fileSystem, dataSetProviderRegistry, scheduler, exceptionManager, dataSetDefModifiedEvent, dataSetDefRegisteredEvent, dataSetDefRemovedEvent, dataSetStaleEvent)); dataSetDefRegistry.init(); when(dataSetDefRegistry.convert(any(org.uberfire.java.nio.file.Path.class))) .thenReturn(mock(org.uberfire.backend.vfs.Path.class)); when(dataSetDefRegistry.convert(any(org.uberfire.backend.vfs.Path.class))) .thenReturn(mock(org.uberfire.java.nio.file.Path.class)); } @Test public void testRegistryDataSetDef() throws Exception { dataSetDefRegistry.registerDataSetDef(dataSetDef); verify(getIOService()).write(any(Path.class), anyString()); verify(dataSetDefRegisteredEvent).fire(any(DataSetDefRegisteredEvent.class)); } @Test public void testDeleteDataSetDef() throws Exception { when(ioService.exists(any(Path.class))).thenReturn(true); dataSetDefRegistry.registerDataSetDef(dataSetDef); dataSetDefRegistry.removeDataSetDef(dataSetDef.getUUID()); verify(getIOService(), atLeastOnce()).deleteIfExists(any(Path.class), eq(StandardDeleteOption.NON_EMPTY_DIRECTORIES)); verify(dataSetDefRemovedEvent).fire(any(DataSetDefRemovedEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/dataset/DataSetProviderRegistryCDITest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import java.util.List; import java.util.Set; import javax.inject.Inject; import org.dashbuilder.dataprovider.*; import org.dashbuilder.test.BaseCDITest; import org.jboss.arquillian.junit.Arquillian; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; @RunWith(Arquillian.class) @Ignore("see https://issues.jboss.org/browse/RHPAM-832") public class DataSetProviderRegistryCDITest extends BaseCDITest { @Inject DataSetProviderRegistryCDI dataSetProviderRegistry; @Before public void setUp() { dataSetProviderRegistry.init(); } @Test public void testRegistryDataSetDef() throws Exception { Set typeList = dataSetProviderRegistry.getAvailableTypes(); assertTrue(typeList.contains(DataSetProviderType.STATIC)); assertTrue(typeList.contains(DataSetProviderType.BEAN)); assertTrue(typeList.contains(DataSetProviderType.CSV)); assertTrue(typeList.contains(DataSetProviderType.SQL)); // In CDI contexts, DataSetProvider implementations are automatically registered assertTrue(typeList.contains(CustomDataSetProvider.TYPE)); DataSetProvider customProvider = dataSetProviderRegistry.getDataSetProvider(CustomDataSetProvider.TYPE); assertNotNull(customProvider); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/dataset/DataSetSubsystemCDITest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import org.dashbuilder.Bootstrap; import org.dashbuilder.test.BaseCDITest; import org.jboss.arquillian.junit.Arquillian; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import javax.inject.Inject; @RunWith(Arquillian.class) @Ignore("see https://issues.jboss.org/browse/RHPAM-832") public class DataSetSubsystemCDITest extends BaseCDITest { @Inject Bootstrap bootstrap; DataSetFilterTest dataSetFilterTest; DataSetGroupTest dataSetGroupTest; DataSetNestedGroupTest nestedGroupTest; DataSetSortTest dataSetSortTest; DataSetTrimTest dataSetTrimTest; @Before public void setUp() throws Exception { bootstrap.init(); dataSetFilterTest = new DataSetFilterTest(); dataSetGroupTest = new DataSetGroupTest(); nestedGroupTest = new DataSetNestedGroupTest(); dataSetSortTest = new DataSetSortTest(); dataSetTrimTest = new DataSetTrimTest(); dataSetFilterTest.setUp(); dataSetGroupTest.setUp(); nestedGroupTest.setUp(); dataSetSortTest.setUp(); dataSetTrimTest.setUp(); } @Test public void testFilter() throws Exception { dataSetFilterTest.testColumnTypes(); dataSetFilterTest.testFilterByString(); dataSetFilterTest.testFilterByNumber(); dataSetFilterTest.testFilterByDate(); dataSetFilterTest.testFilterMultiple(); dataSetFilterTest.testANDExpression(); dataSetFilterTest.testNOTExpression(); dataSetFilterTest.testORExpression(); dataSetFilterTest.testORExpressionMultilple(); dataSetFilterTest.testLogicalExprNonEmpty(); dataSetFilterTest.testCombinedExpression(); dataSetFilterTest.testCombinedExpression2(); dataSetFilterTest.testCombinedExpression3(); dataSetFilterTest.testLikeOperatorCaseSensitive(); dataSetFilterTest.testLikeOperatorNonCaseSensitive(); dataSetFilterTest.testFilterByStringWithPreProcessor(); } @Test public void testGroup() throws Exception { dataSetGroupTest.testDataSetFunctions(); dataSetGroupTest.testDateMinMaxFunctions(); dataSetGroupTest.testNumberMinMaxFunctions(); dataSetGroupTest.testGroupByLabelDynamic(); dataSetGroupTest.testGroupByExcludeLabelColumn(); dataSetGroupTest.testGroupByYearDynamic(); dataSetGroupTest.testGroupByMonthDynamic(); dataSetGroupTest.testGroupByMonthDynamicNonEmpty(); dataSetGroupTest.testGroupByDayOfWeekDynamic(); dataSetGroupTest.testGroupByDayOfWeekFixed(); dataSetGroupTest.testGroupByMonthReverse(); dataSetGroupTest.testGroupByFixedTrim(); dataSetGroupTest.testGroupByMonthFixed(); dataSetGroupTest.testGroupByMonthFirstMonth(); dataSetGroupTest.testGroupByMonthFirstMonthReverse(); dataSetGroupTest.testGroupByQuarter(); dataSetGroupTest.testGroupByDateOneRow(); dataSetGroupTest.testGroupByDateOneDay(); dataSetGroupTest.testGroupAndCountSameColumn(); dataSetGroupTest.testGroupNumberAsLabel(); } @Test public void testNestedGroups() throws Exception { nestedGroupTest.testGroupSelectionFilter(); nestedGroupTest.testNestedGroupFromMultipleSelection(); nestedGroupTest.testNestedGroupRequiresSelection(); nestedGroupTest.testNoResultsSelection(); nestedGroupTest.testThreeNestedLevels(); nestedGroupTest.testGroupByQuarter(); } @Test public void testSort() throws Exception { dataSetSortTest.testSortByString(); dataSetSortTest.testSortByNumber(); dataSetSortTest.testSortByDate(); dataSetSortTest.testSortMultiple(); dataSetSortTest.testGroupAndSort(); } @Test public void testTrim() throws Exception { dataSetTrimTest.testTrim(); dataSetTrimTest.testTrimGroup(); dataSetTrimTest.testDuplicatedColumns(); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/dataset/SQLDataSourceLocatorCDITest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import java.util.List; import javax.inject.Inject; import javax.sql.DataSource; import org.dashbuilder.dataprovider.SQLDataSetProviderCDI; import org.dashbuilder.dataprovider.sql.SQLDataSourceLocator; import org.dashbuilder.dataset.def.SQLDataSourceDef; import org.dashbuilder.test.BaseCDITest; import org.jboss.arquillian.junit.Arquillian; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; @RunWith(Arquillian.class) @Ignore("see https://issues.jboss.org/browse/RHPAM-832") public class SQLDataSourceLocatorCDITest extends BaseCDITest { @Inject SQLDataSetProviderCDI sqlDataSetProviderCDI; @Test public void testInit() throws Exception { assertNotNull(sqlDataSetProviderCDI); SQLDataSourceLocator dataSourceLocator = sqlDataSetProviderCDI.getDataSourceLocator(); assertNotNull(dataSourceLocator); assertTrue(dataSourceLocator instanceof SQLDataSourceLocatorMock); } @Test public void testLookup() throws Exception { SQLDataSourceLocator dataSourceLocator = sqlDataSetProviderCDI.getDataSourceLocator(); DataSource dataSource = dataSourceLocator.lookup(null); assertNull(dataSource); } @Test public void testList() throws Exception { SQLDataSourceLocator dataSourceLocator = sqlDataSetProviderCDI.getDataSourceLocator(); List l = dataSourceLocator.list(); assertEquals(l.size(), 2); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/dataset/SQLDataSourceLocatorMock.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset; import java.util.ArrayList; import java.util.List; import javax.enterprise.inject.Specializes; import javax.sql.DataSource; import org.dashbuilder.dataprovider.SQLDataSourceLocatorCDI; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.def.SQLDataSourceDef; @Specializes public class SQLDataSourceLocatorMock extends SQLDataSourceLocatorCDI { public SQLDataSourceLocatorMock() { } @Override public DataSource lookup(SQLDataSetDef def) throws Exception { return null; } @Override public List list() { List result = new ArrayList<>(); result.add(new SQLDataSourceDef("ds1", "ds1")); result.add(new SQLDataSourceDef("ds2", "ds2")); return result; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/pojo/Bean.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.pojo; import java.util.Map; import java.util.Properties; import javax.inject.Inject; import org.dashbuilder.config.Config; public class Bean { @Inject @Config("From class") public String propString1; @Inject @Config("From class") public String propString2; @Inject @Config("From class") public String propString3; @Inject @Config("a=1,b=2,c=3") public Map propMap4; @Inject @Config("a=1,b=2,c=3") public Properties props5; } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/pojo/BeanExt.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.pojo; import javax.enterprise.inject.Specializes; import javax.inject.Inject; import org.dashbuilder.config.Config; @Specializes public class BeanExt extends Bean { @Inject @Config("From class") public String propString4; @Inject @Config("From class") public String propString5; @Inject @Config("From class") public String propString6; } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/test/BaseCDITest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.test; import java.net.URI; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import javax.enterprise.inject.Produces; import javax.inject.Named; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Path; import static org.mockito.Mockito.*; public class BaseCDITest { @Deployment public static Archive createTestArchive() { return ShrinkWrapHelper.createJavaArchive().addPackages(true, "org.uberfire.backend.server.spaces") .addAsManifestResource(EmptyAsset.INSTANCE, "org.dashbuilder.pojo.Bean.config") .addAsManifestResource(EmptyAsset.INSTANCE, "org.dashbuilder.pojo.BeanExt.config") .addAsManifestResource(EmptyAsset.INSTANCE, "beans.config") .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } protected IOService ioService; @Produces @Named("ioStrategy") public IOService mockIOService() throws Exception { return getIOService(); } public IOService getIOService() throws Exception { if (ioService == null) { ioService = mock(IOService.class); FileSystem fileSystem = mock(FileSystem.class); Iterable iterable = mock(Iterable.class); Iterator iterator = mock(Iterator.class); Path path = mock(Path.class); when(ioService.newFileSystem(any(URI.class), any(Map.class))).thenReturn(fileSystem); when(ioService.getFileSystem(any(URI.class))).thenReturn(fileSystem); when(fileSystem.getRootDirectories()).thenReturn(iterable); when(fileSystem.supportedFileAttributeViews()).thenReturn(new HashSet()); when(iterable.iterator()).thenReturn(iterator); when(iterator.next()).thenReturn(path); when(path.resolve(anyString())).thenReturn(path); when(path.resolve(any(Path.class))).thenReturn(path); when(path.toUri()).thenReturn(new URI("uri")); when(path.getFileName()).thenReturn(path); when(path.getFileSystem()).thenReturn(fileSystem); } return ioService; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/test/MavenProjectHelper.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.test; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.io.filefilter.FileFilterUtils; import org.apache.commons.lang3.StringUtils; public class MavenProjectHelper { public static final String JAVA_FOLDER = "java"; public static File getModuleDir(String moduleName) { File rootDir = MavenProjectHelper.getRootDir(); if (rootDir == null) throw new NullPointerException("Root directory not found"); List javaFolders = getFolders(rootDir, FileFilterUtils.nameFileFilter(moduleName)); if (!javaFolders.isEmpty()) return javaFolders.get(0); throw new RuntimeException("Module " + moduleName + " dir not found. Root=" + rootDir.getPath()); } public static File getRootDir() { File rootDir = new File(System.getProperty("user.dir")); File parentPom = new File(rootDir.getParent(), "pom.xml"); while (parentPom.exists()) { rootDir = rootDir.getParentFile(); parentPom = new File(rootDir.getParent(), "pom.xml"); } return rootDir; } public static Collection getJavaPackages(File root) { Set result = new HashSet(); List folders = getSourceFolders(root); for (File folder : folders) { String fullPath = folder.getAbsolutePath(); int index = fullPath.indexOf("/" + JAVA_FOLDER + "/"); if (index == -1) continue; String javaPath = fullPath.substring(index + 6); String javaPackage = StringUtils.replace(javaPath, "/", "."); if (!javaPackage.contains(".client")) { result.add(javaPackage); } } return result; } public static List getSourceFolders(File root) { List javaFolders = getFolders(root, FileFilterUtils.nameFileFilter(JAVA_FOLDER)); List result = new ArrayList(); for (File javaFolder : javaFolders) { List _folders = getFolders(javaFolder, null); result.add(javaFolder); result.addAll(_folders); } return result; } public static List getFolders(File root, FileFilter filter) { List result = new ArrayList(); if (root == null || !root.isDirectory()) return result; File[] files = root.listFiles(); for (File file : files) { if (file.isDirectory()) { if (filter == null || filter.accept(file)) result.add(file); result.addAll(getFolders(file, filter)); } } return result; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/java/org/dashbuilder/test/ShrinkWrapHelper.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.test; import java.io.File; import java.util.Collection; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; public class ShrinkWrapHelper { public static JavaArchive createJavaArchive() { File rootDir = MavenProjectHelper.getModuleDir("dashbuilder-backend"); if (rootDir == null) throw new NullPointerException("Root directory not found"); return createJavaArchive(rootDir); } public static JavaArchive createJavaArchive(File root) { Collection javaPackages = MavenProjectHelper.getJavaPackages(root); JavaArchive arch = ShrinkWrap.create(JavaArchive.class); for (String javaPackage : javaPackages) arch.addPackage(javaPackage); return arch; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/resources/META-INF/beans.config ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # org.dashbuilder.pojo.Bean.propString2=From beans.config org.dashbuilder.pojo.BeanExt.propString5=From beans.config ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/resources/META-INF/org.dashbuilder.pojo.Bean.config ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # propString3=From Bean.config ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-dataset-cdi/src/test/resources/META-INF/org.dashbuilder.pojo.BeanExt.config ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # propString6=From BeanExt.config ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-backend 7.75.0-SNAPSHOT dashbuilder-external-backend jar Dashbuilder External Backend jakarta.activation jakarta.activation-api commons-io commons-io org.dashbuilder dashbuilder-services-api org.dashbuilder dashbuilder-js org.slf4j slf4j-api org.jboss.errai errai-bus jakarta.enterprise jakarta.enterprise.cdi-api com.google.code.gson gson jakarta.servlet jakarta.servlet-api provided ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/java/org/dashbuilder/external/ExternalComponentServlet.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import javax.activation.MimetypesFileTypeMap; import javax.inject.Inject; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.dashbuilder.external.service.ComponentAssetProvider; import org.dashbuilder.external.service.ComponentLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static java.util.stream.Collectors.joining; public class ExternalComponentServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final String CACHE_CONTROL_PARAM = "cache-control"; private static final Logger logger = LoggerFactory.getLogger(ExternalComponentServlet.class); @Inject ComponentAssetProvider assetProvider; @Inject ComponentLoader loader; String cacheControlHeaderValue = "no-cache"; private MimetypesFileTypeMap mimeTypes; @Override public void init(ServletConfig config) throws ServletException { super.init(config); mimeTypes = new MimetypesFileTypeMap(); String cacheControl = config.getInitParameter(CACHE_CONTROL_PARAM); if (cacheControl != null) { cacheControlHeaderValue = cacheControl; } addAdditionalMimeTypes(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { handle(req, resp); } catch (IOException e) { logger.error("Error handling request to retrieve asset."); logger.debug("Error handling request to retrieve asset.", e); errorResponse(resp); } } private void handle(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.reset(); String pathInfo = req.getPathInfo(); if (pathInfo == null) { badRequest(resp); return; } String[] pathParts = pathInfo.split("/"); if (pathParts.length < 3) { badRequest(resp); return; } String assetPath = Arrays.stream(pathParts).skip(1).collect(joining(File.separator)); logger.debug("Retrieving component asset {}", assetPath); try (InputStream assetStream = assetProvider.openAsset(assetPath)) { int size = IOUtils.copy(assetStream, resp.getOutputStream()); String mimeType = mimeTypes.getContentType(pathInfo); resp.setContentType(mimeType); resp.setContentLength(size); resp.setHeader(CACHE_CONTROL_PARAM, cacheControlHeaderValue); } catch (Exception e) { logger.info("Not able to find component asset {}", assetPath); logger.debug("Error opening external component asset", e); resp.sendError(HttpServletResponse.SC_NOT_FOUND); } } private void badRequest(HttpServletResponse resp) throws IOException { resp.sendError(HttpServletResponse.SC_BAD_REQUEST); } private void errorResponse(HttpServletResponse resp) { try { resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } catch (IOException e) { logger.error("Error setting \"internal server error\" response."); logger.debug("Error setting \"internal server error\" response.", e); } } private void addAdditionalMimeTypes() { mimeTypes.addMimeTypes("text/javascript js"); mimeTypes.addMimeTypes("text/css css"); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/java/org/dashbuilder/external/impl/BackendComponentFunction.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.util.Map; /** * Server side component functions contract. * * @param * The function return type. */ public interface BackendComponentFunction { default String getName() { return this.getClass().getSimpleName(); } /** * * The function execution. Must return an object that can be used in browser windows communication. * @param params * Params set by user when configuring the component. * @return * The result * */ T exec(Map params); } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/java/org/dashbuilder/external/impl/BackendComponentFunctionServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.dashbuilder.external.service.BackendComponentFunctionService; import org.jboss.errai.bus.server.annotations.Service; @Service @ApplicationScoped public class BackendComponentFunctionServiceImpl implements BackendComponentFunctionService { Map> functions; @Inject Instance> functionsInstances; @PostConstruct void loadFunctions() { functions = new HashMap<>(); functionsInstances.forEach(instance -> functions.put(instance.getName(), instance)); } @Override public List listFunctions() { return new ArrayList<>(functions.keySet()); } @Override public Object callFunction(String name, Map params) { BackendComponentFunction function = functions.get(name); return function.exec(params); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/java/org/dashbuilder/external/impl/ComponentAssetProviderImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.apache.commons.io.FilenameUtils; import org.dashbuilder.external.service.ComponentAssetProvider; import org.dashbuilder.external.service.ComponentLoader; /** * Looks for components assets. * */ @ApplicationScoped public class ComponentAssetProviderImpl implements ComponentAssetProvider { @Inject ComponentLoader componentsLoader; @Override public InputStream openAsset(String componentAssetPath) { if (componentAssetPath != null) { String normalizedAssetPath = FilenameUtils.normalizeNoEndSeparator(componentAssetPath); if (normalizedAssetPath != null) { return getInternalComponentAsset(normalizedAssetPath).orElseGet(() -> getExternalComponentAsset(normalizedAssetPath)); } } throw new IllegalArgumentException("Invalid Asset Path."); } String fixSlashes(String componentAssetPath) { return componentAssetPath == null ? "" : componentAssetPath.replaceAll("\\\\", "/"); } private Optional getInternalComponentAsset(String componentAssetPath) { String internalComponentsBaseDir = componentsLoader.getProvidedComponentsPath(); String fullPath = "/" + internalComponentsBaseDir + "/" + fixSlashes(componentAssetPath); return Optional.ofNullable(this.getClass().getResourceAsStream(fullPath)); } private InputStream getExternalComponentAsset(String componentAssetPath) { if (!componentsLoader.isExternalComponentsEnabled()) { throw new IllegalArgumentException("External Components are not enabled"); } Path baseDir = Paths.get(componentsLoader.getExternalComponentsDir()); Path assetPath = baseDir.resolve(componentAssetPath); if (isFileInComponentsDir(baseDir, assetPath)) { return loadExternalComponentFile(assetPath); } else { throw new IllegalArgumentException("Not a component file."); } } private InputStream loadExternalComponentFile(Path assetPath) { try { return new FileInputStream(assetPath.toFile()); } catch (FileNotFoundException e) { throw new IllegalArgumentException("Error opening component file: " + e.getMessage(), e); } } // Used to prevent path traversal attacks. // Reference https://portswigger.net/web-security/file-path-traversal private boolean isFileInComponentsDir(Path baseDir, Path assetPath) { return assetPath.toAbsolutePath().normalize().startsWith(baseDir); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/java/org/dashbuilder/external/impl/ComponentLoaderImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import com.google.gson.Gson; import org.dashbuilder.components.internal.ProvidedComponentInfo; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ApplicationScoped public class ComponentLoaderImpl implements ComponentLoader { Logger logger = LoggerFactory.getLogger(ComponentLoaderImpl.class); public static final String EXTERNAL_COMP_DIR_PROP = "dashbuilder.components.dir"; public static final String EXTERNAL_COMP_ENABLE_PROP = "dashbuilder.components.enable"; private static final String DEFAULT_COMPONENTS_PATH = "/tmp/dashbuilder/components/"; private ProvidedComponentInfo providedComponentsInfo; private String externalComponentsDir; private Gson gson; private boolean externalComponentEnabled; @PostConstruct public void init() { gson = new Gson(); providedComponentsInfo = ProvidedComponentInfo.get(); externalComponentEnabled = Boolean.parseBoolean(System.getProperty(EXTERNAL_COMP_ENABLE_PROP, Boolean.FALSE.toString())); externalComponentsDir = System.getProperty(EXTERNAL_COMP_DIR_PROP, DEFAULT_COMPONENTS_PATH); if (externalComponentEnabled) { Path baseDirPath = Paths.get(externalComponentsDir); if (!baseDirPath.toFile().exists()) { baseDirPath.toFile().mkdirs(); } } } @Override public List loadProvided() { return providedComponentsInfo.getInternalComponentsList() .stream() .map(this::readInternalComponent) .filter(Objects::nonNull) .collect(Collectors.toList()); } @Override public List loadExternal() { if (externalComponentEnabled) { try (Stream walker = Files.walk(Paths.get(externalComponentsDir), 1)) { return walker.filter(p -> p.toFile().isDirectory()) .map(this::getComponentDescriptor) .filter(File::exists) .map(this::readComponent) .filter(Objects::nonNull) .collect(Collectors.toList()); } catch (IOException e) { logger.error("Error loading components from {}. Error: {}", externalComponentsDir, e.getMessage()); logger.debug("Error loading external components.", e); } } return Collections.emptyList(); } @Override public String getExternalComponentsDir() { return externalComponentsDir; } @Override public String getProvidedComponentsPath() { return providedComponentsInfo.getInternalComponentsRootPath(); } private ExternalComponent readInternalComponent(String componentId) { String internalComponentDescriptor = "/" + providedComponentsInfo.getInternalComponentsRootPath() + "/" + componentId + "/" + DESCRIPTOR_FILE; InputStream is = this.getClass().getResourceAsStream(internalComponentDescriptor); if (is == null) { logger.error("Not able to read internal component manifest file for component {}", componentId); return null; } return readComponent(componentId, new InputStreamReader(is)); } private ExternalComponent readComponent(File file) { String id = file.getParentFile().getName(); FileReader reader; try { reader = new FileReader(file); return this.readComponent(id, reader); } catch (FileNotFoundException e) { logger.error("Not able to read component manifest file {}. Error: {}", file.getPath(), e.getMessage()); logger.debug("Error reading component file.", e); return null; } } private ExternalComponent readComponent(String componentId, Reader manifestReader) { try { ExternalComponent component = gson.fromJson(manifestReader, ExternalComponent.class); component.setId(componentId); return component; } catch (Exception e) { logger.error("Not able to load component {}. Error: {}", componentId, e.getMessage()); logger.debug("Error reading component.", e); } return null; } private File getComponentDescriptor(Path p) { return Paths.get(p.toString(), DESCRIPTOR_FILE).toFile(); } public boolean isExternalComponentsEnabled() { return externalComponentEnabled; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/java/org/dashbuilder/external/impl/ComponentServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentLoader; import org.dashbuilder.external.service.ComponentService; import org.jboss.errai.bus.server.annotations.Service; @Service @ApplicationScoped public class ComponentServiceImpl implements ComponentService { @Inject ComponentLoader loader; @Override public List listExternalComponents() { return loader.loadExternal(); } @Override public List listProvidedComponents() { return loader.loadProvided(); } @Override public Optional byId(String componentId) { return Stream.concat(loader.loadProvided().stream(), loader.loadExternal().stream()) .filter(c -> componentId.equals(c.getId())) .findFirst(); } @Override public List listAllComponents() { List allComponents = new ArrayList<>(); List external = loader.loadExternal(); List provided = loader.loadProvided(); external.forEach(c -> c.setProvided(false)); provided.forEach(c -> c.setProvided(true)); allComponents.addAll(provided); allComponents.addAll(external); return allComponents; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/java/org/dashbuilder/external/impl/function/BackendDateFunction.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl.function; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import javax.enterprise.context.Dependent; import org.dashbuilder.external.impl.BackendComponentFunction; /** * Component backend function that returns the date. * */ @Dependent public class BackendDateFunction implements BackendComponentFunction { private static final String FORMAT_PARAM = "format"; @Override public String exec(Map params) { Object pattern = params.get(FORMAT_PARAM); if (pattern != null) { return new SimpleDateFormat(pattern.toString()).format(new Date()); } return new Date().toString(); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/test/java/org/dashbuilder/external/impl/ComponentAssetProviderImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.dashbuilder.components.internal.ProvidedComponentInfo; import org.dashbuilder.external.service.ComponentLoader; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.Silent.class) public class ComponentAssetProviderImplTest { @Mock ComponentLoader componentLoader; @InjectMocks ComponentAssetProviderImpl componentAssetProviderImpl; private Path componentsDir; @Before public void prepare() throws IOException { componentsDir = Files.createTempDirectory("components"); when(componentLoader.getExternalComponentsDir()).thenReturn(componentsDir.toString()); when(componentLoader.getProvidedComponentsPath()).thenReturn(ProvidedComponentInfo.get().getInternalComponentsRootPath()); } @After public void after() { FileUtils.deleteQuietly(componentsDir.toFile()); } @Test public void testExternalComponentAsset() throws Exception { String componentFileContent = "abc"; String componentId = "c1"; String componentFileName = "testFile"; String assetPath = createComponentFile(componentId, componentFileName, componentFileContent); when(componentLoader.isExternalComponentsEnabled()).thenReturn(true); String assetFileLoadedContent = IOUtils.toString(componentAssetProviderImpl.openAsset(assetPath), StandardCharsets.UTF_8); assertEquals(componentFileContent, assetFileLoadedContent); } @Test(expected = IllegalArgumentException.class) public void testExternalComponentAssetWithExternalComponentsDisabled() throws Exception { String componentFileContent = "abc"; String componentId = "c1"; String componentFileName = "testFile"; String assetPath = createComponentFile(componentId, componentFileName, componentFileContent); when(componentLoader.isExternalComponentsEnabled()).thenReturn(false); componentAssetProviderImpl.openAsset(assetPath); } @Test(expected = IllegalArgumentException.class) public void testAvoidTraversalPath() throws Exception { String componentFileContent = "abc"; String componentId = "c1"; String componentFileName = "testFile"; createComponentFile(componentId, componentFileName, componentFileContent); Path shouldNotBeAccessible = Files.createTempFile("should_not_be_accessible", ""); Path relativePath = componentsDir.relativize(shouldNotBeAccessible); when(componentLoader.isExternalComponentsEnabled()).thenReturn(true); try { componentAssetProviderImpl.openAsset(relativePath.toString()); } catch (Exception e) { throw e; } finally { FileUtils.deleteQuietly(shouldNotBeAccessible.toFile()); } } @Test public void testInternalComponentAsset() throws Exception { String logoImage = "logo-provided/images/dashbuilder-logo.png"; String logoIndexJs = "logo-provided/index.js"; String logoIndexHtml = "logo-provided/index.html"; assertNotNull(componentAssetProviderImpl.openAsset(logoImage)); assertNotNull(componentAssetProviderImpl.openAsset(logoIndexJs)); assertNotNull(componentAssetProviderImpl.openAsset(logoIndexHtml)); } @Test(expected = IllegalArgumentException.class) public void testInternalComponentAssetPathTraversal() throws Exception { assertNotNull(componentAssetProviderImpl.openAsset("../../../dashbuilder-components.properties")); } @Test public void testFixSlashes() throws Exception { assertEquals("/abc/cde", componentAssetProviderImpl.fixSlashes("\\abc\\cde")); assertEquals("/abc/cde", componentAssetProviderImpl.fixSlashes("/abc/cde")); assertEquals("", componentAssetProviderImpl.fixSlashes(null)); } private String createComponentFile(String componentId, String fileName, String fileContent) throws Exception { Path componentDir = componentsDir.resolve(componentId); Path componentFile = componentDir.resolve(fileName); if (!componentDir.toFile().exists()) { Files.createDirectory(componentDir); } Files.createFile(componentFile); Files.write(componentFile, fileContent.getBytes(StandardCharsets.UTF_8)); return componentId + "/" + fileName; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/test/java/org/dashbuilder/external/impl/ComponentLoaderImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.Optional; import org.dashbuilder.external.model.ComponentParameter; import org.dashbuilder.external.model.ExternalComponent; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.lesscss.deps.org.apache.commons.io.FileUtils; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class ComponentLoaderImplTest { private static final String C1_ID = "c1_id"; private static final String C2_ID = "c2_id"; private static final String TEXT = "text"; private static final String C2P1_LABEL = "c2p1 label"; private static final String C2P1_DEFAULT = "c2p1 default"; private static final String C2P1 = "c2p1"; private static final String C2_ICON = "c2 icon"; private static final String C2 = "c2"; private static final String C1P1_LABEL = "c1p1 label"; private static final String C1P1_DEFAULT = "c1p1 default"; private static final String C1P1 = "c1p1"; private static final String C1_ICON = "c1 icon"; private static final String C1 = "c1"; final String C1_MANIFEST = "{\n" + " \"name\": \"" + C1 + "\",\n" + " \"icon\": \"" + C1_ICON + "\",\n" + " \"parameters\": [\n" + " {\n" + " \"name\": \"" + C1P1 + "\",\n" + " \"type\": \"" + TEXT + "\",\n" + " \"defaultValue\": \"" + C1P1_DEFAULT + "\",\n" + " \"label\": \"" + C1P1_LABEL + "\"\n" + " }\n" + "\n" + " ]\n" + "}"; final String C2_MANIFEST = "{\n" + " \"name\": \"" + C2 + "\",\n" + " \"icon\": \"" + C2_ICON + "\",\n" + " \"parameters\": [\n" + " {\n" + " \"name\": \"" + C2P1 + "\",\n" + " \"type\": \"text\",\n" + " \"defaultValue\": \"" + C2P1_DEFAULT + "\",\n" + " \"label\": \"" + C2P1_LABEL + "\"\n" + " }\n" + "\n" + " ]\n" + "}"; private Path componentPath; ComponentLoaderImpl externalComponentLoaderImpl; @Before public void init() throws URISyntaxException { String rootPath = ComponentLoaderImplTest.class.getResource("/") .getFile(); externalComponentLoaderImpl = new ComponentLoaderImpl(); componentPath = Paths.get(rootPath, "components"); System.setProperty(ComponentLoaderImpl.EXTERNAL_COMP_DIR_PROP, componentPath.toString()); System.setProperty(ComponentLoaderImpl.EXTERNAL_COMP_ENABLE_PROP, Boolean.TRUE.toString()); } @After public void cleanup() throws IOException { FileUtils.deleteQuietly(componentPath.toFile()); } @Test public void testBaseDirCreated() { assertFalse(Files.exists(componentPath)); externalComponentLoaderImpl.init(); assertTrue(Files.exists(componentPath)); } @Test public void testLoad() { externalComponentLoaderImpl.init(); createComponentsFiles(); List components = externalComponentLoaderImpl.loadExternal(); assertEquals(2, components.size()); ExternalComponent c1 = getComponent(components, C1_ID); ExternalComponent c2 = getComponent(components, C2_ID); assertEquals(1, c1.getParameters().size()); assertEquals(C1, c1.getName()); assertEquals(C1_ICON, c1.getIcon()); ComponentParameter cp1 = c1.getParameters().get(0); assertEquals(C1P1, cp1.getName()); assertEquals(C1P1_DEFAULT, cp1.getDefaultValue()); assertEquals(C1P1_LABEL, cp1.getLabel()); assertEquals(1, c2.getParameters().size()); assertEquals(C2, c2.getName()); assertEquals(C2_ICON, c2.getIcon()); ComponentParameter cp2 = c2.getParameters().get(0); assertEquals(C2P1, cp2.getName()); assertEquals(C2P1_DEFAULT, cp2.getDefaultValue()); assertEquals(C2P1_LABEL, cp2.getLabel()); } @Test public void testLoadWhenDisabled() throws IOException { System.setProperty(ComponentLoaderImpl.EXTERNAL_COMP_ENABLE_PROP, Boolean.FALSE.toString()); externalComponentLoaderImpl.init(); assertFalse(Files.exists(componentPath)); Files.createDirectory(componentPath); createComponentsFiles(); assertTrue(externalComponentLoaderImpl.loadExternal().isEmpty()); } @Test public void testLoadInternalComponents() throws IOException { externalComponentLoaderImpl.init(); List internalComponents = externalComponentLoaderImpl.loadProvided(); assertEquals(4, internalComponents.size()); ExternalComponent component = internalComponents.get(0); assertEquals("logo-provided", component.getId()); List parameters = component.getParameters(); assertEquals(3, parameters.size()); Optional srcParamOp = component.getParameters() .stream() .filter(p -> p.getName().equals("src")) .findFirst(); assertTrue(srcParamOp.isPresent()); ComponentParameter srcParam = srcParamOp.get(); assertEquals("src", srcParam.getName()); assertEquals("Logo URL", srcParam.getLabel()); assertEquals("text", srcParam.getType()); Optional widthParamOp = component.getParameters() .stream() .filter(p -> p.getName().equals("width")) .findFirst(); assertTrue(widthParamOp.isPresent()); ComponentParameter widthParam = widthParamOp.get(); assertEquals("width", widthParam.getName()); assertEquals("Width", widthParam.getLabel()); assertEquals("text", widthParam.getType()); Optional heightParamOp = component.getParameters() .stream() .filter(p -> p.getName().equals("height")) .findFirst(); assertTrue(heightParamOp.isPresent()); ComponentParameter heightParam = heightParamOp.get(); assertEquals("height", heightParam.getName()); assertEquals("Height", heightParam.getLabel()); assertEquals("text", heightParam.getType()); } private ExternalComponent getComponent(List components, String id) { return components.stream().filter(c -> c.getId().equals(id)).findFirst().get(); } private void createComponentsFiles() { try { Path c1 = Paths.get(componentPath.toString(), C1_ID, ComponentLoaderImpl.DESCRIPTOR_FILE); c1.toFile().getParentFile().mkdirs(); c1.toFile().createNewFile(); Files.write(c1, C1_MANIFEST.getBytes()); Path c2 = Paths.get(componentPath.toString(), C2_ID, ComponentLoaderImpl.DESCRIPTOR_FILE); c2.toFile().getParentFile().mkdirs(); c2.toFile().createNewFile(); Files.write(c2, C2_MANIFEST.getBytes()); } catch (IOException e) { e.printStackTrace(); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-external-backend/src/test/java/org/dashbuilder/external/impl/ComponentServiceImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.impl; import java.util.Collections; import java.util.List; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentLoader; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class ComponentServiceImplTest { private static final String C1_ID = "c1"; private static final String C2_ID = "c2"; @Mock ComponentLoader loader; @InjectMocks ComponentServiceImpl externalComponentServiceImpl; @Test public void testById() { ExternalComponent c1 = new ExternalComponent(C1_ID, "c1 name", "c1 icon", false, Collections.emptyList()); ExternalComponent c2 = new ExternalComponent(C2_ID, "c2 name", "c2 icon", false, Collections.emptyList()); Mockito.when(loader.loadExternal()).thenReturn(asList(c1, c2)); assertTrue(externalComponentServiceImpl.byId(C1_ID).isPresent()); assertTrue(externalComponentServiceImpl.byId(C2_ID).isPresent()); assertFalse(externalComponentServiceImpl.byId("do not exist").isPresent()); } @Test public void testByIdProvidedPriority() { String c1ProvidedName = "c1 provided"; ExternalComponent c1_provided = new ExternalComponent(C1_ID, c1ProvidedName, "c1 icon", false, Collections.emptyList()); ExternalComponent c1_external = new ExternalComponent(C1_ID, "c1 external", "c1 icon", false, Collections.emptyList()); when(loader.loadProvided()).thenReturn(asList(c1_provided)); when(loader.loadExternal()).thenReturn(asList(c1_external)); assertEquals(c1ProvidedName, externalComponentServiceImpl.byId(C1_ID).get().getName()); } @Test public void testListAllComponents() { String providedId = "c1"; String externalId = "c2"; ExternalComponent c1_provided = new ExternalComponent(providedId, "name", "icon", false, Collections.emptyList()); ExternalComponent c1_external = new ExternalComponent(externalId, "name", "icon", false, Collections.emptyList()); when(loader.loadProvided()).thenReturn(asList(c1_provided)); when(loader.loadExternal()).thenReturn(asList(c1_external)); List comps = externalComponentServiceImpl.listAllComponents(); ExternalComponent cp = comps.stream().filter(c -> providedId.equals(c.getId())).findAny().get(); ExternalComponent ce = comps.stream().filter(c -> externalId.equals(c.getId())).findAny().get(); assertTrue(cp.isProvided()); assertFalse(ce.isProvided()); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-backend 7.75.0-SNAPSHOT dashbuilder-kie-server-backend jar Dashbuilder Kie Server Backend org.dashbuilder dashbuilder-kie-server-api jakarta.enterprise jakarta.enterprise.cdi-api provided jakarta.xml.bind jakarta.xml.bind-api provided org.jboss.errai errai-config org.jboss.resteasy resteasy-client provided org.dashbuilder dashbuilder-external-backend provided javax.annotation javax.annotation-api ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/KieServerConnectionInfoProviderImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.kieserver.KieServerConnectionInfo; import org.dashbuilder.kieserver.KieServerConnectionInfoProvider; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.jboss.errai.bus.server.annotations.Service; /** * Provide access to user configured connection provider * */ @Service @ApplicationScoped public class KieServerConnectionInfoProviderImpl implements KieServerConnectionInfoProvider { static final String CONFIGURATION_NOT_FOUND_MESSAGE = "Configuration for dataset %s / server template %s not found"; static final String MISSING_URL_MESSAGE = "URL configuration for dataset %s / server template %s is missing"; static final String MISSING_AUTH_MESSAGE = "Auth configuration for dataset %s / server template %s is missing." + "You should provide user/password or token authentication"; private static final String SERVER_TEMPLATE_SEPARATOR = ","; static final String DEFAULT_SERVER_TEMPLATE_PROPERTY = "dashbuilder.kieserver.defaultServerTemplate"; static final String SERVER_TEMPLATE_LIST_PROPERTY = "dashbuilder.kieserver.serverTemplates"; static final String SERVER_TEMPLATE_PROP_PREFFIX = "dashbuilder.kieserver.serverTemplate"; static final String DATASET_PROP_PREFFIX = "dashbuilder.kieserver.dataset"; private static final String SERVER_TEMPLATE_PROPERTY_TEMPLATE = SERVER_TEMPLATE_PROP_PREFFIX + ".%s.%s"; private static final String REMOTE_DATASET_PROPERTY_TEMPLATE = DATASET_PROP_PREFFIX + ".%s.%s"; public static enum KieServerConfigurationKey { LOCATION("location"), USER("user"), PASSWORD("password"), REPLACE_QUERY("replace_query"), TOKEN("token"); private KieServerConfigurationKey(String value) { this.value = value; } private String value; public String getValue() { return this.value; } } @Override public List serverTemplates() { return Optional.ofNullable(System.getProperty(SERVER_TEMPLATE_LIST_PROPERTY)) .map(templates -> templates.split(SERVER_TEMPLATE_SEPARATOR)) .map(template -> Arrays.stream(template) .map(String::trim) .filter(s -> !s.isEmpty()) .collect(Collectors.toList())) .orElse(Collections.emptyList()); } @Override public KieServerConnectionInfo verifiedConnectionInfo(RemoteDataSetDef def) { String name = def.getName(); String serverTemplateId = def.getServerTemplateId(); String missingConfigError = String.format(CONFIGURATION_NOT_FOUND_MESSAGE, name, serverTemplateId); String missingUrlError = String.format(MISSING_URL_MESSAGE, name, serverTemplateId); String missingAuthError = String.format(MISSING_AUTH_MESSAGE, name, serverTemplateId); KieServerConnectionInfo connectionInfo = get(name, serverTemplateId).orElseThrow(() -> new RuntimeException(missingConfigError)); if (!connectionInfo.getLocation().isPresent()) { throw new RuntimeException(missingUrlError); } if (!connectionInfo.getUser().isPresent() && !connectionInfo.getToken().isPresent()) { throw new RuntimeException(missingAuthError); } return connectionInfo; } @Override public Optional get(String name, String serverTemplate) { Optional optional = get(name, this::remoteDatasetProperty); if (!optional.isPresent()) { optional = get(serverTemplate, this::serverTemplateProperty); } return optional; } public Optional serverTemplateProperty(String serverTemplate, KieServerConfigurationKey configurationKey) { String property = String.format(SERVER_TEMPLATE_PROPERTY_TEMPLATE, serverTemplate, configurationKey.value); return filteredProperty(property); } public Optional remoteDatasetProperty(String datasetUUID, KieServerConfigurationKey configurationKey) { String property = String.format(REMOTE_DATASET_PROPERTY_TEMPLATE, datasetUUID, configurationKey.value); return filteredProperty(property); } @Override public Optional getDefault() { String defaultTemplate = System.getProperty(DEFAULT_SERVER_TEMPLATE_PROPERTY); if (defaultTemplate != null) { return this.get(null, defaultTemplate); } return findFirstServerTemplateConf().flatMap(template -> get(null, template)); } private Optional filteredProperty(String property) { return Optional.ofNullable(System.getProperty(property)).filter(v -> !v.trim().isEmpty()); } private Optional get(String confType, BiFunction> propertyProvider) { Optional url = propertyProvider.apply(confType, KieServerConfigurationKey.LOCATION); Optional user = propertyProvider.apply(confType, KieServerConfigurationKey.USER); Optional password = propertyProvider.apply(confType, KieServerConfigurationKey.PASSWORD); Optional token = propertyProvider.apply(confType, KieServerConfigurationKey.TOKEN); Optional replaceQueryOp = propertyProvider.apply(confType, KieServerConfigurationKey.REPLACE_QUERY); boolean noPropertyFound = Stream.of(url, user, password, token, replaceQueryOp) .noneMatch(Optional::isPresent); if (noPropertyFound) { return Optional.empty(); } boolean replaceQuery = replaceQueryOp.isPresent() && Boolean.TRUE.toString().equalsIgnoreCase(replaceQueryOp.get()); return Optional.of(new KieServerConnectionInfo(url, user, password, token, replaceQuery)); } Optional findFirstServerTemplateConf() { return Collections.list(System.getProperties().keys()) .stream() .map(Object::toString) .filter(key -> key.startsWith(SERVER_TEMPLATE_PROP_PREFFIX)) .map(this::retrieveTemplateId) .filter(Objects::nonNull) .findFirst(); } String retrieveTemplateId(String property) { String[] parts = property.replaceAll(SERVER_TEMPLATE_PROP_PREFFIX, "") .split("\\."); if (parts.length > 1) { return parts[1]; } return null; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/KieServerDataSetListener.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.kieserver.KieServerConnectionInfo; import org.dashbuilder.kieserver.KieServerConnectionInfoProvider; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.kieserver.backend.rest.KieServerQueryClient; import org.dashbuilder.kieserver.backend.rest.QueryDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Keeps Kie Server up to date with remote dataset changes * */ @ApplicationScoped public class KieServerDataSetListener { private static final Logger LOGGER = LoggerFactory.getLogger(KieServerDataSetListener.class); @Inject KieServerQueryClient queryClient; @Inject KieServerConnectionInfoProvider connectionInfoProvider; void onDataSetDefRegisteredEvent(@Observes DataSetDefRegisteredEvent event) { DataSetDef def = event.getDataSetDef(); replaceQueryInKieServers(def); } void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { DataSetDef def = event.getNewDataSetDef(); replaceQueryInKieServers(def); } void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { DataSetDef def = event.getDataSetDef(); if (def instanceof RemoteDataSetDef) { try { KieServerConnectionInfo connectionInfo = connectionInfoProvider.verifiedConnectionInfo((RemoteDataSetDef) def); queryClient.unregisterQuery(connectionInfo, def.getUUID()); LOGGER.info("Data set definition {} ({}) deletion event processed", def.getUUID(), def.getName()); } catch (Exception e) { LOGGER.warn("Not able to delete query in server for removed dataset definition {} ", def.getName()); LOGGER.debug("Not able to delete query in server for removed dataset definition {}", def.getName(), e); } } } protected void replaceQueryInKieServers(DataSetDef def) { if (def instanceof RemoteDataSetDef && ((RemoteDataSetDef) def).getServerTemplateId() != null) { try { KieServerConnectionInfo connectionInfo = connectionInfoProvider.verifiedConnectionInfo((RemoteDataSetDef) def); QueryDefinition queryDefinition = QueryDefinition.builder() .name(def.getUUID()) .source(((RemoteDataSetDef) def).getDataSource()) .target(((RemoteDataSetDef) def).getQueryTarget()) .expression(((RemoteDataSetDef) def).getDbSQL()) .build(); queryClient.replaceQuery(connectionInfo, queryDefinition); LOGGER.info("Data set definition {} ({}) modification event processed", def.getUUID(), def.getName()); } catch (Exception e) { LOGGER.warn("Not able to replace query in server for dataset definition {} ", def.getName()); LOGGER.debug("Not able to replace query in server for dataset definition {} ", def.getName(), e); } } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/RuntimeKieServerDataSetProvider.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Map.Entry; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataprovider.DataSetProvider; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.filter.LogicalExprFilter; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.impl.DataColumnImpl; import org.dashbuilder.dataset.impl.DataSetMetadataImpl; import org.dashbuilder.dataset.sort.ColumnSort; import org.dashbuilder.dataset.sort.DataSetSort; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.kieserver.ConsoleDataSetLookup; import org.dashbuilder.kieserver.KieServerConnectionInfo; import org.dashbuilder.kieserver.KieServerConnectionInfoProvider; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.kieserver.RuntimeKieServerDataSetProviderType; import org.dashbuilder.kieserver.backend.rest.KieServerQueryClient; import org.dashbuilder.kieserver.backend.rest.QueryDefinition; import org.dashbuilder.kieserver.backend.rest.QueryFilterSpec; import org.dashbuilder.kieserver.backend.rest.QueryParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ApplicationScoped public class RuntimeKieServerDataSetProvider implements DataSetProvider { public static final DataSetProviderType TYPE = new RuntimeKieServerDataSetProviderType(); private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeKieServerDataSetProvider.class); @Inject KieServerQueryClient queryClient; @Inject KieServerConnectionInfoProvider connectionInfoProvider; @Override public DataSetProviderType getType() { return TYPE; } @Override public DataSetMetadata getDataSetMetadata(DataSetDef def) throws Exception { List columnNames = new ArrayList<>(); List columnTypes = new ArrayList<>(); if (def.getColumns() == null && def instanceof RemoteDataSetDef) { KieServerConnectionInfo connectionInfo = connectionInfoProvider.verifiedConnectionInfo((RemoteDataSetDef) def); QueryDefinition definition = queryClient.getQuery(connectionInfo, def.getUUID()); if (definition.getColumns() != null) { addColumnsToDefinition(def, definition); } } def.getColumns().forEach(column -> { columnNames.add(column.getId()); columnTypes.add(column.getColumnType()); }); return new DataSetMetadataImpl(def, def.getUUID(), -1, def.getColumns().size(), columnNames, columnTypes, -1); } @Override public DataSet lookupDataSet(DataSetDef def, DataSetLookup lookup) throws Exception { ConsoleDataSetLookup dataSetLookup = adoptLookup(def, lookup); LOGGER.debug("Data Set lookup using Server Template Id: {}", dataSetLookup.getServerTemplateId()); if (dataSetLookup.getServerTemplateId() == null || dataSetLookup.getServerTemplateId().isEmpty()) { return buildDataSet(def, new ArrayList<>(), new ArrayList<>()); } List filterParams = new ArrayList<>(); QueryFilterSpec filterSpec = new QueryFilterSpec(); // apply filtering for (DataSetFilter filter : dataSetLookup.getOperationList(DataSetFilter.class)) { if (filter != null) { for (ColumnFilter cFilter : filter.getColumnFilterList()) { if (cFilter instanceof CoreFunctionFilter) { CoreFunctionFilter coreFunctionFilter = (CoreFunctionFilter) cFilter; filterParams.add(new QueryParam(coreFunctionFilter.getColumnId(), coreFunctionFilter.getType().toString(), coreFunctionFilter.getParameters())); } else if (cFilter instanceof LogicalExprFilter) { LogicalExprFilter logicalExprFilter = (LogicalExprFilter) cFilter; filterParams.add(new QueryParam(logicalExprFilter.getColumnId(), logicalExprFilter.getLogicalOperator().toString(), logicalExprFilter.getLogicalTerms())); } } } } List extraColumns = new ArrayList(); List dataSetGroups = lookup.getFirstGroupOpSelections(); for (DataSetGroup group : dataSetGroups) { if (group.getSelectedIntervalList() != null && group.getSelectedIntervalList().size() > 0) { appendIntervalSelection(group, filterParams); } } DataSetGroup dataSetGroup = dataSetLookup.getLastGroupOp(); handleDataSetGroup(def, dataSetGroup, filterParams, extraColumns); if (!filterParams.isEmpty()) { filterSpec.setParameters(filterParams.toArray(new QueryParam[filterParams.size()])); } // apply sorting DataSetSort sort = dataSetLookup.getFirstSortOp(); if (sort != null) { SortOrder sortOrder = SortOrder.UNSPECIFIED; StringBuilder orderBy = new StringBuilder(); for (ColumnSort cSort : sort.getColumnSortList()) { orderBy.append(cSort.getColumnId()).append(","); sortOrder = cSort.getOrder(); } // remove last , orderBy.deleteCharAt(orderBy.length() - 1); filterSpec.setOrderBy(orderBy.toString()); filterSpec.setAscending(sortOrder.equals(SortOrder.ASCENDING)); } final List instances = performQuery((RemoteDataSetDef) def, dataSetLookup, filterSpec); LOGGER.debug("Query client returned {} row(s)", instances.size()); return buildDataSet(def, instances, extraColumns); } protected ConsoleDataSetLookup adoptLookup(DataSetDef def, DataSetLookup lookup) { ConsoleDataSetLookup dataSetLookup = null; if (!(lookup instanceof ConsoleDataSetLookup)) { if (def instanceof RemoteDataSetDef) { dataSetLookup = (ConsoleDataSetLookup) ConsoleDataSetLookup.fromInstance(lookup, ((RemoteDataSetDef) def).getServerTemplateId()); DataSetFilter filter = def.getDataSetFilter(); if (filter != null) { dataSetLookup.addOperation(filter); } } else { throw new IllegalArgumentException("DataSetLookup is of incorrect type " + lookup.getClass().getName()); } } else { dataSetLookup = (ConsoleDataSetLookup) lookup; } return dataSetLookup; } protected List performQuery(RemoteDataSetDef def, ConsoleDataSetLookup lookup, QueryFilterSpec filterSpec) { KieServerConnectionInfo connectionInfo = connectionInfoProvider.verifiedConnectionInfo(def); String queryName = def.getQueryName() != null ? def.getQueryName() : def.getUUID(); int pageNumber = lookup.getRowOffset() / lookup.getNumberOfRows(); if (lookup.testMode() || connectionInfo.isReplaceQuery()) { QueryDefinition queryDefinition = QueryDefinition.builder() .name(queryName) .source(def.getDataSource()) .target(def.getQueryTarget()) .expression(def.getDbSQL()) .build(); QueryDefinition registered = queryClient.replaceQuery(connectionInfo, queryDefinition); if (registered.getColumns() != null) { addColumnsToDefinition(def, registered); } try { return queryClient.query(connectionInfo, queryName, filterSpec, pageNumber, lookup.getNumberOfRows()); } catch (Exception e) { queryClient.unregisterQuery(connectionInfo, queryName); throw new RuntimeException(e); } } else { if (def.getColumns() != null && def.getColumns().isEmpty()) { QueryDefinition query = queryClient.getQuery(connectionInfo, queryName); addColumnsToDefinition(def, query); } return queryClient.query(connectionInfo, queryName, filterSpec, pageNumber, lookup.getNumberOfRows()); } } @Override public boolean isDataSetOutdated(DataSetDef def) { return false; } protected DataSet buildDataSet(DataSetDef def, List instances, List extraColumns) throws Exception { DataSet dataSet = DataSetFactory.newEmptyDataSet(); dataSet.setUUID(def.getUUID()); dataSet.setDefinition(def); if (extraColumns != null && !extraColumns.isEmpty()) { for (DataColumn extraColumn : extraColumns) { dataSet.addColumn(extraColumn); } } else { for (DataColumnDef column : def.getColumns()) { DataColumn numRows = new DataColumnImpl(column.getId(), column.getColumnType()); dataSet.addColumn(numRows); } } for (List row : instances) { int columnIndex = 0; for (Object value : row) { DataColumn intervalBuilder = dataSet.getColumnByIndex(columnIndex); ColumnType columnType = intervalBuilder.getColumnType(); if (columnType.equals(ColumnType.DATE) && isNumberValue(value)) { Number dateNumber = NumberFormat.getInstance().parse(value.toString()); Date dateValue = new Date(dateNumber.longValue()); intervalBuilder.getValues().add(dateValue); } else { intervalBuilder.getValues().add(value); } columnIndex++; } } // set size of the results to allow paging to be more then the actual size // dataSet.setRowCountNonTrimmed(instances.size() == 0 ? 0 : instances.size() + 1); dataSet.setRowCountNonTrimmed(instances.size()); return dataSet; } protected void appendIntervalSelection(DataSetGroup intervalSel, List filterParams) { if (intervalSel != null && intervalSel.isSelect()) { ColumnGroup cg = intervalSel.getColumnGroup(); List intervalList = intervalSel.getSelectedIntervalList(); // Get the filter values List names = new ArrayList(); Comparable min = null; Comparable max = null; for (Interval interval : intervalList) { names.add(interval.getName()); Comparable intervalMin = (Comparable) interval.getMinValue(); Comparable intervalMax = (Comparable) interval.getMaxValue(); if (intervalMin != null) { if (min == null) { min = intervalMin; } else if (min.compareTo(intervalMin) > 0) { min = intervalMin; } } if (intervalMax != null) { if (max == null) { max = intervalMax; } else if (max.compareTo(intervalMax) > 0) { max = intervalMax; } } } // Min can't be greater than max. if (min != null && max != null && min.compareTo(max) > 0) { min = max; } ColumnFilter filter; if (min != null && max != null) { filter = FilterFactory.between(cg.getSourceId(), min, max); } else if (min != null) { filter = FilterFactory.greaterOrEqualsTo(cg.getSourceId(), min); } else if (max != null) { filter = FilterFactory.lowerOrEqualsTo(cg.getSourceId(), max); } else { filter = FilterFactory.equalsTo(cg.getSourceId(), names); } CoreFunctionFilter coreFunctionFilter = (CoreFunctionFilter) filter; filterParams.add(new QueryParam(coreFunctionFilter.getColumnId(), coreFunctionFilter.getType().toString(), coreFunctionFilter.getParameters())); } } protected void handleDataSetGroup(final DataSetDef def, final DataSetGroup dataSetGroup, final List filterParams, final List extraColumns) { if (dataSetGroup != null) { if (dataSetGroup.getColumnGroup() != null) { // handle group if (dataSetGroup.getColumnGroup().getIntervalSize() != null) { filterParams.add(new QueryParam(dataSetGroup.getColumnGroup().getSourceId(), "group", Arrays.asList(dataSetGroup.getColumnGroup().getColumnId(), dataSetGroup.getColumnGroup().getIntervalSize(), dataSetGroup.getColumnGroup().getMaxIntervals()))); } else { filterParams.add(new QueryParam(dataSetGroup.getColumnGroup().getSourceId(), "group", Arrays.asList(dataSetGroup.getColumnGroup().getColumnId()))); } } // handle additional columns for (GroupFunction groupFunction : dataSetGroup.getGroupFunctions()) { if (groupFunction.getFunction() != null) { filterParams.add(new QueryParam(groupFunction.getSourceId(), groupFunction.getFunction().toString(), Arrays.asList(groupFunction.getColumnId()))); extraColumns.add(new DataColumnImpl(groupFunction.getSourceId(), ColumnType.NUMBER)); } else { filterParams.add(new QueryParam(groupFunction.getSourceId(), null, Arrays.asList(groupFunction.getColumnId()))); extraColumns.add(new DataColumnImpl(groupFunction.getSourceId(), getGroupFunctionColumnType(def, dataSetGroup.getColumnGroup(), groupFunction))); } } } } protected ColumnType getGroupFunctionColumnType(final DataSetDef def, final ColumnGroup columnGroup, final GroupFunction groupFunction) { ColumnType type = def.getColumnById(groupFunction.getColumnId()).getColumnType(); if (type != ColumnType.DATE || columnGroup == null || groupFunction == null) { return type; } else { return columnGroup.getSourceId().equals(groupFunction.getSourceId()) ? ColumnType.LABEL : type; } } protected void addColumnsToDefinition(DataSetDef def, QueryDefinition queryDef) { Map columns = queryDef.getColumns(); if (columns != null) { columns.entrySet().stream() .filter(e -> def.getColumnById(e.getKey()) == null) .forEach(e -> def.addColumn(e.getKey(), ColumnType.valueOf(e.getValue()))); } } protected boolean isNumberValue(Object value) { try { NumberFormat.getInstance().parse(value.toString()); return true; } catch (Exception e) { LOGGER.debug("Date value is not parseable to number", e); } return false; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/function/ProcessSVGFunction.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend.function; import java.util.Map; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.ws.rs.WebApplicationException; import org.dashbuilder.external.impl.BackendComponentFunction; import org.dashbuilder.kieserver.KieServerConnectionInfo; import org.dashbuilder.kieserver.KieServerConnectionInfoProvider; import org.dashbuilder.kieserver.backend.rest.KieServerQueryClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Dependent public class ProcessSVGFunction implements BackendComponentFunction { private static final Logger LOGGER = LoggerFactory.getLogger(ProcessSVGFunction.class); private static final String ERROR_REQUESTING_SVG = "Error requesting SVG from Kie Server: %s"; private static final String NOT_FOUND_MSG = "Process SVG not found for container %s and process %s"; private static final String CONTAINERID_PARAM = "containerId"; private static final String PROCESSID_PARAM = "processId"; private static final String SERVER_TEMPLATE_PARAM = "serverTemplate"; @Inject KieServerQueryClient queryClient; @Inject KieServerConnectionInfoProvider connectionInfoProvider; @Override public String exec(Map params) { String containerId = getRequiredParam(CONTAINERID_PARAM, params); String processId = getRequiredParam(PROCESSID_PARAM, params); Object serverTemplate = params.get(SERVER_TEMPLATE_PARAM); KieServerConnectionInfo connectionInfo; if (serverTemplate != null && !serverTemplate.toString().trim().isEmpty()) { connectionInfo = connectionInfoProvider.get(null, serverTemplate.toString()) .orElseThrow(() -> new RuntimeException("Configuration for server template not found " + serverTemplate)); } else { connectionInfo = connectionInfoProvider.getDefault() .orElseThrow(() -> new RuntimeException("Not able to find credentials to retrieve processes SVG")); } try { return queryClient.processSVG(connectionInfo, containerId, processId); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 404) { notFoundSVGError(containerId, processId); } errorRetrievingSVG(e); } catch (Exception e) { errorRetrievingSVG(e); } return null; } private void errorRetrievingSVG(Exception e) { String message = String.format(ERROR_REQUESTING_SVG, e.getMessage()); LOGGER.warn(message); LOGGER.debug(message, e); throw new RuntimeException(message, e); } private void notFoundSVGError(String containerId, String processId) { String notFoundMessage = String.format(NOT_FOUND_MSG, containerId, processId); LOGGER.warn(notFoundMessage); throw new RuntimeException(notFoundMessage); } private String getRequiredParam(String param, Map params) { Object value = params.get(param); if (value == null || value.toString().trim().isEmpty()) { throw new RuntimeException("Param '" + param + "' is required."); } return value.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/rest/BasicAuthFilter.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend.rest; import java.io.IOException; import java.nio.charset.StandardCharsets; import javax.ws.rs.client.ClientRequestContext; import javax.ws.rs.client.ClientRequestFilter; import javax.ws.rs.core.HttpHeaders; import org.jboss.resteasy.util.Base64; public class BasicAuthFilter implements ClientRequestFilter { private final String user; private final String password; public BasicAuthFilter(String user, String password) { this.user = user; this.password = password; } @Override public void filter(ClientRequestContext ctx) throws IOException { final String basicAuthToken = getEncodedToken(); ctx.getHeaders().add(HttpHeaders.AUTHORIZATION, basicAuthToken); } private String getEncodedToken() { String token = this.user + ":" + this.password; return "Basic " + Base64.encodeBytes(token.getBytes(StandardCharsets.UTF_8)); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/rest/KieServerQueryClient.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend.rest; import java.util.List; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import org.dashbuilder.kieserver.KieServerConnectionInfo; /** * Run queries on Kie Server using its REST API * */ @ApplicationScoped public class KieServerQueryClient { private static final String PROCESS_ID_PARAM = "processId"; private static final String CONTAINER_ID_PARAM = "containerId"; private static final String DEFAULT_REQUEST_MEDIA_TYPE = MediaType.APPLICATION_JSON; public static final String QUERY_MAP_RAW = "RawList"; public static final String QUERY_DEFINITION_URI = "queries/definitions/{id}"; public static final String QUERY_EXECUTION_URI = QUERY_DEFINITION_URI + "/filtered-data"; public static final String PROCESS_SVG_URI = "containers/{" + CONTAINER_ID_PARAM + "}/images/processes/{" + PROCESS_ID_PARAM + "}"; public QueryDefinition getQuery(KieServerConnectionInfo connectionInfo, String uuid) { Client client = ClientBuilder.newClient(); WebTarget target = requestForQueryDefinition(connectionInfo, uuid, client); QueryDefinition queryDefinition = target.request() .accept(DEFAULT_REQUEST_MEDIA_TYPE) .get(QueryDefinition.class); client.close(); return queryDefinition; } @SuppressWarnings({"rawtypes", "unchecked"}) public List query(KieServerConnectionInfo connectionInfo, String uuid, QueryFilterSpec filterSpec, int i, int numberOfRows) { Client client = ClientBuilder.newClient(); WebTarget target = client.target(connectionInfo.getLocation().get()) .path(QUERY_EXECUTION_URI) .resolveTemplate("id", uuid) .queryParam("mapper", QUERY_MAP_RAW) .queryParam("page", i) .queryParam("pageSize", numberOfRows); addAuth(connectionInfo, target); List response = target.request() .accept(DEFAULT_REQUEST_MEDIA_TYPE) .post(Entity.entity(filterSpec, DEFAULT_REQUEST_MEDIA_TYPE), List.class); client.close(); return response; } public QueryDefinition replaceQuery(KieServerConnectionInfo connectionInfo, QueryDefinition queryDefinition) { Client client = ClientBuilder.newClient(); WebTarget target = requestForQueryDefinition(connectionInfo, queryDefinition.getName(), client); QueryDefinition def = target.request() .accept(DEFAULT_REQUEST_MEDIA_TYPE) .put(Entity.entity(queryDefinition, DEFAULT_REQUEST_MEDIA_TYPE), QueryDefinition.class); client.close(); return def; } public void unregisterQuery(KieServerConnectionInfo connectionInfo, String dataSetUUID) { Client client = ClientBuilder.newClient(); WebTarget target = requestForQueryDefinition(connectionInfo, dataSetUUID, client); target.request().delete(); client.close(); } public String processSVG(KieServerConnectionInfo connectionInfo, String containerId, String processId) { Optional location = connectionInfo.getLocation(); if (location.isPresent()) { Client client = ClientBuilder.newClient(); WebTarget target = client.target(location.get()) .path(PROCESS_SVG_URI) .resolveTemplate(CONTAINER_ID_PARAM, containerId) .resolveTemplate(PROCESS_ID_PARAM, processId); addAuth(connectionInfo, target); String svg = target.request().get(String.class); client.close(); return svg; } throw new RuntimeException("Location for Kie Server is required. Check configuration."); } private WebTarget requestForQueryDefinition(KieServerConnectionInfo connectionInfo, String dataSetUUID, Client client) { WebTarget target = client.target(connectionInfo.getLocation().get()) .path(QUERY_DEFINITION_URI) .resolveTemplate("id", dataSetUUID); addAuth(connectionInfo, target); return target; } private void addAuth(KieServerConnectionInfo connectionInfo, WebTarget target) { if (connectionInfo.getUser().isPresent()) { String user = connectionInfo.getUser().get(); String password = connectionInfo.getPassword().orElse(""); target.register(new BasicAuthFilter(user, password)); } if (connectionInfo.getToken().isPresent()) { target.register(new TokenFilter(connectionInfo.getToken().get())); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/rest/QueryDefinition.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend.rest; import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "query-definition") public class QueryDefinition { @XmlElement(name = "query-name") private String name; @XmlElement(name = "query-source") private String source; @XmlElement(name = "query-expression") private String expression; @XmlElement(name = "query-target") private String target; @XmlElement(name = "query-columns") private Map columns; public QueryDefinition() { } public static Builder builder() { return new Builder(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } public String getExpression() { return expression; } public void setExpression(String expression) { this.expression = expression; } public String getTarget() { return target; } public void setTarget(String target) { this.target = target; } public Map getColumns() { return columns; } public void setColumns(Map columns) { this.columns = columns; } public static class Builder { private QueryDefinition definition = new QueryDefinition(); public QueryDefinition build() { return definition; } public Builder name(String name) { definition.setName(name); return this; } public Builder source(String source) { definition.setSource(source); return this; } public Builder expression(String expression) { definition.setExpression(expression); return this; } public Builder target(String target) { definition.setTarget(target); return this; } public Builder columns(Map columns) { definition.setColumns(columns); return this; } } @Override public String toString() { return "QueryDefinition{" + "name='" + name + '\'' + ", source='" + source + '\'' + ", expression='" + expression + '\'' + ", target='" + target + '\'' + '}'; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/rest/QueryFilterSpec.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend.rest; import java.util.Arrays; import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "query-filter-spec") public class QueryFilterSpec { @XmlElement(name = "order-by") private String orderBy; @XmlElement(name = "order-asc") private boolean ascending; @XmlElement(name = "query-params") private QueryParam[] parameters; @XmlElement(name = "result-column-mapping") private Map columnMapping; @XmlElement(name = "order-by-clause") private String orderByClause; public QueryFilterSpec() { } public String getOrderBy() { return orderBy; } public void setOrderBy(String orderBy) { this.orderBy = orderBy; } public boolean isAscending() { return ascending; } public void setAscending(boolean ascending) { this.ascending = ascending; } public QueryParam[] getParameters() { return parameters; } public void setParameters(QueryParam[] parameters) { this.parameters = parameters; } public Map getColumnMapping() { return columnMapping; } public void setColumnMapping(Map columnMapping) { this.columnMapping = columnMapping; } public String getOrderByClause() { return this.orderByClause; } public void setOrderByClause(String orderByClause) { this.orderByClause = orderByClause; } @Override public String toString() { return "QueryFilterSpec{" + "orderBy='" + orderBy + '\'' + ", ascending=" + ascending + ", parameters=" + Arrays.toString(parameters) + '}'; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/rest/QueryParam.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend.rest; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "query-param") public class QueryParam { @XmlElement(name = "cond-column") private String column; @XmlElement(name = "cond-operator") private String operator; @XmlElement(name = "cond-values") private List value; public QueryParam() { } public QueryParam(String column, String operator, List value) { this.column = column; this.operator = operator; this.value = value; } public String getColumn() { return column; } public void setColumn(String column) { this.column = column; } public String getOperator() { return operator; } public void setOperator(String operator) { this.operator = operator; } public List getValue() { return value; } public void setValue(List value) { this.value = value; } @Override public String toString() { return "QueryParam{" + ((column != null) ? "column='" + column + "\'," : "") + " operator='" + operator + '\'' + ", value=" + value + '}'; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/java/org/dashbuilder/kieserver/backend/rest/TokenFilter.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend.rest; import java.io.IOException; import javax.ws.rs.client.ClientRequestContext; import javax.ws.rs.client.ClientRequestFilter; public class TokenFilter implements ClientRequestFilter { private String token; public TokenFilter(String token) { this.token = token; } @Override public void filter(ClientRequestContext ctx) throws IOException { ctx.getHeaders().add("Bearer ", token); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/test/java/org/dashbuilder/kieserver/backend/KieServerConnectionInfoProviderImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend; import java.util.Arrays; import java.util.List; import java.util.Optional; import org.dashbuilder.kieserver.KieServerConnectionInfo; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.kieserver.backend.KieServerConnectionInfoProviderImpl.KieServerConfigurationKey; import org.junit.Before; import org.junit.Test; import static org.dashbuilder.kieserver.backend.KieServerConnectionInfoProviderImpl.DATASET_PROP_PREFFIX; import static org.dashbuilder.kieserver.backend.KieServerConnectionInfoProviderImpl.SERVER_TEMPLATE_PROP_PREFFIX; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class KieServerConnectionInfoProviderImplTest { private static final String SERVER_USER = "serveruser"; private static final String SERVER_PASSWORD = "serverpassword"; private static final String SERVER_TOKEN = "servertoken"; private static final String SERVER_LOCATION = "serverlocation"; private static final String DS_USER = "dsuser"; private static final String DS_PASSWORD = "dspassword"; private static final String DS_TOKEN = "dstoken"; private static final String DS_LOCATION = "dslocation"; private KieServerConnectionInfoProviderImpl kieServerConnectionInfoProvider; private final static String SERVER_ID = "server1"; private final static String DATASET_NAME = "ds1"; private final static String SERVER_TEMPLATE_PROP = SERVER_TEMPLATE_PROP_PREFFIX + "." + SERVER_ID + "."; private final static String DATASET_PROP = DATASET_PROP_PREFFIX + "." + DATASET_NAME + "."; private RemoteDataSetDef def; @Before public void init() { kieServerConnectionInfoProvider = new KieServerConnectionInfoProviderImpl(); def = new RemoteDataSetDef(); def.setName(DATASET_NAME); def.setServerTemplateId(SERVER_ID); clearProperties(); } @Test public void serverListTest() { System.setProperty(KieServerConnectionInfoProviderImpl.SERVER_TEMPLATE_LIST_PROPERTY, "server1, server2, server3"); List serverTemplates = kieServerConnectionInfoProvider.serverTemplates(); assertEquals(3, serverTemplates.size()); List expectedList = Arrays.asList("server1", "server2", "server3"); assertEquals(expectedList, serverTemplates); } @Test public void emptyServerListTest() { System.setProperty(KieServerConnectionInfoProviderImpl.SERVER_TEMPLATE_LIST_PROPERTY, ""); List serverTemplates = kieServerConnectionInfoProvider.serverTemplates(); assertTrue(serverTemplates.isEmpty()); } @Test(expected = RuntimeException.class) public void absentConfigurationErrorTest() { kieServerConnectionInfoProvider.verifiedConnectionInfo(def); } @Test(expected = RuntimeException.class) public void testServerMissingAuth() { setServerProp(KieServerConfigurationKey.LOCATION, "somelocation"); kieServerConnectionInfoProvider.verifiedConnectionInfo(def); } @Test(expected = RuntimeException.class) public void testDataSetMissingAuth() { setDataSetProp(KieServerConfigurationKey.LOCATION, "somelocation"); kieServerConnectionInfoProvider.verifiedConnectionInfo(def); } @Test public void testDsPropsPrecedence() { setDataSetProp(KieServerConfigurationKey.LOCATION, DS_LOCATION); setDataSetProp(KieServerConfigurationKey.USER, DS_USER); setDataSetProp(KieServerConfigurationKey.PASSWORD, DS_PASSWORD); setServerProp(KieServerConfigurationKey.LOCATION, SERVER_LOCATION); setServerProp(KieServerConfigurationKey.USER, SERVER_USER); setServerProp(KieServerConfigurationKey.PASSWORD, SERVER_PASSWORD); KieServerConnectionInfo connectionInfo = kieServerConnectionInfoProvider.verifiedConnectionInfo(def); assertEquals(DS_LOCATION, connectionInfo.getLocation().get()); assertEquals(DS_USER, connectionInfo.getUser().get()); assertEquals(DS_PASSWORD, connectionInfo.getPassword().get()); assertFalse(connectionInfo.isReplaceQuery()); } @Test public void testServerTemplateProps() { setServerProp(KieServerConfigurationKey.LOCATION, SERVER_LOCATION); setServerProp(KieServerConfigurationKey.USER, SERVER_USER); setServerProp(KieServerConfigurationKey.PASSWORD, SERVER_PASSWORD); KieServerConnectionInfo connectionInfo = kieServerConnectionInfoProvider.verifiedConnectionInfo(def); assertEquals(SERVER_LOCATION, connectionInfo.getLocation().get()); assertEquals(SERVER_USER, connectionInfo.getUser().get()); assertEquals(SERVER_PASSWORD, connectionInfo.getPassword().get()); assertFalse(connectionInfo.isReplaceQuery()); } @Test public void testDsTokenPropPrecedence() { setDataSetProp(KieServerConfigurationKey.LOCATION, DS_LOCATION); setDataSetProp(KieServerConfigurationKey.TOKEN, DS_TOKEN); setServerProp(KieServerConfigurationKey.LOCATION, SERVER_LOCATION); setServerProp(KieServerConfigurationKey.TOKEN, SERVER_TOKEN); KieServerConnectionInfo connectionInfo = kieServerConnectionInfoProvider.verifiedConnectionInfo(def); assertEquals(DS_LOCATION, connectionInfo.getLocation().get()); assertEquals(DS_TOKEN, connectionInfo.getToken().get()); } @Test public void testServerToken() { setServerProp(KieServerConfigurationKey.LOCATION, SERVER_LOCATION); setServerProp(KieServerConfigurationKey.TOKEN, SERVER_TOKEN); KieServerConnectionInfo connectionInfo = kieServerConnectionInfoProvider.verifiedConnectionInfo(def); assertEquals(SERVER_LOCATION, connectionInfo.getLocation().get()); assertEquals(SERVER_TOKEN, connectionInfo.getToken().get()); } @Test public void testReplaceQuery() { setServerProp(KieServerConfigurationKey.LOCATION, SERVER_LOCATION); setServerProp(KieServerConfigurationKey.USER, SERVER_USER); setServerProp(KieServerConfigurationKey.PASSWORD, SERVER_PASSWORD); setServerProp(KieServerConfigurationKey.REPLACE_QUERY, "True"); KieServerConnectionInfo connectionInfo = kieServerConnectionInfoProvider.verifiedConnectionInfo(def); assertTrue(connectionInfo.isReplaceQuery()); } @Test public void testReplaceQueryFalse() { setServerProp(KieServerConfigurationKey.LOCATION, SERVER_LOCATION); setServerProp(KieServerConfigurationKey.USER, SERVER_USER); setServerProp(KieServerConfigurationKey.PASSWORD, SERVER_PASSWORD); setServerProp(KieServerConfigurationKey.REPLACE_QUERY, "false"); KieServerConnectionInfo connectionInfo = kieServerConnectionInfoProvider.verifiedConnectionInfo(def); assertFalse(connectionInfo.isReplaceQuery()); } @Test public void testRetrieveServerTemplateId() { String serverTemplate = kieServerConnectionInfoProvider.retrieveTemplateId(SERVER_TEMPLATE_PROP_PREFFIX + ".myServerTemplate.url"); assertEquals("myServerTemplate", serverTemplate); } @Test public void testRetrieveServerTemplateIdBadString() { String serverTemplate = kieServerConnectionInfoProvider.retrieveTemplateId("test"); assertNull(serverTemplate); } @Test public void testFindFirstServerTemplateConf() { setServerProp(KieServerConfigurationKey.LOCATION, SERVER_LOCATION); setServerProp(KieServerConfigurationKey.USER, SERVER_USER); setServerProp(KieServerConfigurationKey.PASSWORD, SERVER_PASSWORD); Optional conf = kieServerConnectionInfoProvider.findFirstServerTemplateConf(); assertTrue(conf.isPresent()); } @Test public void testFindFirstServerTemplateConfNotFound() { clearProperties(); Optional conf = kieServerConnectionInfoProvider.findFirstServerTemplateConf(); assertFalse(conf.isPresent()); } private void setDataSetProp(KieServerConfigurationKey key, String value) { System.setProperty(DATASET_PROP + key.getValue(), value); } private void setServerProp(KieServerConfigurationKey key, String value) { System.setProperty(SERVER_TEMPLATE_PROP + key.getValue(), value); } private void clearProperties() { System.setProperty(KieServerConnectionInfoProviderImpl.SERVER_TEMPLATE_LIST_PROPERTY, ""); for (KieServerConfigurationKey key : KieServerConfigurationKey.values()) { System.clearProperty(DATASET_PROP + key.getValue()); System.clearProperty(SERVER_TEMPLATE_PROP + key.getValue()); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-kie-server-backend/src/test/java/org/dashbuilder/kieserver/backend/RuntimeKieServerDataSetProviderTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver.backend; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.dataset.group.GroupStrategy; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.impl.DataSetImpl; import org.dashbuilder.kieserver.ConsoleDataSetLookup; import org.dashbuilder.kieserver.KieServerConnectionInfo; import org.dashbuilder.kieserver.KieServerConnectionInfoProvider; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.kieserver.backend.rest.KieServerQueryClient; import org.dashbuilder.kieserver.backend.rest.QueryDefinition; import org.dashbuilder.kieserver.backend.rest.QueryFilterSpec; import org.dashbuilder.kieserver.backend.rest.QueryParam; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.filter.FilterFactory.OR; import static org.dashbuilder.dataset.filter.FilterFactory.likeTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.Silent.class) public class RuntimeKieServerDataSetProviderTest { private static final String SERVER_TEMPLATE = "serverTemplate"; public static String COLUMN_TEST = "columTest"; @InjectMocks RuntimeKieServerDataSetProvider kieServerDataSetProvider; @Mock KieServerQueryClient queryClient; @Mock DataSetImpl dataSet; @Mock KieServerConnectionInfoProvider kieServerConnectionInfoProvider; @Mock RemoteDataSetDef dataSetDef; private KieServerConnectionInfo connectionInfo; private KieServerConnectionInfo connectionInfoWithQueryReplace; private QueryDefinition definition; @Before public void setUp() { connectionInfo = new KieServerConnectionInfo(Optional.of("location"), Optional.of("user"), Optional.of("password"), Optional.of("token"), false); connectionInfoWithQueryReplace = new KieServerConnectionInfo(Optional.of("location"), Optional.of("user"), Optional.of("password"), Optional.of("token"), true); Map columns = new HashMap<>(); columns.put("test", "NUMBER"); definition = QueryDefinition.builder() .name("q1") .columns(columns) .build(); } @Test public void appendEqualToIntervalSelectionTest() { String filterValue = "testValue"; DataSetGroup dataSetGroup = new DataSetGroup(); dataSetGroup.setColumnGroup(new ColumnGroup(COLUMN_TEST, COLUMN_TEST, GroupStrategy.DYNAMIC)); List intervalList = new ArrayList(); Interval interval = new Interval(filterValue); intervalList.add(interval); dataSetGroup.setSelectedIntervalList(intervalList); List filterParams = new ArrayList<>(); kieServerDataSetProvider.appendIntervalSelection(dataSetGroup, filterParams); assertEquals(1, filterParams.size()); assertEquals(COLUMN_TEST, filterParams.get(0).getColumn()); assertEquals("EQUALS_TO", filterParams.get(0).getOperator()); assertEquals(filterValue, filterParams.get(0).getValue().get(0)); } @Test public void appendBetweenIntervalSelectionTest() { String filterValue = "testValue"; Long minValue = Long.valueOf(0); Long maxValue = Long.valueOf(2); DataSetGroup dataSetGroup = new DataSetGroup(); dataSetGroup.setColumnGroup(new ColumnGroup(COLUMN_TEST, COLUMN_TEST, GroupStrategy.DYNAMIC)); List intervalList = new ArrayList(); Interval interval = new Interval(filterValue); interval.setMinValue(minValue); interval.setMaxValue(maxValue); intervalList.add(interval); dataSetGroup.setSelectedIntervalList(intervalList); List filterParams = new ArrayList<>(); kieServerDataSetProvider.appendIntervalSelection(dataSetGroup, filterParams); assertEquals(1, filterParams.size()); assertEquals(COLUMN_TEST, filterParams.get(0).getColumn()); assertEquals("BETWEEN", filterParams.get(0).getOperator()); assertEquals(Double.valueOf(minValue), filterParams.get(0).getValue().get(0)); assertEquals(Double.valueOf(maxValue), filterParams.get(0).getValue().get(1)); } @Test public void lookupDataSetLogicalExprTest() throws Exception { DataSetLookup lookup = new DataSetLookup(); lookup.setDataSetUUID(""); when(dataSetDef.getUUID()).thenReturn(""); when(kieServerConnectionInfoProvider.verifiedConnectionInfo(dataSetDef)).thenReturn(connectionInfo); final ColumnFilter testFilter = OR(likeTo("column1", "%value%"), likeTo("column2", "%value%")); DataSetFilter filter = new DataSetFilter(); filter.addFilterColumn(testFilter); lookup.addOperation(filter); when(queryClient.getQuery(eq(connectionInfo), any())).thenReturn(definition); kieServerDataSetProvider.lookupDataSet(dataSetDef, ConsoleDataSetLookup.fromInstance(lookup, SERVER_TEMPLATE)); final ArgumentCaptor captorEdit = ArgumentCaptor.forClass(QueryFilterSpec.class); verify(queryClient).query(eq(connectionInfo), any(), captorEdit.capture(), anyInt(), anyInt()); assertNotNull(captorEdit.getValue()); QueryParam[] parameters = captorEdit.getValue().getParameters(); assertEquals(1, parameters.length); List expr = (List) parameters[0].getValue(); assertEquals("OR", parameters[0].getOperator()); assertEquals("column1 like %value%, true", expr.get(0).toString()); assertEquals("column2 like %value%, true", expr.get(1).toString()); } @Test public void testGroupWithInterval() { DataSetGroup dataSetGroup = new DataSetGroup(); dataSetGroup.setColumnGroup(new ColumnGroup(COLUMN_TEST, COLUMN_TEST, GroupStrategy.DYNAMIC, 30, DateIntervalType.DAY.name())); List filterParams = new ArrayList<>(); List extraColumns = new ArrayList<>(); kieServerDataSetProvider.handleDataSetGroup(dataSetDef, dataSetGroup, filterParams, extraColumns); assertEquals(1, filterParams.size()); assertEquals(COLUMN_TEST, filterParams.get(0).getColumn()); assertEquals("group", filterParams.get(0).getOperator()); assertEquals(3, filterParams.get(0).getValue().size()); assertEquals(COLUMN_TEST, filterParams.get(0).getValue().get(0)); assertEquals(DateIntervalType.DAY.name(), filterParams.get(0).getValue().get(1)); assertEquals(30, filterParams.get(0).getValue().get(2)); } @Test public void testGroupWithNotSetInterval() { DataSetGroup dataSetGroup = new DataSetGroup(); dataSetGroup.setColumnGroup(new ColumnGroup(COLUMN_TEST, COLUMN_TEST, GroupStrategy.DYNAMIC)); List filterParams = new ArrayList<>(); List extraColumns = new ArrayList<>(); kieServerDataSetProvider.handleDataSetGroup(dataSetDef, dataSetGroup, filterParams, extraColumns); assertEquals(1, filterParams.size()); assertEquals(COLUMN_TEST, filterParams.get(0).getColumn()); assertEquals("group", filterParams.get(0).getOperator()); assertEquals(1, filterParams.get(0).getValue().size()); assertEquals(COLUMN_TEST, filterParams.get(0).getValue().get(0)); } @Test public void testPerformQueryTestMode() { QueryFilterSpec filterSpec = new QueryFilterSpec(); ConsoleDataSetLookup dataSetLookup = Mockito.mock(ConsoleDataSetLookup.class); when(dataSetLookup.testMode()).thenReturn(true); when(dataSetLookup.getNumberOfRows()).thenReturn(10); when(dataSetLookup.getRowOffset()).thenReturn(1); when(dataSetLookup.getDataSetUUID()).thenReturn(""); when(kieServerConnectionInfoProvider.verifiedConnectionInfo(dataSetDef)).thenReturn(connectionInfo); when(queryClient.replaceQuery(eq(connectionInfo), any())).thenReturn(definition); kieServerDataSetProvider.performQuery(dataSetDef, dataSetLookup, filterSpec); verify(dataSetLookup, times(1)).testMode(); verify(queryClient).replaceQuery(eq(connectionInfo), any()); verify(queryClient).query(eq(connectionInfo), any(), any(QueryFilterSpec.class), anyInt(), anyInt()); } @Test public void testPerformQueryWithReplace() { QueryFilterSpec filterSpec = new QueryFilterSpec(); ConsoleDataSetLookup dataSetLookup = Mockito.mock(ConsoleDataSetLookup.class); when(dataSetLookup.testMode()).thenReturn(true); when(dataSetLookup.getNumberOfRows()).thenReturn(10); when(dataSetLookup.getRowOffset()).thenReturn(1); when(dataSetLookup.getDataSetUUID()).thenReturn(""); when(kieServerConnectionInfoProvider.verifiedConnectionInfo(dataSetDef)).thenReturn(connectionInfoWithQueryReplace); when(queryClient.replaceQuery(eq(connectionInfoWithQueryReplace), any())).thenReturn(definition); kieServerDataSetProvider.performQuery(dataSetDef, dataSetLookup, filterSpec); verify(dataSetLookup, times(1)).testMode(); verify(queryClient).replaceQuery(eq(connectionInfoWithQueryReplace), any()); verify(queryClient).query(eq(connectionInfoWithQueryReplace), any(), any(QueryFilterSpec.class), anyInt(), anyInt()); } @Test public void testPerformQueryRegularMode() { QueryFilterSpec filterSpec = new QueryFilterSpec(); ConsoleDataSetLookup dataSetLookup = Mockito.mock(ConsoleDataSetLookup.class); when(dataSetLookup.testMode()).thenReturn(false); when(dataSetLookup.getNumberOfRows()).thenReturn(10); when(dataSetLookup.getRowOffset()).thenReturn(1); when(dataSetLookup.getDataSetUUID()).thenReturn(""); when(queryClient.getQuery(eq(connectionInfo), any())).thenReturn(definition); when(kieServerConnectionInfoProvider.verifiedConnectionInfo(dataSetDef)).thenReturn(connectionInfo); kieServerDataSetProvider.performQuery(dataSetDef, dataSetLookup, filterSpec); verify(dataSetLookup, times(1)).testMode(); verify(queryClient, times(0)).replaceQuery(eq(connectionInfo), any()); verify(queryClient).query(eq(connectionInfo), any(), any(QueryFilterSpec.class), anyInt(), anyInt()); } @Test public void testDataSetMetaData() throws Exception { when(kieServerConnectionInfoProvider.verifiedConnectionInfo(dataSetDef)).thenReturn(connectionInfo); when(dataSetDef.getColumns()).thenReturn(null, new ArrayList<>()); when(queryClient.getQuery(eq(connectionInfo), any())).thenReturn(definition); kieServerDataSetProvider.getDataSetMetadata(dataSetDef); verify(dataSetDef, times(1)).addColumn(eq("test"), eq(ColumnType.NUMBER)); verify(queryClient).getQuery(eq(connectionInfo), any()); } @Test public void testNoAdoptLookup() throws Exception { ConsoleDataSetLookup dataSetLookup = Mockito.mock(ConsoleDataSetLookup.class); kieServerDataSetProvider.adoptLookup(dataSetDef, dataSetLookup); verify(dataSetDef, times(0)).getServerTemplateId(); } @Test public void testAdoptLookup() throws Exception { DataSetLookup dataSetLookup = Mockito.mock(DataSetLookup.class); when(dataSetDef.getDataSetFilter()).thenReturn(Mockito.mock(DataSetFilter.class)); when(dataSetDef.getServerTemplateId()).thenReturn("servereTemplateId"); ConsoleDataSetLookup adopted = kieServerDataSetProvider.adoptLookup(dataSetDef, dataSetLookup); verify(dataSetDef, times(1)).getServerTemplateId(); assertNotNull(adopted.getOperationList()); assertEquals(1, adopted.getOperationList().size()); } @Test public void testGroupFunctionColumnType() { for (ColumnType type : ColumnType.values()) { assertGroupFuntionColumnType(type, type == ColumnType.DATE ? ColumnType.LABEL : type); } } protected void assertGroupFuntionColumnType(final ColumnType source, final ColumnType expected) { final DataSetDef def = new DataSetDef(); def.addColumn("columnId", source); final ColumnGroup columnGroup = new ColumnGroup("sourceId", "columnId"); final GroupFunction groupFunction = new GroupFunction("sourceId", "columnId", null); assertEquals(expected, kieServerDataSetProvider.getGroupFunctionColumnType(def, columnGroup, groupFunction)); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-navigation-backend/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-backend 7.75.0-SNAPSHOT dashbuilder-navigation-backend jar Dashbuilder Navigation Backend org.dashbuilder dashbuilder-navigation-api org.kie.soup kie-soup-json org.slf4j slf4j-api org.jboss.errai errai-bus org.jboss.errai errai-config org.jboss.errai errai-security-server jakarta.enterprise jakarta.enterprise.cdi-api jakarta.servlet jakarta.servlet-api provided org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-nio2-api org.uberfire uberfire-nio2-model org.uberfire uberfire-backend-api org.uberfire uberfire-backend-server org.uberfire uberfire-api org.uberfire uberfire-io org.uberfire uberfire-runtime-plugins-api org.uberfire uberfire-runtime-plugins-backend org.uberfire uberfire-layout-editor-api org.uberfire uberfire-layout-editor-backend ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-navigation-backend/src/main/java/org/dashbuilder/navigation/service/LayoutTemplateAnalyzer.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.service; import java.util.Arrays; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.layout.LayoutNavigationRef; import org.dashbuilder.navigation.layout.LayoutNavigationRefType; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.layout.NavDragComponentType; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.uberfire.ext.layout.editor.api.editor.LayoutColumn; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.dashbuilder.navigation.layout.LayoutNavigationRefType.*; import static org.dashbuilder.navigation.layout.NavDragComponentSettings.*; import static org.dashbuilder.navigation.layout.NavDragComponentType.*; @ApplicationScoped public class LayoutTemplateAnalyzer { static final List ALL_NAV_GROUP_COMPONENTS = Arrays.asList(CAROUSEL, MENUBAR, TABLIST, TREE, TILES); static final List SHOW_ENTIRE_NAV_GROUP_COMPONENTS = Arrays.asList(CAROUSEL); static final List DEFAULT_ITEM_NAV_GROUP_COMPONENTS = Arrays.asList(MENUBAR, TABLIST, TREE); private PerspectivePluginServicesImpl pluginServices; private NavigationServicesImpl navigationServices; public LayoutTemplateAnalyzer() { } @Inject public LayoutTemplateAnalyzer(PerspectivePluginServicesImpl pluginServices, NavigationServicesImpl navigationServices) { this.pluginServices = pluginServices; this.navigationServices = navigationServices; } public LayoutRecursionIssue analyzeRecursion(LayoutTemplate layoutTemplate) { return analyzeRecursion(layoutTemplate, null); } public LayoutRecursionIssue analyzeRecursion(LayoutTemplate layoutTemplate, LayoutTemplateContext layoutCtx) { LayoutRecursionIssue info = new LayoutRecursionIssue(); info.push(new LayoutNavigationRef(PERSPECTIVE, layoutTemplate.getName())); boolean hasIssue = analyzeRecursion(layoutTemplate, info, layoutCtx); if (!hasIssue) { info.pop(); } return info; } public boolean analyzeRecursion(LayoutTemplate layoutTemplate, LayoutRecursionIssue issue, LayoutTemplateContext layoutCtx) { for (LayoutRow row : layoutTemplate.getRows()) { boolean hasIssue = analyzeRecursion(row, issue, layoutCtx); if (hasIssue) { return true; } } return false; } public boolean analyzeRecursion(LayoutRow row, LayoutRecursionIssue issue, LayoutTemplateContext layoutCtx) { NavTree navTree = navigationServices.loadNavTree(); for (LayoutColumn column : row.getLayoutColumns()) { for (LayoutComponent component : column.getLayoutComponents()) { issue.push(new LayoutNavigationRef(NAV_COMPONENT, component.getDragTypeName())); // Components pointing to a perspective can cause an infinite recursion issue String perspectiveId = component.getProperties().get(PERSPECTIVE_ID); if (perspectiveId != null) { boolean hasIssue = analyzeRecursion(perspectiveId, issue); if (hasIssue) { return true; } } // Get the nav group the component is tied to String navGroupId = component.getProperties().get(NAV_GROUP_ID); String navDefaultId = component.getProperties().get(NAV_DEFAULT_ID); LayoutNavigationRefType navGroupRefType = NAV_GROUP_DEFINED; if (layoutCtx != null && layoutCtx.getNavGroupId() != null) { navGroupId = layoutCtx.getNavGroupId(); navDefaultId = null; navGroupRefType = NAV_GROUP_CONTEXT; } else { LayoutNavigationRef lastDefaultItemRef = issue.getLastDefaultItemRef(); if (lastDefaultItemRef != null) { NavItem lastDefaultItem = navTree.getItemById(lastDefaultItemRef.getName()); String lastDefaultGroupId = NavWorkbenchCtx.get(lastDefaultItem).getNavGroupId(); if (lastDefaultGroupId != null) { navGroupId = lastDefaultGroupId; navDefaultId = null; navGroupRefType = NAV_GROUP_CONTEXT; } } } NavGroup navGroup = navTree != null ? (NavGroup) navTree.getItemById(navGroupId) : null; if (navGroup != null) { // The configured default item can cause an infinite recursion issue if (navDefaultId != null) { issue.push(new LayoutNavigationRef(navGroupRefType, navGroup.getId())); issue.push(new LayoutNavigationRef(DEFAULT_ITEM_DEFINED, navDefaultId)); NavItem defaultItem = navTree.getItemById(navDefaultId); NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(defaultItem); perspectiveId = navCtx.getResourceId(); boolean hasIssue = analyzeRecursion(perspectiveId, issue); if (hasIssue) { return true; } else { issue.pop(); issue.pop(); } } // For some components the first available item is taken when there is no default item set else if (hasDefaultItem(component)) { NavItem firstItem = getFirstRuntimePerspective(navGroup.getChildren()); if (firstItem != null) { issue.push(new LayoutNavigationRef(navGroupRefType, navGroup.getId())); issue.push(new LayoutNavigationRef(DEFAULT_ITEM_FOUND, firstItem.getId())); perspectiveId = NavWorkbenchCtx.get(firstItem).getResourceId(); boolean hasIssue = analyzeRecursion(perspectiveId, issue); if (hasIssue) { return true; } else { issue.pop(); issue.pop(); } } } // Any layout component linked to a nav group can potentially lead to an infinite recursion issue. boolean showAtOnce = showEntireNavGroup(component); if (navGroupId != null && showAtOnce) { boolean hasIssue = analyzeRecursion(navGroup, navGroupRefType, issue); if (hasIssue) { return true; } } } issue.pop(); } for (LayoutRow childRow : column.getRows()) { boolean hasIssue = analyzeRecursion(childRow, issue, layoutCtx); if (hasIssue) { return true; } } } return false; } public boolean analyzeRecursion(NavGroup navGroup, LayoutNavigationRefType navGroupRefType, LayoutRecursionIssue issue) { if (navGroup == null) { return false; } issue.push(new LayoutNavigationRef(navGroupRefType, navGroup.getId())); for (NavItem navItem : navGroup.getChildren()) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); String perspectiveId = navCtx.getResourceId(); boolean hasIssue = analyzeRecursion(perspectiveId, issue); if (hasIssue) { return true; } } issue.pop(); return false; } public boolean analyzeRecursion(String perspectiveId, LayoutRecursionIssue issue) { LayoutTemplate layoutTemplate = pluginServices.getLayoutTemplate(perspectiveId); if (layoutTemplate != null) { // An infinite recursion occurs either when the perspective is linked to an already // traversed perspective or when the layout itself is causing so. LayoutNavigationRef perspectiveRef = new LayoutNavigationRef(PERSPECTIVE, perspectiveId); if (issue.contains(perspectiveRef)) { issue.push(new LayoutNavigationRef(PERSPECTIVE, perspectiveId)); return true; } else { issue.push(new LayoutNavigationRef(PERSPECTIVE, perspectiveId)); boolean hasIssue = analyzeRecursion(layoutTemplate, issue, null); if (hasIssue) { return true; } else { issue.pop(); } } } return false; } public boolean hasNavigationComponents(LayoutTemplate layoutTemplate) { for (LayoutRow row : layoutTemplate.getRows()) { boolean hasNavComps = hasNavigationComponents(row); if (hasNavComps) { return true; } } return false; } public boolean hasNavigationComponents(LayoutRow row) { for (LayoutColumn column : row.getLayoutColumns()) { for (LayoutComponent component : column.getLayoutComponents()) { NavDragComponentType dragType = NavDragComponentType.getByClassName(component.getDragTypeName()); if (dragType != null && ALL_NAV_GROUP_COMPONENTS.contains(dragType)) { return true; } } for (LayoutRow childRow : column.getRows()) { boolean hasNavComps = hasNavigationComponents(childRow); if (hasNavComps) { return true; } } } return false; } protected boolean showEntireNavGroup(LayoutComponent component) { NavDragComponentType dragType = NavDragComponentType.getByClassName(component.getDragTypeName()); return dragType != null && SHOW_ENTIRE_NAV_GROUP_COMPONENTS.contains(dragType); } protected boolean hasDefaultItem(LayoutComponent component) { NavDragComponentType dragType = NavDragComponentType.getByClassName(component.getDragTypeName()); return dragType != null && DEFAULT_ITEM_NAV_GROUP_COMPONENTS.contains(dragType); } protected boolean isRuntimePerspectiveId(NavItem navItem) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); String perspectiveId = navCtx.getResourceId(); return pluginServices.getLayoutTemplate(perspectiveId) != null; } protected NavItem getFirstRuntimePerspective(List itemList) { if (itemList.isEmpty()) { return null; } for (NavItem navItem : itemList) { if (isRuntimePerspectiveId(navItem)) { return navItem; } if (navItem instanceof NavGroup) { NavItem result = getFirstRuntimePerspective(((NavGroup) navItem).getChildren()); if (result != null) { return result; } } } return null; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-navigation-backend/src/main/java/org/dashbuilder/navigation/service/NavigationServicesImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.service; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.storage.NavTreeStorage; import org.jboss.errai.bus.server.annotations.Service; @ApplicationScoped @Service public class NavigationServicesImpl implements NavigationServices { private NavTreeStorage storage; public NavigationServicesImpl() { } @Inject public NavigationServicesImpl(NavTreeStorage storage) { this.storage = storage; } @Override public NavTree loadNavTree() { return storage.loadNavTree(); } @Override public void saveNavTree(NavTree navTree) { storage.saveNavTree(navTree); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-navigation-backend/src/main/java/org/dashbuilder/navigation/service/PerspectivePluginServicesImpl.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.service; import java.util.Collection; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.layout.LayoutTemplateInfo; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.layout.editor.impl.LayoutServicesImpl; import org.uberfire.ext.plugin.backend.PluginServicesImpl; import org.uberfire.ext.plugin.model.LayoutEditorModel; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.ext.plugin.model.PluginType; @ApplicationScoped @Service public class PerspectivePluginServicesImpl implements PerspectivePluginServices { private PluginServicesImpl pluginServices; private LayoutServicesImpl layoutServices; private LayoutTemplateAnalyzer layoutTemplateAnalyzer; public PerspectivePluginServicesImpl() { } @Inject public PerspectivePluginServicesImpl(PluginServicesImpl pluginServices, LayoutServicesImpl layoutServices, LayoutTemplateAnalyzer layoutTemplateAnalyzer) { this.pluginServices = pluginServices; this.layoutServices = layoutServices; this.layoutTemplateAnalyzer = layoutTemplateAnalyzer; } @Override public Collection listPlugins() { return pluginServices.listPlugins(PluginType.PERSPECTIVE_LAYOUT); } @Override public Plugin getPerspectivePlugin(String perspectiveName) { if (perspectiveName == null) { return null; } for (Plugin plugin : listPlugins()) { if (PluginType.PERSPECTIVE_LAYOUT.equals(plugin.getType()) && plugin.getName().equals(perspectiveName)) { return plugin; } } return null; } @Override public LayoutTemplate getLayoutTemplate(String perspectiveName) { Plugin perspectivePlugin = getPerspectivePlugin(perspectiveName); return perspectivePlugin != null ? getLayoutTemplate(perspectivePlugin) : null; } @Override public LayoutTemplateInfo getLayoutTemplateInfo(String perspectiveName) { LayoutTemplate layoutTemplate = getLayoutTemplate(perspectiveName); return layoutTemplate != null ? getLayoutTemplateInfo(layoutTemplate) : null; } @Override public LayoutTemplate getLayoutTemplate(Plugin perspectivePlugin) { LayoutEditorModel layoutEditorModel = pluginServices.getLayoutEditor(perspectivePlugin.getPath(), PluginType.PERSPECTIVE_LAYOUT); return layoutServices.convertLayoutFromString(layoutEditorModel.getLayoutEditorModel()); } @Override public LayoutTemplateInfo getLayoutTemplateInfo(Plugin perspectivePlugin, LayoutTemplateContext layoutCtx) { LayoutTemplate layoutTemplate = getLayoutTemplate(perspectivePlugin); LayoutRecursionIssue recursiveIssue = layoutTemplateAnalyzer.analyzeRecursion(layoutTemplate, layoutCtx); boolean hasNavComps = layoutTemplateAnalyzer.hasNavigationComponents(layoutTemplate); return new LayoutTemplateInfo(layoutTemplate, hasNavComps, recursiveIssue); } @Override public LayoutTemplateInfo getLayoutTemplateInfo(LayoutTemplate layoutTemplate) { LayoutRecursionIssue recursiveIssue = layoutTemplateAnalyzer.analyzeRecursion(layoutTemplate); boolean hasNavComps = layoutTemplateAnalyzer.hasNavigationComponents(layoutTemplate); return new LayoutTemplateInfo(layoutTemplate, hasNavComps, recursiveIssue); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-navigation-backend/src/main/java/org/dashbuilder/navigation/storage/NavTreeStorage.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.storage; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.json.NavTreeJSONMarshaller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Path; @ApplicationScoped public class NavTreeStorage { public static final String NAV_TREE_FILE_NAME = "navtree.json"; private IOService ioService; private NavTreeJSONMarshaller jsonMarshaller; private Path root; private Logger log = LoggerFactory.getLogger(NavTreeStorage.class); private FileSystem fileSystem; public NavTreeStorage() { } @Inject public NavTreeStorage(@Named("ioStrategy") IOService ioService, @Named("navigationFS") FileSystem fileSystem) { this.ioService = ioService; this.fileSystem = fileSystem; this.jsonMarshaller = NavTreeJSONMarshaller.get(); } @PostConstruct public void init() { root = fileSystem.getRootDirectories().iterator().next(); } protected Path getNavRootPath() { return root.resolve("navigation"); } protected Path getNavTreePath() { return getNavRootPath().resolve(NAV_TREE_FILE_NAME); } public NavTree loadNavTree() { Path path = getNavTreePath(); if (!ioService.exists(path)) { return null; } try { String json = ioService.readAllString(path); return jsonMarshaller.fromJson(json); } catch (Exception e) { log.error("Error parsing json definition: " + path.getFileName(), e); return null; } } public void saveNavTree(NavTree navTree) { ioService.startBatch(fileSystem); try { String json = jsonMarshaller.toJson(navTree).toString(); Path path = getNavTreePath(); ioService.write(path, json); } catch (Exception e) { log.error("Can't save the navigation tree.", e); } finally { ioService.endBatch(); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-navigation-backend/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-navigation-backend/src/test/java/org/dashbuilder/navigation/service/LayoutTemplateAnalyzerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.service; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.layout.LayoutNavigationRef; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.ext.layout.editor.api.editor.LayoutColumn; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.dashbuilder.navigation.layout.LayoutNavigationRefType.*; import static org.dashbuilder.navigation.layout.NavDragComponentSettings.*; import static org.dashbuilder.navigation.layout.NavDragComponentType.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class LayoutTemplateAnalyzerTest { @Mock PerspectivePluginServicesImpl pluginServices; @Mock NavigationServicesImpl navigationServices; @InjectMocks LayoutTemplateAnalyzer layoutTemplateAnalyzer; LayoutTemplate layoutA = new LayoutTemplate("A"); LayoutTemplate layoutB = new LayoutTemplate("B"); LayoutTemplate layoutC = new LayoutTemplate("C"); LayoutTemplate layoutD = new LayoutTemplate("D"); LayoutTemplate layoutE = new LayoutTemplate("D"); LayoutColumn layoutColumnA = new LayoutColumn("12"); LayoutColumn layoutColumnB = new LayoutColumn("12"); LayoutColumn layoutColumnD = new LayoutColumn("12"); LayoutComponent layoutComponentA = new LayoutComponent(CAROUSEL.getFQClassName()); LayoutComponent layoutComponentB = new LayoutComponent(CAROUSEL.getFQClassName()); LayoutComponent layoutComponentC1 = new LayoutComponent(TABLIST.getFQClassName()); LayoutComponent layoutComponentC2 = new LayoutComponent(TABLIST.getFQClassName()); LayoutComponent layoutComponentD = new LayoutComponent(TREE.getFQClassName()); LayoutComponent layoutComponentE = new LayoutComponent(); @Before public void setUp() throws Exception { LayoutRow layoutRowA = new LayoutRow(); layoutComponentA.addProperty(NAV_GROUP_ID, "groupA"); layoutRowA.add(layoutColumnA); layoutColumnA.add(layoutComponentA); layoutA.addRow(layoutRowA); LayoutRow layoutRowB = new LayoutRow(); layoutComponentB.addProperty(NAV_GROUP_ID, "groupB"); layoutRowB.add(layoutColumnB); layoutColumnB.add(layoutComponentB); layoutB.addRow(layoutRowB); LayoutRow layoutRowC = new LayoutRow(); LayoutColumn layoutColumnC1 = new LayoutColumn("6"); LayoutColumn layoutColumnC2 = new LayoutColumn("6"); layoutComponentC1.addProperty(NAV_GROUP_ID, "groupC"); layoutComponentC2.addProperty(NAV_GROUP_ID, "groupC"); layoutRowC.add(layoutColumnC1); layoutRowC.add(layoutColumnC2); layoutColumnC1.add(layoutComponentC1); layoutColumnC2.add(layoutComponentC2); layoutC.addRow(layoutRowC); LayoutRow layoutRowD = new LayoutRow(); layoutComponentD.addProperty(NAV_GROUP_ID, "groupD"); layoutRowD.add(layoutColumnD); layoutColumnD.add(layoutComponentD); layoutD.addRow(layoutRowD); LayoutRow layoutRowE = new LayoutRow(); LayoutColumn layoutColumnE = new LayoutColumn("12"); layoutRowE.add(layoutColumnE); layoutColumnE.add(layoutComponentE); layoutE.addRow(layoutRowE); when(pluginServices.getLayoutTemplate("A")).thenReturn(layoutA); when(pluginServices.getLayoutTemplate("B")).thenReturn(layoutB); when(pluginServices.getLayoutTemplate("C")).thenReturn(layoutC); when(pluginServices.getLayoutTemplate("D")).thenReturn(layoutD); } @Test public void testNavTreeNotDefined() throws Exception { when(navigationServices.loadNavTree()).thenReturn(null); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutA); assertTrue(info.isEmpty()); } @Test public void testOneLevelNoRecursiveIssue() throws Exception { when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupA", "", "", true) .item("layout", "", "", true, NavWorkbenchCtx.perspective("B")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutA); assertTrue(info.isEmpty()); } @Test public void testPerspectiveReuseNoRecursiveIssue() throws Exception { when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupC", "", "", true) .item("layout", "", "", true, NavWorkbenchCtx.perspective("B")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutC); assertTrue(info.isEmpty()); } @Test public void testSimpleRecursion() throws Exception { when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupA", "", "", true) .item("layout", "", "", true, NavWorkbenchCtx.perspective("A")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutA); assertEquals(info.getRefList().size(), 4); assertEquals(info.getRefList().get(0), new LayoutNavigationRef(PERSPECTIVE, "A")); assertEquals(info.getRefList().get(1), new LayoutNavigationRef(NAV_COMPONENT, CAROUSEL.getFQClassName())); assertEquals(info.getRefList().get(2), new LayoutNavigationRef(NAV_GROUP_DEFINED, "groupA")); assertEquals(info.getRefList().get(3), new LayoutNavigationRef(PERSPECTIVE, "A")); } @Test public void testPerspectiveComponent() throws Exception { LayoutComponent layoutComponentB = new LayoutComponent("PerspectiveDrag"); layoutComponentB.addProperty(PERSPECTIVE_ID, "B"); layoutColumnA.add(layoutComponentB); when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder().build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutA); assertTrue(info.isEmpty()); } @Test public void testPerspectiveRecursiveIssue() throws Exception { LayoutComponent layoutComponentB = new LayoutComponent("PerspectiveDrag"); layoutComponentB.addProperty(PERSPECTIVE_ID, "B"); layoutColumnA.add(layoutComponentB); LayoutComponent layoutComponentA = new LayoutComponent("PerspectiveDrag"); layoutComponentB.addProperty(PERSPECTIVE_ID, "A"); layoutColumnB.add(layoutComponentA); when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder().build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutA); assertEquals(info.getRefList().size(), 3); assertEquals(info.getRefList().get(0), new LayoutNavigationRef(PERSPECTIVE, "A")); assertEquals(info.getRefList().get(1), new LayoutNavigationRef(NAV_COMPONENT, "PerspectiveDrag")); assertEquals(info.getRefList().get(2), new LayoutNavigationRef(PERSPECTIVE, "A")); } @Test public void testIndirectRecursiveIssue() throws Exception { when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupA", "", "", true) .item("layout", "", "", true, NavWorkbenchCtx.perspective("B")) .endGroup() .group("groupB", "", "", true) .item("layout", "", "", true, NavWorkbenchCtx.perspective("A")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutA); assertEquals(info.getRefList().size(), 7); assertEquals(info.getRefList().get(0), new LayoutNavigationRef(PERSPECTIVE, "A")); assertEquals(info.getRefList().get(1), new LayoutNavigationRef(NAV_COMPONENT, CAROUSEL.getFQClassName())); assertEquals(info.getRefList().get(2), new LayoutNavigationRef(NAV_GROUP_DEFINED, "groupA")); assertEquals(info.getRefList().get(3), new LayoutNavigationRef(PERSPECTIVE, "B")); assertEquals(info.getRefList().get(4), new LayoutNavigationRef(NAV_COMPONENT, CAROUSEL.getFQClassName())); assertEquals(info.getRefList().get(5), new LayoutNavigationRef(NAV_GROUP_DEFINED, "groupB")); assertEquals(info.getRefList().get(6), new LayoutNavigationRef(PERSPECTIVE, "A")); } @Test public void testDefaultItemNoRecursiveIssue() throws Exception { layoutComponentC1.addProperty(NAV_DEFAULT_ID, "item2"); layoutComponentC2.addProperty(NAV_DEFAULT_ID, "item2"); when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupC", "", "", true) .item("item1", "", "", true, NavWorkbenchCtx.perspective("C")) .item("item2", "", "", true, NavWorkbenchCtx.perspective("B")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutC); assertTrue(info.isEmpty()); } @Test public void testIndirectNavGroupRecursiveIssue() throws Exception { layoutComponentC1.addProperty(NAV_DEFAULT_ID, "item2"); layoutComponentD.addProperty(NAV_DEFAULT_ID, "item4"); when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupC", "", "", true) .item("item1", "", "", true, NavWorkbenchCtx.perspective("A")) .item("item2", "", "", true, NavWorkbenchCtx.perspective("D").setNavGroupId("groupX")) .endGroup() .group("groupX", "", "", true) .item("item3", "", "", true, NavWorkbenchCtx.perspective("D").setNavGroupId("groupX")) .item("item4", "", "", true, NavWorkbenchCtx.perspective("A")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutC); assertEquals(info.getRefList().size(), 9); assertEquals(info.getRefList().get(0), new LayoutNavigationRef(PERSPECTIVE, "C")); assertEquals(info.getRefList().get(1), new LayoutNavigationRef(NAV_COMPONENT, TABLIST.getFQClassName())); assertEquals(info.getRefList().get(2), new LayoutNavigationRef(NAV_GROUP_DEFINED, "groupC")); assertEquals(info.getRefList().get(3), new LayoutNavigationRef(DEFAULT_ITEM_DEFINED, "item2")); assertEquals(info.getRefList().get(4), new LayoutNavigationRef(PERSPECTIVE, "D")); assertEquals(info.getRefList().get(5), new LayoutNavigationRef(NAV_COMPONENT, TREE.getFQClassName())); assertEquals(info.getRefList().get(6), new LayoutNavigationRef(NAV_GROUP_CONTEXT, "groupX")); assertEquals(info.getRefList().get(7), new LayoutNavigationRef(DEFAULT_ITEM_FOUND, "item3")); assertEquals(info.getRefList().get(8), new LayoutNavigationRef(PERSPECTIVE, "D")); } @Test public void testDefaultItemRecursiveIssue() throws Exception { layoutComponentC1.addProperty(NAV_DEFAULT_ID, "item1"); layoutComponentC2.addProperty(NAV_DEFAULT_ID, "item1"); when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupC", "", "", true) .item("item1", "", "", true, NavWorkbenchCtx.perspective("C")) .item("item2", "", "", true, NavWorkbenchCtx.perspective("B")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutC); assertEquals(info.getRefList().size(), 5); assertEquals(info.getRefList().get(0), new LayoutNavigationRef(PERSPECTIVE, "C")); assertEquals(info.getRefList().get(1), new LayoutNavigationRef(NAV_COMPONENT, TABLIST.getFQClassName())); assertEquals(info.getRefList().get(2), new LayoutNavigationRef(NAV_GROUP_DEFINED, "groupC")); assertEquals(info.getRefList().get(3), new LayoutNavigationRef(DEFAULT_ITEM_DEFINED, "item1")); assertEquals(info.getRefList().get(4), new LayoutNavigationRef(PERSPECTIVE, "C")); } @Test public void testFirstItemIndirectRecursiveIssue() throws Exception { when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupA", "", "", true) .item("itemA", "", "", true, NavWorkbenchCtx.perspective("C")) .endGroup() .group("groupC", "", "", true) .item("itemC", "", "", true, NavWorkbenchCtx.perspective("A")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutC); assertEquals(info.getRefList().size(), 8); assertEquals(info.getRefList().get(0), new LayoutNavigationRef(PERSPECTIVE, "C")); assertEquals(info.getRefList().get(1), new LayoutNavigationRef(NAV_COMPONENT, TABLIST.getFQClassName())); assertEquals(info.getRefList().get(2), new LayoutNavigationRef(NAV_GROUP_DEFINED, "groupC")); assertEquals(info.getRefList().get(3), new LayoutNavigationRef(DEFAULT_ITEM_FOUND, "itemC")); assertEquals(info.getRefList().get(4), new LayoutNavigationRef(PERSPECTIVE, "A")); assertEquals(info.getRefList().get(5), new LayoutNavigationRef(NAV_COMPONENT, CAROUSEL.getFQClassName())); assertEquals(info.getRefList().get(6), new LayoutNavigationRef(NAV_GROUP_DEFINED, "groupA")); assertEquals(info.getRefList().get(7), new LayoutNavigationRef(PERSPECTIVE, "C")); } @Test public void testNavGroupFromContext() throws Exception { when(navigationServices.loadNavTree()).thenReturn(new NavTreeBuilder() .group("groupC", "", "", true) .item("item1", "", "", true, NavWorkbenchCtx.perspective("A")) .endGroup() .group("groupX", "", "", true) .item("item2", "", "", true, NavWorkbenchCtx.perspective("C")) .endGroup() .build()); LayoutRecursionIssue info = layoutTemplateAnalyzer.analyzeRecursion(layoutC, new LayoutTemplateContext("groupX")); assertEquals(info.getRefList().size(), 5); assertEquals(info.getRefList().get(0), new LayoutNavigationRef(PERSPECTIVE, "C")); assertEquals(info.getRefList().get(1), new LayoutNavigationRef(NAV_COMPONENT, TABLIST.getFQClassName())); assertEquals(info.getRefList().get(2), new LayoutNavigationRef(NAV_GROUP_CONTEXT, "groupX")); assertEquals(info.getRefList().get(3), new LayoutNavigationRef(DEFAULT_ITEM_FOUND, "item2")); assertEquals(info.getRefList().get(4), new LayoutNavigationRef(PERSPECTIVE, "C")); } @Test public void testHasNavigationComponents() throws Exception { assertTrue(layoutTemplateAnalyzer.hasNavigationComponents(layoutA)); assertTrue(layoutTemplateAnalyzer.hasNavigationComponents(layoutB)); assertTrue(layoutTemplateAnalyzer.hasNavigationComponents(layoutC)); assertTrue(layoutTemplateAnalyzer.hasNavigationComponents(layoutD)); assertFalse(layoutTemplateAnalyzer.hasNavigationComponents(layoutE)); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-backend 7.75.0-SNAPSHOT dashbuilder-services jar Dashbuilder Services commons-io commons-io org.dashbuilder dashbuilder-services-api org.dashbuilder dashbuilder-dataset-cdi org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-dataset-core org.kie.soup kie-soup-dataset-sql org.dashbuilder dashbuilder-navigation-api org.dashbuilder dashbuilder-navigation-backend org.dashbuilder dashbuilder-displayer-api org.kie.soup kie-soup-json org.slf4j slf4j-api org.jboss.errai errai-bus org.jboss.errai errai-config org.jboss.errai errai-security-server jakarta.enterprise jakarta.enterprise.cdi-api jakarta.servlet jakarta.servlet-api provided org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-nio2-api org.uberfire uberfire-nio2-model org.uberfire uberfire-nio2-fs org.uberfire uberfire-backend-api org.uberfire uberfire-backend-server org.uberfire uberfire-api org.uberfire uberfire-io net.sf.opencsv opencsv org.apache.poi poi org.apache.poi poi-ooxml stax stax-api org.uberfire uberfire-nio2-jgit org.eclipse.jgit org.eclipse.jgit commons-logging commons-logging ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/dataset/service/DataSetDefServicesImpl.java ================================================ /** * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import java.io.File; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.servlet.ServletContext; import org.dashbuilder.DataSetCore; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSetDefDeployerCDI; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.uuid.UUIDGenerator; import org.dashbuilder.exception.ExceptionManager; import org.jboss.errai.bus.server.annotations.Service; import org.jboss.errai.bus.server.api.RpcContext; import org.jboss.errai.security.shared.api.identity.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ApplicationScoped @Service public class DataSetDefServicesImpl implements DataSetDefServices { protected static Logger log = LoggerFactory.getLogger(DataSetDefServicesImpl.class); protected User identity; protected ExceptionManager exceptionManager; protected UUIDGenerator uuidGenerator; protected DataSetDefRegistryCDI dataSetDefRegistry; protected DataSetDefDeployerCDI dataSetDefDeployer; public DataSetDefServicesImpl() { } @Inject public DataSetDefServicesImpl(User identity, ExceptionManager exceptionManager, DataSetDefRegistryCDI dataSetDefRegistry, DataSetDefDeployerCDI dataSetDefDeployer) { this.identity = identity; this.uuidGenerator = DataSetCore.get().getUuidGenerator(); this.dataSetDefRegistry = dataSetDefRegistry; this.exceptionManager = exceptionManager; this.dataSetDefDeployer = dataSetDefDeployer; } @PostConstruct protected void init() { // By default, enable the register of data set definitions stored into the deployment folder. ServletContext servletContext = RpcContext.getHttpSession().getServletContext(); if (!dataSetDefDeployer.isRunning() && servletContext != null) { String dir = servletContext.getRealPath("WEB-INF/datasets"); if (dir != null && new File(dir).exists()) { dir = dir.replaceAll("\\\\", "/"); dataSetDefDeployer.deploy(dir); } } } @Override public List getPublicDataSetDefs() { return dataSetDefRegistry.getDataSetDefs(true); } @Override public DataSetDef createDataSetDef(DataSetProviderType type) { DataSetDef result = type != null ? type.createDataSetDef() : new DataSetDef(); result.setUUID(uuidGenerator.newUuid()); return result; } @Override public String registerDataSetDef(DataSetDef definition, String comment) { // Data sets registered from the UI does not contain a UUID. if (definition.getUUID() == null) { final String uuid = uuidGenerator.newUuid(); definition.setUUID(uuid); } dataSetDefRegistry.registerDataSetDef(definition, identity != null ? identity.getIdentifier() : "---", comment); return definition.getUUID(); } @Override public void removeDataSetDef(final String uuid, String comment) { final DataSetDef def = dataSetDefRegistry.getDataSetDef(uuid); if (def != null) { dataSetDefRegistry.removeDataSetDef(uuid, identity != null ? identity.getIdentifier() : "---", comment); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/dataset/service/DataSetDefVfsServicesImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetManagerCDI; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.backend.EditDataSetDef; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.exception.ExceptionManager; import org.jboss.errai.bus.server.annotations.Service; import org.jboss.errai.security.shared.api.identity.User; import org.uberfire.backend.vfs.Path; @ApplicationScoped @Service public class DataSetDefVfsServicesImpl implements DataSetDefVfsServices { private static final String SYSTEM = "system"; protected User identity; protected DataSetDefRegistryCDI dataSetDefRegistry; protected DataSetManagerCDI dataSetManager; protected ExceptionManager exceptionManager; public DataSetDefVfsServicesImpl() { } @Inject public DataSetDefVfsServicesImpl(User identity, DataSetDefRegistryCDI dataSetDefRegistry, DataSetManagerCDI dataSetManager, ExceptionManager exceptionManager) { this.identity = identity; this.dataSetDefRegistry = dataSetDefRegistry; this.dataSetManager = dataSetManager; this.exceptionManager = exceptionManager; } @Override public Path resolve(DataSetDef dataSetDef) { return dataSetDefRegistry.resolveVfsPath(dataSetDef); } @Override public DataSetDef get(Path path) { return dataSetDefRegistry.loadDataSetDef(path); } @Override public EditDataSetDef load(Path path) { try { DataSetDef def = dataSetDefRegistry.loadDataSetDef(path); if (def == null) { return null; } // Clone the definition DataSetDef cloned = def.clone(); // Enable all columns and set columns to null, force to obtain metadata with all original columns // and all original column types. boolean clonedAllColumns = cloned.isAllColumnsEnabled(); List clonedColumns = cloned.getColumns(); cloned.setAllColumnsEnabled(true); cloned.setColumns(null); // Obtain all original columns and all original column types. DataSetMetadata _cd = dataSetManager.resolveProvider(cloned) .getDataSetMetadata(cloned); // Return the list of original columns and its types. List columns = new ArrayList(); if (_cd.getNumberOfColumns() > 0) { for (int x = 0; x < _cd.getNumberOfColumns(); x++) { String cId = _cd.getColumnId(x); ColumnType cType = _cd.getColumnType(x); DataColumnDef cdef = new DataColumnDef(cId, cType); columns.add(cdef); } } // Set columns attributes as initially were. cloned.setAllColumnsEnabled(clonedAllColumns); cloned.setColumns(clonedColumns); return new EditDataSetDef(cloned, columns); } catch (Exception e) { throw exceptionManager.handleException(e); } } @Override public Path save(DataSetDef definition, String commitMessage) { dataSetDefRegistry.registerDataSetDef(definition, identity != null ? identity.getIdentifier() : SYSTEM, commitMessage); return dataSetDefRegistry.resolveVfsPath(definition); } @Override public Path copy(Path path, String newName, String commitMessage) { DataSetDef def = dataSetDefRegistry.loadDataSetDef(path); if (def == null) { throw exceptionManager.handleException( new Exception("Data set definition not found: " + path.getFileName())); } DataSetDef clone = dataSetDefRegistry.copyDataSetDef(def, newName, identity != null ? identity.getIdentifier() : SYSTEM, commitMessage); return dataSetDefRegistry.resolveVfsPath(clone); } @Override public Path copy( final Path path, final String newName, final Path targetDirectory, final String comment ) { if (targetDirectory == null) { return copy(path, newName, comment); } throw new UnsupportedOperationException( "A data set definition cannot be copied to another directory." ); } @Override public void delete(Path path, String commitMessage) { dataSetDefRegistry.removeDataSetDef(path, identity != null ? identity.getIdentifier() : SYSTEM, commitMessage); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/dataset/service/DataSetExportServicesImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.math.BigDecimal; import java.math.BigInteger; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import au.com.bytecode.opencsv.CSVWriter; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.PrintSetup; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.DateFormatConverter; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.dashbuilder.DataSetCore; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetManagerCDI; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.uuid.UUIDGenerator; import org.dashbuilder.exception.ExceptionManager; import org.jboss.errai.bus.server.annotations.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.util.Paths; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; @ApplicationScoped @Service public class DataSetExportServicesImpl implements DataSetExportServices { private static final String TEXT_CELL = "text_cell"; protected static Logger log = LoggerFactory.getLogger(DataSetExportServicesImpl.class); protected DataSetManagerCDI dataSetManager; protected DataSetDefRegistryCDI gitStorage; protected UUIDGenerator uuidGenerator; protected ExceptionManager exceptionManager; protected String DEFAULT_SEPARATOR_CHAR = ";"; protected String DEFAULT_QUOTE_CHAR = "\""; protected String DEFAULT_ESCAPE_CHAR = "\\"; protected String dateFormatPattern = "dd/MM/yyyy HH:mm:ss"; protected String numberFormatPattern = "#,###.##########"; protected DecimalFormat decf = new DecimalFormat(numberFormatPattern); protected DateFormat datef = new SimpleDateFormat(dateFormatPattern); public DataSetExportServicesImpl() { } @Inject public DataSetExportServicesImpl(DataSetManagerCDI dataSetManager, DataSetDefRegistryCDI gitStorage, ExceptionManager exceptionManager) { this.dataSetManager = dataSetManager; this.gitStorage = gitStorage; this.uuidGenerator = DataSetCore.get().getUuidGenerator(); this.exceptionManager = exceptionManager; } public org.uberfire.backend.vfs.Path exportDataSetCSV(DataSetLookup lookup) { DataSet dataSet = dataSetManager.lookupDataSet(lookup); return exportDataSetCSV(dataSet); } public org.uberfire.backend.vfs.Path exportDataSetCSV(DataSet dataSet) { try { if (dataSet == null) { throw new IllegalArgumentException("Null dataSet specified!"); } int columnCount = dataSet.getColumns().size(); int rowCount = dataSet.getRowCount(); List lines = new ArrayList<>(rowCount+1); String[] line = new String[columnCount]; for (int cc = 0; cc < columnCount; cc++) { DataColumn dc = dataSet.getColumnByIndex(cc); line[cc] = dc.getId(); } lines.add(line); for (int rc = 0; rc < rowCount; rc++) { line = new String[columnCount]; for (int cc = 0; cc < columnCount; cc++) { line[cc] = formatAsString(dataSet.getValueAt(rc, cc)); } lines.add(line); } String tempCsvFile = uuidGenerator.newUuid() + ".csv"; Path tempCsvPath = gitStorage.createTempFile(tempCsvFile); try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(tempCsvPath))); CSVWriter writer = new CSVWriter(bw, DEFAULT_SEPARATOR_CHAR.charAt(0), DEFAULT_QUOTE_CHAR.charAt(0), DEFAULT_ESCAPE_CHAR.charAt(0)) ) { writer.writeAll(lines); writer.flush(); } return Paths.convert(tempCsvPath); } catch (Exception e) { throw exceptionManager.handleException(e); } } @Override public org.uberfire.backend.vfs.Path exportDataSetExcel(DataSetLookup dataSetLookup) { DataSet dataSet = dataSetManager.lookupDataSet( dataSetLookup ); return exportDataSetExcel( dataSet ); } @Override public org.uberfire.backend.vfs.Path exportDataSetExcel(DataSet dataSet) { try { SXSSFWorkbook wb = dataSetToWorkbook(dataSet); // Write workbook to Path String tempXlsFile = uuidGenerator.newUuid() + ".xlsx"; Path tempXlsPath = gitStorage.createTempFile(tempXlsFile); try (OutputStream os = Files.newOutputStream(tempXlsPath)) { wb.write(os); os.flush(); } // Dispose of temporary files backing this workbook on disk if (!wb.dispose()) { log.warn("Could not dispose of temporary file associated to data export!"); } return Paths.convert(tempXlsPath); } catch (Exception e) { throw exceptionManager.handleException(e); } } //Package private to enable testing SXSSFWorkbook dataSetToWorkbook(DataSet dataSet) { // TODO?: Excel 2010 limits: 1,048,576 rows by 16,384 columns; row width 255 characters if (dataSet == null) { throw new IllegalArgumentException("Null dataSet specified!"); } int columnCount = dataSet.getColumns().size(); int rowCount = dataSet.getRowCount() + 1; //Include header row; int row = 0; SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk Map styles = createStyles(wb); SXSSFSheet sh = wb.createSheet("Sheet 1"); // General setup sh.setDisplayGridlines(true); sh.setPrintGridlines(false); sh.setFitToPage(true); sh.setHorizontallyCenter(true); sh.trackAllColumnsForAutoSizing(); PrintSetup printSetup = sh.getPrintSetup(); printSetup.setLandscape(true); // Create header Row header = sh.createRow(row++); header.setHeightInPoints(20f); for (int i = 0; i < columnCount; i++) { Cell cell = header.createCell(i); cell.setCellStyle(styles.get("header")); cell.setCellValue(dataSet.getColumnByIndex(i).getId()); } // Create data rows for (; row < rowCount; row++) { Row _row = sh.createRow(row); for (int cellnum = 0; cellnum < columnCount; cellnum++) { Cell cell = _row.createCell(cellnum); Object value = dataSet.getValueAt(row - 1, cellnum); if (value instanceof Short || value instanceof Long || value instanceof Integer || value instanceof BigInteger) { cell.setCellType(CellType.NUMERIC); cell.setCellStyle(styles.get("integer_number_cell")); cell.setCellValue(((Number) value).doubleValue()); } else if (value instanceof Float || value instanceof Double || value instanceof BigDecimal) { cell.setCellType(CellType.NUMERIC); cell.setCellStyle(styles.get("decimal_number_cell")); cell.setCellValue(((Number) value).doubleValue()); } else if (value instanceof Date) { cell.setCellType(CellType.STRING); cell.setCellStyle(styles.get("date_cell")); cell.setCellValue((Date) value); } else if (value instanceof Interval) { cell.setCellType(CellType.STRING); cell.setCellStyle(styles.get(TEXT_CELL)); cell.setCellValue(((Interval) value).getName()); } else { cell.setCellType(CellType.STRING); cell.setCellStyle(styles.get(TEXT_CELL)); String val = value == null ? "" : value.toString(); cell.setCellValue(val); } } } // Adjust column size for (int i = 0; i < columnCount; i++) { sh.autoSizeColumn(i); } return wb; } private String formatAsString(Object value) { if (value == null) return ""; if (value instanceof Number) return decf.format(value); else if (value instanceof Date) return datef.format(value); // TODO verify if this is correct else if (value instanceof Interval) return ((Interval)value).getName(); else return value.toString(); } private Map createStyles(Workbook wb){ Map styles = new HashMap<>(); CellStyle style; Font titleFont = wb.createFont(); titleFont.setFontHeightInPoints((short)12); titleFont.setBold(true); style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); style.setFillForegroundColor( IndexedColors.GREY_25_PERCENT.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); style.setFont(titleFont); style.setWrapText(false); style.setBorderBottom(BorderStyle.THIN); style.setBottomBorderColor(IndexedColors.GREY_80_PERCENT.getIndex()); styles.put("header", style); Font cellFont = wb.createFont(); cellFont.setFontHeightInPoints((short)10); cellFont.setBold(true); style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.RIGHT); style.setVerticalAlignment(VerticalAlignment.BOTTOM); style.setFont(cellFont); style.setWrapText(false); style.setDataFormat(wb.createDataFormat().getFormat( BuiltinFormats.getBuiltinFormat( 3 ))); styles.put("integer_number_cell", style); style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.RIGHT); style.setVerticalAlignment(VerticalAlignment.BOTTOM); style.setFont(cellFont); style.setWrapText(false); style.setDataFormat(wb.createDataFormat().getFormat(BuiltinFormats.getBuiltinFormat(4))); styles.put("decimal_number_cell", style); style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.LEFT); style.setVerticalAlignment(VerticalAlignment.BOTTOM); style.setFont(cellFont); style.setWrapText(false); style.setDataFormat( (short) BuiltinFormats.getBuiltinFormat("text") ); styles.put(TEXT_CELL, style); style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.BOTTOM); style.setFont(cellFont); style.setWrapText(false); style.setDataFormat(wb.createDataFormat().getFormat( DateFormatConverter.convert( Locale.getDefault(), dateFormatPattern ))); styles.put("date_cell", style); return styles; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/dataset/service/DataSetLookupServicesImpl.java ================================================ /** * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import java.io.File; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.servlet.ServletContext; import org.dashbuilder.DataSetCore; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetDefDeployerCDI; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetManagerCDI; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.exception.DataSetLookupException; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.uuid.UUIDGenerator; import org.dashbuilder.exception.ExceptionManager; import org.jboss.errai.bus.server.annotations.Service; import org.jboss.errai.bus.server.api.RpcContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ApplicationScoped @Service public class DataSetLookupServicesImpl implements DataSetLookupServices { protected static Logger log = LoggerFactory.getLogger(DataSetLookupServicesImpl.class); protected DataSetManagerCDI dataSetManager; protected UUIDGenerator uuidGenerator; protected DataSetDefDeployerCDI dataSetDefDeployer; protected ExceptionManager exceptionManager; public DataSetLookupServicesImpl() { } @Inject public DataSetLookupServicesImpl(DataSetManagerCDI dataSetManager, DataSetDefDeployerCDI dataSetDefDeployer, ExceptionManager exceptionManager) { this.dataSetManager = dataSetManager; this.uuidGenerator = DataSetCore.get().getUuidGenerator(); this.dataSetDefDeployer = dataSetDefDeployer; this.exceptionManager = exceptionManager; } @PostConstruct protected void init() { // By default, enable the register of data set definitions stored into the deployment folder. ServletContext servletContext = RpcContext.getHttpSession().getServletContext(); if (!dataSetDefDeployer.isRunning() && servletContext != null) { String dir = servletContext.getRealPath("WEB-INF/datasets"); if (dir != null && new File(dir).exists()) { dir = dir.replaceAll("\\\\", "/"); dataSetDefDeployer.deploy(dir); } } } public DataSet lookupDataSet(DataSetLookup lookup) throws Exception { DataSet _d = null; try { _d = dataSetManager.lookupDataSet(lookup); } catch (DataSetLookupException e) { throw exceptionManager.handleException(e); } return _d; } public DataSet lookupDataSet(DataSetDef def, DataSetLookup lookup) throws Exception { try { // Although if using a not registered definition, it must have an uuid set for performing lookups. if (def.getUUID() == null) { final String uuid = uuidGenerator.newUuid(); def.setUUID(uuid); lookup.setDataSetUUID(uuid); } return dataSetManager.resolveProvider(def) .lookupDataSet(def, lookup); } catch (Exception e) { throw exceptionManager.handleException(e); } } public DataSetMetadata lookupDataSetMetadata(String uuid) throws Exception { DataSetMetadata _d = null; try { _d = dataSetManager.getDataSetMetadata(uuid); } catch (DataSetLookupException e) { throw exceptionManager.handleException(e); } return _d; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/dataset/service/SQLProviderServicesImpl.java ================================================ /** * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataprovider.sql.SQLDataSourceLocator; import org.dashbuilder.dataset.def.SQLDataSourceDef; import org.jboss.errai.bus.server.annotations.Service; @ApplicationScoped @Service public class SQLProviderServicesImpl implements SQLProviderServices { SQLDataSourceLocator sqlDataSourceLocator; public SQLProviderServicesImpl() { } @Inject public SQLProviderServicesImpl(SQLDataSourceLocator sqlDataSourceLocator) { this.sqlDataSourceLocator = sqlDataSourceLocator; } @Override public List getDataSourceDefs() { return sqlDataSourceLocator.list(); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/migration/DashbuilderDataMigration.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.migration; import java.io.File; import java.net.URI; import java.util.HashMap; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.spaces.SpacesAPIImpl; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import org.uberfire.java.nio.file.FileVisitResult; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.SimpleFileVisitor; import org.uberfire.java.nio.file.api.FileSystemUtils; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import org.uberfire.java.nio.fs.jgit.FileSystemLock; import org.uberfire.java.nio.fs.jgit.FileSystemLockManager; import org.uberfire.java.nio.fs.jgit.JGitFileSystem; import org.uberfire.mvp.Command; import org.uberfire.spaces.Space; import org.uberfire.spaces.SpacesAPI; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; @ApplicationScoped @Startup public class DashbuilderDataMigration { private static final Logger LOGGER = LoggerFactory.getLogger(DashbuilderDataMigration.class); private IOService ioService; private FileSystem datasetsFS; private FileSystem pluginsFS; private FileSystem perspectivesFS; private FileSystem navigationFS; public DashbuilderDataMigration() { } @Inject public DashbuilderDataMigration( final @Named("ioStrategy") IOService ioService, final @Named("datasetsFS") FileSystem datasetsFS, final @Named("pluginsFS") FileSystem pluginsFS, final @Named("perspectivesFS") FileSystem perspectivesFS, final @Named("navigationFS") FileSystem navigationFS) { this.ioService = ioService; this.datasetsFS = datasetsFS; this.pluginsFS = pluginsFS; this.perspectivesFS = perspectivesFS; this.navigationFS = navigationFS; } @PostConstruct protected void init() { if (this.isMigrationEnabled()) { runWithLock(() -> { migrateDatasets(); migratePerspectives(); migrateNavigation(); }); } } protected boolean isMigrationEnabled() { return FileSystemUtils.isGitDefaultFileSystem(); } private void migrateDatasets() { FileSystem oldDatasetsFS = lookupFileSystem(SpacesAPI.DEFAULT_SPACE, "datasets"); this.migrateDatasets(oldDatasetsFS, datasetsFS); cleanupFileSystem(oldDatasetsFS); } private FileSystem lookupFileSystem(Space space, String name) { FileSystem fs; URI uri = new SpacesAPIImpl().resolveFileSystemURI( SpacesAPI.Scheme.DEFAULT, space, name); HashMap env = new HashMap<>(); env.put("init", Boolean.TRUE); env.put("internal", Boolean.TRUE); try { fs = ioService.newFileSystem(uri, env); } catch (FileSystemAlreadyExistsException e) { fs = ioService.getFileSystem(uri); } return fs; } private void cleanupFileSystem(FileSystem fs) { Path root = getRoot(fs); if (root != null && fs instanceof JGitFileSystem) { try { Path fsPath = fs.getPath(""); Files.delete(fsPath); } catch (Exception e) { LOGGER.error("Failed to remove the datasets git repository."); LOGGER.debug("Error during dashbuilder migration", e); } } } private void migratePerspectives() { this.migratePerspectives(pluginsFS, perspectivesFS); } private void migrateNavigation() { this.migrateNavigation(pluginsFS, navigationFS); } public void migrateDatasets(FileSystem sourceFS, FileSystem targetFS) { LOGGER.info("attempt to migrate datasets"); migrate(sourceFS, targetFS, path -> !path.getFileName().toString().equals("readme.md")); } public void migratePerspectives(FileSystem sourceFS, FileSystem targetFS) { LOGGER.info("attempt to migrate perspectives"); migrate(sourceFS, targetFS, path -> path.getFileName().toString().startsWith("perspective_layout")); } public void migrateNavigation(FileSystem sourceFS, FileSystem targetFS) { LOGGER.info("attempt to migrate navigation"); migrate(sourceFS, targetFS, path -> path.getFileName().toString().equals("navtree.json")); } private void migrate(FileSystem sourceFS, FileSystem targetFS, Predicate predicate) { Path sourceRoot = getRoot(sourceFS); Path targetRoot = getRoot(targetFS); if (sourceRoot == null) { LOGGER.info("source does not exists"); return; } if (targetRoot == null) { LOGGER.error("target does not exists"); return; } LOGGER.info("moving from " + sourceFS.getName() + " to " + targetFS.getName()); Files.walkFileTree(sourceRoot, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) { checkNotNull("file", path); checkNotNull("attrs", attrs); Path targetPath = targetRoot.resolve(path.toString()); if (!predicate.test(path)) { LOGGER.debug("skip file " + path.toString()); } else if (ioService.exists(targetPath)) { LOGGER.debug("file " + path.toString() + " already exists on target"); Files.delete(path); } else { LOGGER.debug("moving file " + path.toString()); Files.copy(path, targetPath); Files.delete(path); } return FileVisitResult.CONTINUE; } }); } private Path getRoot(FileSystem fileSystem) { try { return fileSystem.getRootDirectories().iterator().next(); } catch (Exception e) { LOGGER.debug("could not get filesystem root", e); return null; } } protected void runWithLock(Command command) { String lockName = "data-migration.lock"; String markerName = "data-migration.done"; TimeUnit lastAccessTimeUnit = TimeUnit.SECONDS; int lastAccessThreshold = 1; // get .niogit/dashbuilder path File dir = navigationFS.getPath("/") .toFile() .getParentFile(); File marker = new File(dir, markerName); FileSystemLock lock = FileSystemLockManager .getInstance() .getFileSystemLock( dir, lockName, lastAccessTimeUnit, lastAccessThreshold); try { lock.lock(); if (!marker.exists()) { marker.createNewFile(); command.execute(); } } catch (java.io.IOException e) { LOGGER.error(e.getMessage(), e); } finally { lock.unlock(); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/renderer/service/RendererSettingsServiceImpl.java ================================================ package org.dashbuilder.renderer.service; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.renderer.RendererSettings; import org.jboss.errai.bus.server.annotations.Service; @Service @ApplicationScoped public class RendererSettingsServiceImpl implements RendererSettingsService { private RendererSettings settings; @PostConstruct public void loadSettings() { String defaultRenderer = System.getProperty(DEFAULT_RENDERER_PROPERTY, ""); String offlineStr = System.getProperty(OFFLINE_RENDERER_PROPERTY, "false"); boolean offline= Boolean.parseBoolean(offlineStr); settings = new RendererSettings(defaultRenderer, offline); } @Override public RendererSettings getSettings() { return settings; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/transfer/DataTransferServicesImpl.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.io.FileUtils; import org.apache.http.client.utils.URIBuilder; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.external.service.ComponentLoader; import org.dashbuilder.navigation.event.NavTreeChangedEvent; import org.dashbuilder.navigation.storage.NavTreeStorage; import org.jboss.errai.bus.server.annotations.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.ext.plugin.event.PluginAdded; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.ext.plugin.type.TypeConverterUtil; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileVisitResult; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.Paths; import org.uberfire.java.nio.file.SimpleFileVisitor; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import org.uberfire.rpc.SessionInfo; import org.uberfire.spaces.SpacesAPI; import static org.dashbuilder.dataset.DataSetDefRegistryCDI.DATASET_EXT; import static org.uberfire.ext.plugin.model.Plugin.FILE_EXT; @Service @ApplicationScoped public class DataTransferServicesImpl implements DataTransferServices { public static final String VERSION = "1.0.0"; private static final Logger LOGGER = LoggerFactory.getLogger(DataTransferServicesImpl.class); private IOService ioService; private FileSystem datasetsFS; private FileSystem perspectivesFS; private FileSystem navigationFS; private FileSystem systemFS; private DataSetDefRegistryCDI dataSetDefRegistryCDI; private SessionInfo sessionInfo; private Event dataSetDefRegisteredEvent; private Event pluginAddedEvent; private Event navTreeChangedEvent; private NavTreeStorage navTreeStorage; private byte[] buffer = new byte[1024]; private ComponentLoader externalComponentLoader; private LayoutComponentHelper layoutComponentsHelper; private String dashbuilderLocation; private String exportDir; private boolean shareOpenModel; public DataTransferServicesImpl() { // empty constructor } @Inject public DataTransferServicesImpl( final @Named("ioStrategy") IOService ioService, final @Named("datasetsFS") FileSystem datasetsFS, final @Named("perspectivesFS") FileSystem perspectivesFS, final @Named("navigationFS") FileSystem navigationFS, final @Named("systemFS") FileSystem systemFS, final DataSetDefRegistryCDI dataSetDefRegistryCDI, final SessionInfo sessionInfo, final Event dataSetDefRegisteredEvent, final Event pluginAddedEvent, final Event navTreeChangedEvent, final NavTreeStorage navTreeStorage, final ComponentLoader externalComponentLoader, final LayoutComponentHelper layoutComponentsHelper) { this.ioService = ioService; this.datasetsFS = datasetsFS; this.perspectivesFS = perspectivesFS; this.navigationFS = navigationFS; this.systemFS = systemFS; this.dataSetDefRegistryCDI = dataSetDefRegistryCDI; this.sessionInfo = sessionInfo; this.dataSetDefRegisteredEvent = dataSetDefRegisteredEvent; this.pluginAddedEvent = pluginAddedEvent; this.navTreeChangedEvent = navTreeChangedEvent; this.navTreeStorage = navTreeStorage; this.externalComponentLoader = externalComponentLoader; this.layoutComponentsHelper = layoutComponentsHelper; } @PostConstruct public void init() { dashbuilderLocation = System.getProperty(DB_STANDALONE_LOCATION_PROP); exportDir = System.getProperty(EXPORT_LOCATION_PROP); String shareOpenModelStr = System.getProperty(SHARE_OPEN_MODEL_PROP, Boolean.FALSE.toString()); shareOpenModel = Boolean.parseBoolean(shareOpenModelStr); } @Override public String doExport(DataTransferExportModel exportModel) throws java.io.IOException { String zipLocation = new StringBuilder().append(System.getProperty("java.io.tmpdir")) .append(File.separator) .append(FILE_PATH) .append(File.separator) .append(EXPORT_FILE_NAME) .toString() .replace("\\", "/"); Predicate readmeFilter = p -> p.toString().toLowerCase().endsWith("readme.md"); Predicate datasetsFilter = def -> true; Predicate pagesFilter = page -> true; boolean exportNavigation = true; if (!exportModel.isExportAll()) { datasetsFilter = filterDatasets(exportModel.getDatasetDefinitions()); pagesFilter = filterPages(exportModel.getPages()); exportNavigation = exportModel.isExportNavigation(); } new File(zipLocation).getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(zipLocation); ZipOutputStream zos = new ZipOutputStream(fos); zipFileSystem(datasetsFS, zos, readmeFilter.or(datasetsFilter)); zipFileSystem(perspectivesFS, zos, readmeFilter.or(pagesFilter)); if (exportNavigation) { zipFileSystem(navigationFS, zos, p -> true); } else { zipFileSystem(navigationFS, zos, readmeFilter); } if (externalComponentLoader.isExternalComponentsEnabled()) { String componentsPath = externalComponentLoader.getExternalComponentsDir(); if (componentsPath != null && exists(componentsPath)) { Path componentsBasePath = Paths.get(new StringBuilder().append(SpacesAPI.Scheme.FILE) .append("://") .append(componentsPath) .toString()); Predicate pagesComponentsFilter = page -> exportModel.isExportAll() || exportModel.getPages().contains(page); layoutComponentsHelper.findComponentsInTemplates(pagesComponentsFilter) .stream() .map(c -> componentsBasePath.resolve(c)) .filter(Files::exists) .forEach(c -> { Path componentPath = componentsBasePath.resolve(c); zipComponentFiles(componentsBasePath, componentPath, zos, p -> true); }); } } zipFile(createVersionFile(), "VERSION", zos); zos.close(); fos.close(); moveZipToFileSystem(zipLocation, systemFS); return new StringBuilder().append(SpacesAPI.Scheme.GIT) .append("://") .append(systemFS.getName()) .append(File.separator) .append(FILE_PATH) .append(File.separator) .append(EXPORT_FILE_NAME) .toString() .replace("\\", "/"); } @Override public List doImport() throws Exception { List imported = new ArrayList<>(); Path root = Paths.get(URI.create(new StringBuilder().append(SpacesAPI.Scheme.GIT) .append("://") .append(systemFS.getName()) .append(File.separator) .toString() .replace("\\", "/"))); String expectedPath = new StringBuilder().append(File.separator) .append(FILE_PATH) .append(File.separator) .append(IMPORT_FILE_NAME) .toString() .replace("\\", "/"); Files.walkFileTree(root, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { if (!path.toString().equalsIgnoreCase(expectedPath)) { return FileVisitResult.CONTINUE; } try { imported.addAll(importFiles(path)); return FileVisitResult.TERMINATE; } catch (Exception e) { LOGGER.error(e.getMessage(), e); return FileVisitResult.TERMINATE; } } }); ioService.deleteIfExists(root.resolve(expectedPath)); return imported; } @Override public ExportInfo exportInfo() { List pages = listPaths(perspectivesFS, p -> p.endsWith(FILE_EXT)).stream() .map(p -> p.getName(p.getNameCount() - 2)) .map(Object::toString) .collect(Collectors.toList()); List datasetsDefs = listPaths(datasetsFS, p -> p.endsWith(DATASET_EXT)).stream() .map(this::getDataSetFileContent) .map(this::parseDataSetDefinition) .filter(DataSetDef::isPublic) .collect(Collectors.toList()); return new ExportInfo(datasetsDefs, pages, isExternalServerConfigured()); } @Override public String generateExportUrl(DataTransferExportModel exportModel) throws Exception { if (!isExternalServerConfigured()) { throw new RuntimeException("External Server is not configured."); } try { String path = this.doExport(exportModel); String prefix = shareOpenModel ? "business-central" : sessionInfo.getIdentity().getIdentifier(); String fileName = prefix + "-dashboard-latest"; String destination = new StringBuilder().append(exportDir) .append(File.separator) .append(fileName) .append(".zip") .toString(); FileUtils.deleteQuietly(new File(destination)); copyFileContents(Paths.get(path).toFile(), destination); return new URIBuilder(dashbuilderLocation).addParameter("import", fileName).toString(); } catch (Exception e) { LOGGER.error("Error generating model link.", e); throw new RuntimeException("Error generating model link.", e); } } private boolean isExternalServerConfigured() { return exportDir != null && dashbuilderLocation != null; } private List importFiles(Path path) throws Exception { String tmpDir = System.getProperty("java.io.tmpdir"); if (tmpDir.lastIndexOf('/') == tmpDir.length() - 1 || tmpDir.lastIndexOf('\\') == tmpDir.length() - 1) { tmpDir = tmpDir.substring(0, tmpDir.length() - 1); } String tempPath = new StringBuilder().append(tmpDir) .append(File.separator) .append(FILE_PATH) .append(File.separator) .toString().replace("\\", "/"); List imported = new ArrayList<>(); File destDir = new File(tempPath); try (ZipInputStream zis = new ZipInputStream(new FileInputStream(path.toFile()))) { ZipEntry zipEntry; while ((zipEntry = zis.getNextEntry()) != null) { if (zipEntry.isDirectory()) { continue; } File newFile = unzipFile(destDir, zipEntry, zis); FileSystem fileSystem = getImportFileSystem(newFile, tempPath); if (fileSystem != null) { String newFilePath = importFSFile(fileSystem.getName(), newFile, tempPath); imported.add(new StringBuilder().append(fileSystem.getName()) .append(newFilePath) .toString()); } if (isComponent(zipEntry) && externalComponentLoader.getExternalComponentsDir() != null && externalComponentLoader.isExternalComponentsEnabled()) { try { importComponentFile(zipEntry.getName(), newFile); imported.add(zipEntry.getName()); } catch (Exception e) { LOGGER.error("Error importing component file {}", zipEntry.getName()); LOGGER.debug("Component file import error.", e); } } } } FileUtils.deleteDirectory(destDir); return imported; } private boolean isComponent(ZipEntry zipEntry) { return zipEntry.getName() != null && zipEntry.getName().startsWith(COMPONENTS_EXPORT_PATH); } private String importComponentFile(String entryName, File newFile) { String externalComponentsDir = externalComponentLoader.getExternalComponentsDir(); externalComponentsDir = externalComponentsDir.endsWith(File.separator) ? externalComponentsDir : externalComponentsDir + "/"; String newFileName = externalComponentsDir + entryName.replaceAll(COMPONENTS_EXPORT_PATH, ""); copyFileContents(newFile, newFileName); return newFileName; } private void copyFileContents(File originFile, String newFileName) { File target = new File(newFileName); target.getParentFile().mkdirs(); if (!target.exists()) { ioService.copy(Paths.get(originFile.toURI()), Paths.get(target.toURI())); } } private String importFSFile(String fsName, File newFile, String workingDir) throws Exception { URI uri = URI.create(new StringBuilder().append(SpacesAPI.Scheme.GIT) .append("://") .append(fsName) .toString() .replace("\\", "/")); String newFilePath = newFile.toPath() .toString() .replace("\\", "/") .replace(new StringBuilder(workingDir).append(fsName), ""); ioService.write(Paths.get(uri).resolve(newFilePath), java.nio.file.Files.readAllBytes(newFile.toPath())); fireEvent(newFile, workingDir, uri, newFilePath); return newFilePath; } private void fireEvent(File newFile, String tempPath, URI uri, String newFilePath) { String filePath = newFile.toURI().toString(); if (filePath.contains(tempPath + datasetsFS.getName()) && newFilePath.endsWith(DATASET_EXT)) { fireDatasetEvent(uri, newFilePath); } else if (filePath.contains(tempPath + perspectivesFS.getName()) && newFilePath.endsWith(FILE_EXT)) { firePerspectiveEvent(newFile, uri, newFilePath); } else if (filePath.contains(tempPath + navigationFS.getName()) && newFilePath.endsWith(NavTreeStorage.NAV_TREE_FILE_NAME)) { fireNavigationEvent(); } } private void fireDatasetEvent(URI uri, String newFilePath) { try { String json = ioService.readAllString(Paths.get(uri).resolve(newFilePath)); DataSetDef newDef = dataSetDefRegistryCDI.getDataSetDefJsonMarshaller().fromJson(json); dataSetDefRegisteredEvent.fire(new DataSetDefRegisteredEvent(newDef)); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } } private void firePerspectiveEvent(File newFile, URI uri, String newFilePath) { org.uberfire.backend.vfs.Path pluginPath = org.uberfire.backend.server.util.Paths.convert( Paths.get(uri).resolve(newFilePath)); Plugin plugin = new Plugin( newFile.toPath().getParent().getFileName().toString(), TypeConverterUtil.fromPath(pluginPath), pluginPath); pluginAddedEvent.fire(new PluginAdded(plugin, sessionInfo)); } private void fireNavigationEvent() { navTreeChangedEvent.fire( new NavTreeChangedEvent( navTreeStorage.loadNavTree())); } private FileSystem getImportFileSystem(File file, String tempPath) { List fileSystems = Arrays.asList(datasetsFS, perspectivesFS, navigationFS); String filePath = file.toURI().toString().replace("\\", "/"); return fileSystems.stream() .filter(fs -> filePath.contains(tempPath + fs.getName())) .findFirst() .orElse(null); } private void moveZipToFileSystem(String zipLocation, FileSystem fileSystem) { String sourceLocation = new StringBuilder() .append(SpacesAPI.Scheme.FILE) .append(":///") .append(zipLocation) .toString(); Path source = Paths.get(URI.create(sourceLocation)); Path target = Paths.get(URI.create(new StringBuilder().append(SpacesAPI.Scheme.GIT) .append("://") .append(fileSystem.getName()) .append(File.separator) .append(FILE_PATH) .append(File.separator) .append(EXPORT_FILE_NAME) .toString() .replace("\\", "/"))); ioService.write(target, Files.readAllBytes(source)); Files.delete(source); } private File unzipFile(File destinationDir, ZipEntry zipEntry, ZipInputStream zis) throws java.io.IOException { File destFile = new File(destinationDir, zipEntry.getName()); if (!destFile.exists()) { destFile.getParentFile().mkdirs(); if (!destFile.createNewFile()) { throw new IOException("could not create file " + destFile.getPath()); } } try (FileOutputStream fos = new FileOutputStream(destFile)) { int len; while ((len = zis.read(buffer)) > 0) { fos.write(buffer, 0, len); } } return destFile; } private void zipFileSystem(FileSystem fs, ZipOutputStream zos, Predicate pathTest) { Path root = fs.getRootDirectories().iterator().next(); Files.walkFileTree(root, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { try { if (pathTest.test(path)) { String location = fs.getName() + path.toString(); zipFile(path.toFile(), location, zos); } return FileVisitResult.CONTINUE; } catch (Exception e) { LOGGER.error(e.getMessage(), e); return FileVisitResult.TERMINATE; } } }); } private void zipComponentFiles(Path componentsRoot, Path componentRoot, ZipOutputStream zos, Predicate pathTest) { Files.walkFileTree(componentRoot, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { try { if (pathTest.test(path)) { File file = path.toFile(); Path relativePath = componentsRoot.relativize(path); String location = COMPONENTS_EXPORT_PATH + relativePath.toString(); zipFile(file, location, zos); } return FileVisitResult.CONTINUE; } catch (Exception e) { LOGGER.error(e.getMessage(), e); return FileVisitResult.TERMINATE; } } }); } private void zipFile(File file, String path, ZipOutputStream zos) throws java.io.IOException { try (FileInputStream fis = new FileInputStream(file)) { ZipEntry zipEntry = new ZipEntry(path); zos.putNextEntry(zipEntry); int length; while ((length = fis.read(buffer)) >= 0) { zos.write(buffer, 0, length); } zos.closeEntry(); } } private File createVersionFile() throws java.io.IOException { File version = File.createTempFile("temp", "version"); try (BufferedWriter out = new BufferedWriter(new FileWriter(version))) { out.write(VERSION); } return version; } private List listPaths(FileSystem fs, Predicate pathTester) { List files = new ArrayList<>(); Path root = fs.getRootDirectories().iterator().next(); Files.walkFileTree(root, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { try { if (pathTester.test(path.toString())) { files.add(path); } return FileVisitResult.CONTINUE; } catch (Exception e) { LOGGER.error(e.getMessage(), e); return FileVisitResult.TERMINATE; } } }); return files; } private String getDataSetFileContent(Path path) { return Files.readAllLines(path, StandardCharsets.UTF_8).stream().collect(Collectors.joining()); } private DataSetDef parseDataSetDefinition(String defJson) { try { return dataSetDefRegistryCDI.getDataSetDefJsonMarshaller().fromJson(defJson); } catch (Exception e) { LOGGER.error("Error parsing dataset definition", e); LOGGER.debug("Json Definition: {}", defJson); throw new IllegalArgumentException(e); } } private Predicate filterPages(List pages) { return page -> { if (pages.isEmpty()) { return false; } int nameCount = page.getNameCount(); if (nameCount > 1) { return pages.stream() .anyMatch(p -> page.getName(nameCount - 2).toString().equals(p)); } return false; }; } private Predicate filterDatasets(List datasets) { return dsPath -> { if (datasets.isEmpty()) { return false; } int nameCount = dsPath.getNameCount(); if (nameCount > 1) { String fileName = dsPath.getName(nameCount - 1) .toString() .split("\\.")[0]; return datasets.stream() .anyMatch(ds -> ds.getUUID().equals(fileName)); } return false; }; } private boolean exists(String file) { return java.nio.file.Files.exists(java.nio.file.Paths.get(file)); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/transfer/ExportModelValidationServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.navigation.service.PerspectivePluginServices; import org.jboss.errai.bus.server.annotations.Service; @Service @ApplicationScoped public class ExportModelValidationServiceImpl implements ExportModelValidationService { PerspectivePluginServices perspectivePluginServices; DisplayerSettingsJSONMarshaller marshaller; public ExportModelValidationServiceImpl() {} @Inject public ExportModelValidationServiceImpl(PerspectivePluginServices perspectivePluginServices) { this(perspectivePluginServices, DisplayerSettingsJSONMarshaller.get()); } ExportModelValidationServiceImpl(PerspectivePluginServices perspectivePluginServices, DisplayerSettingsJSONMarshaller marshaller) { this.perspectivePluginServices = perspectivePluginServices; this.marshaller = marshaller; } @Override public Map> checkMissingDatasets(DataTransferExportModel exportModel) { if (exportModel == null || exportModel.getPages().isEmpty()) { return Collections.emptyMap(); } Map> deps = exportModel.getPages() .stream() .collect(Collectors.toMap(p -> p, p -> datasetsUsedInPage(p, exportModel))); deps.entrySet().removeIf(e -> e.getValue().isEmpty()); return deps; } private List datasetsUsedInPage(String p, DataTransferExportModel exportModel) { List exportedDefs = exportModel.getDatasetDefinitions(); return allDataSetsFromPage(p).filter(uuid -> isDataSetMissing(uuid, exportedDefs)) .distinct() .collect(Collectors.toList()); } private boolean isDataSetMissing(String uuid, List exportedDefs) { return exportedDefs.isEmpty() || exportedDefs.stream().noneMatch(ds -> ds.getUUID().equals(uuid)); } private Stream allDataSetsFromPage(String p) { return perspectivePluginServices.getLayoutTemplate(p) .getRows().stream() .flatMap(r -> r.getLayoutColumns().stream()) .flatMap(cl -> cl.getLayoutComponents().stream()) .map(lc -> lc.getProperties().get("json")) .filter(Objects::nonNull) .map(marshaller::fromJsonString) .map(DisplayerSettings::getDataSetLookup) .filter(Objects::nonNull) .map(DataSetLookup::getDataSetUUID) .filter(Objects::nonNull); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/transfer/LayoutComponentHelper.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.List; import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.external.model.ExternalComponent; import org.uberfire.ext.layout.editor.api.PerspectiveServices; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; @ApplicationScoped public class LayoutComponentHelper { @Inject private PerspectiveServices perspectiveServices; public List findComponentsInTemplates(Predicate pageFilter) { return perspectiveServices.listLayoutTemplates() .stream() .filter(lt -> pageFilter.test(lt.getName())) .map(LayoutTemplate::getRows) .flatMap(this::allComponentsStream) .map(lt -> lt.getProperties().get(ExternalComponent.COMPONENT_ID_KEY)) .filter(Objects::nonNull) .collect(Collectors.toList()); } private Stream allComponentsStream(List row) { return row.stream() .flatMap(r -> r.getLayoutColumns().stream()) .flatMap(cl -> Stream.concat(cl.getLayoutComponents().stream(), allComponentsStream(cl.getRows()))); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/java/org/dashbuilder/transfer/rest/DataTransferResource.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer.rest; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import org.dashbuilder.transfer.DataTransferExportModel; import org.dashbuilder.transfer.DataTransferServices; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.Paths; @ApplicationScoped @Path("dashbuilder") public class DataTransferResource { Logger logger = LoggerFactory.getLogger(DataTransferResource.class); @Inject private DataTransferServices dataTransferServices; @Inject @Named("ioStrategy") private IOService ioService; @GET @Path("export") @Produces("application/zip") public Response export() { try { String exportFile = dataTransferServices.doExport(DataTransferExportModel.exportAll()); org.uberfire.java.nio.file.Path path = Paths.get(exportFile); return Response.ok(ioService.readAllBytes(path)).build(); } catch (Exception e) { String errorMessage = "Error creating export: " + e.getMessage(); logger.error(errorMessage); logger.debug("Not able to create export.", e); return Response.serverError() .entity(errorMessage) .build(); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/java/org/dashbuilder/dataset/service/DataSetExportServicesTest.java ================================================ package org.dashbuilder.dataset.service; import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.DataSetManagerCDI; import org.dashbuilder.exception.ExceptionManager; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class DataSetExportServicesTest { private static final String JAVA_AWT_HEADLESS_PROPERTY = "java.awt.headless"; private static String originalJavaAwtHeadless; @Mock DataSetManagerCDI dataSetManagerM; @Mock DataSetDefRegistryCDI gitStorageM; @Mock ExceptionManager exceptionManagerM; @BeforeClass public static void setUp() { /* * Make the test run in headless mode. It used to fail frequently on Jenkins (40 failures in 6 months) with * the following stack trace (abridged): * * java.awt.AWTError: Can't connect to X11 window server using ':93' as the value of the DISPLAY variable. * at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method) * at sun.awt.X11GraphicsEnvironment.access$200(X11GraphicsEnvironment.java:65) * at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:115) * at sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:74) * at java.lang.Class.forName0(Native Method) * at java.lang.Class.forName(Class.java:264) * at java.awt.GraphicsEnvironment.createGE(GraphicsEnvironment.java:103) * at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82) * at sun.awt.X11FontManager.isHeadless(X11FontManager.java:509) * at sun.awt.X11FontManager.getFontPath(X11FontManager.java:786) * at sun.font.SunFontManager.getPlatformFontPath(SunFontManager.java:3282) * at sun.font.SunFontManager$10.run(SunFontManager.java:3308) * at sun.font.SunFontManager.loadFonts(SunFontManager.java:3304) * at sun.awt.X11FontManager.loadFonts(X11FontManager.java:460) * at sun.font.SunFontManager.findFont2D(SunFontManager.java:2348) * at java.awt.Font.getFont2D(Font.java:500) * at java.awt.Font.canDisplayUpTo(Font.java:2060) * at java.awt.font.TextLayout.singleFont(TextLayout.java:470) * at java.awt.font.TextLayout.(TextLayout.java:531) * at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:275) * at org.apache.poi.xssf.streaming.AutoSizeColumnTracker.(AutoSizeColumnTracker.java:117) * at org.apache.poi.xssf.streaming.SXSSFSheet.(SXSSFSheet.java:82) * at org.apache.poi.xssf.streaming.SXSSFWorkbook.createAndRegisterSXSSFSheet(SXSSFWorkbook.java:658) * at org.apache.poi.xssf.streaming.SXSSFWorkbook.createSheet(SXSSFWorkbook.java:679) * at org.dashbuilder.dataset.service.DataSetExportServicesImpl.dataSetToWorkbook(DataSetExportServicesImpl.java:194) * at org.dashbuilder.dataset.service.DataSetExportServicesTest.exportToExcelWorksWhenDataSetHasNulls(DataSetExportServicesTest.java:41) * * To reproduce locally, use -Djava.awt.headless and set DISPLAY to a non-existent display number, e.g. :12345. * * Headless mode doesn't seem to affect the SXSSFWorkbook behavior. SheetUtil.getDefaultCharWidth() returns 0 in * both modes. */ originalJavaAwtHeadless = System.getProperty(JAVA_AWT_HEADLESS_PROPERTY); System.setProperty(JAVA_AWT_HEADLESS_PROPERTY, "true"); } @AfterClass public static void tearDown() { if (originalJavaAwtHeadless == null) { System.clearProperty(JAVA_AWT_HEADLESS_PROPERTY); } else { System.setProperty(JAVA_AWT_HEADLESS_PROPERTY, originalJavaAwtHeadless); } } @Test public void exportToExcelWorksWhenDataSetHasNulls() { DataSetExportServicesImpl exporter = new DataSetExportServicesImpl(dataSetManagerM, gitStorageM, exceptionManagerM); DataSet dataSetWithNulls = DataSetFactory.newDataSetBuilder() .date("Date of birth") .number("Age") .text("Description") .row(null, null, null).buildDataSet(); SXSSFWorkbook workbook = exporter.dataSetToWorkbook(dataSetWithNulls); assertNotNull("Export of dataset containing null should succeed", workbook); // Verify header SXSSFRow firstRow = workbook.getSheetAt(0).getRow(0); assertEquals("Date of birth", firstRow.getCell(0).getStringCellValue()); assertEquals("Age", firstRow.getCell(1).getStringCellValue()); assertEquals("Description", firstRow.getCell(2).getStringCellValue()); // Verify data row SXSSFRow secondRow = workbook.getSheetAt(0).getRow(1); assertEquals("", secondRow.getCell(0).getStringCellValue()); assertEquals("", secondRow.getCell(1).getStringCellValue()); assertEquals("", secondRow.getCell(2).getStringCellValue()); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/java/org/dashbuilder/migration/DashbuilderDataMigrationTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.migration; import java.net.URI; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.io.IOService; import org.uberfire.io.impl.IOServiceDotFileImpl; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemMetadata; import org.uberfire.java.nio.file.FileVisitResult; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.SimpleFileVisitor; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import org.uberfire.java.nio.fs.jgit.JGitFileSystem; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class DashbuilderDataMigrationTest { private DashbuilderDataMigration dashbuilderDataMigration; private IOService ioService; private FileSystem sourceFS; private FileSystem targetFS; @Before public void setup() { ioService = new IOServiceDotFileImpl(); sourceFS = createFileSystem(); targetFS = createFileSystem(); dashbuilderDataMigration = spy( new DashbuilderDataMigration( ioService, null, null, null, null)); } @Test public void testMigrateNull() { checkInitialCondition(); dashbuilderDataMigration.migrateDatasets(null, null); dashbuilderDataMigration.migratePerspectives(null, null); dashbuilderDataMigration.migrateNavigation(null, null); dashbuilderDataMigration.migrateDatasets(sourceFS, null); checkInitialCondition(); dashbuilderDataMigration.migrateDatasets(null, targetFS); checkInitialCondition(); dashbuilderDataMigration.migratePerspectives(sourceFS, null); checkInitialCondition(); dashbuilderDataMigration.migratePerspectives(null, targetFS); checkInitialCondition(); dashbuilderDataMigration.migrateNavigation(sourceFS, null); checkInitialCondition(); dashbuilderDataMigration.migrateNavigation(null, targetFS); checkInitialCondition(); } @Test public void testGitIsDefaultFileSystem() { doNothing().when(dashbuilderDataMigration).runWithLock(any()); doReturn(true).when(dashbuilderDataMigration).isMigrationEnabled(); dashbuilderDataMigration.init(); verify(dashbuilderDataMigration, times(1)).runWithLock(any()); } @Test public void testGitIsNotDefaultFileSystem() { doReturn(false).when(dashbuilderDataMigration).isMigrationEnabled(); dashbuilderDataMigration.init(); verify(dashbuilderDataMigration, never()).runWithLock(any()); } @Test public void testMigrateEmpty() { checkInitialCondition(); dashbuilderDataMigration.migrateDatasets(sourceFS, targetFS); checkInitialCondition(); dashbuilderDataMigration.migratePerspectives(sourceFS, targetFS); checkInitialCondition(); dashbuilderDataMigration.migrateNavigation(sourceFS, targetFS); checkInitialCondition(); } @Test public void testMigrateDatasets() { checkInitialCondition(); createFiles(sourceFS); dashbuilderDataMigration.migrateDatasets(sourceFS, targetFS); List sourceFiles = getFiles(sourceFS); List targetFiles = getFiles(targetFS); assertEquals(1, sourceFiles.size()); assertEquals(8, targetFiles.size()); assertEquals(new ArrayList() {{ add("/readme.md"); }}, sourceFiles); assertEquals(new ArrayList() {{ add("/bbb.txt"); add("/dataset1.csv"); add("/definitions/dataset2.dset"); add("/navtree.json"); add("/page-abc/perspective_layout.json"); add("/perspective_layout2.txt"); add("/perspective_layouts/aaa.txt"); add("/readme.md"); }}, targetFiles); } @Test public void testMigratePerspectives() { checkInitialCondition(); createFiles(sourceFS); dashbuilderDataMigration.migratePerspectives(sourceFS, targetFS); List sourceFiles = getFiles(sourceFS); List targetFiles = getFiles(targetFS); assertEquals(6, sourceFiles.size()); assertEquals(3, targetFiles.size()); assertEquals(new ArrayList() {{ add("/bbb.txt"); add("/dataset1.csv"); add("/definitions/dataset2.dset"); add("/navtree.json"); add("/perspective_layouts/aaa.txt"); add("/readme.md"); }}, sourceFiles); assertEquals(new ArrayList() {{ add("/page-abc/perspective_layout.json"); add("/perspective_layout2.txt"); add("/readme.md"); }}, targetFiles); } @Test public void testMigrateNavigation() { checkInitialCondition(); createFiles(sourceFS); dashbuilderDataMigration.migrateNavigation(sourceFS, targetFS); List sourceFiles = getFiles(sourceFS); List targetFiles = getFiles(targetFS); assertEquals(7, sourceFiles.size()); assertEquals(2, targetFiles.size()); assertEquals(new ArrayList() {{ add("/bbb.txt"); add("/dataset1.csv"); add("/definitions/dataset2.dset"); add("/page-abc/perspective_layout.json"); add("/perspective_layout2.txt"); add("/perspective_layouts/aaa.txt"); add("/readme.md"); }}, sourceFiles); assertEquals(new ArrayList() {{ add("/navtree.json"); add("/readme.md"); }}, targetFiles); } private void checkInitialCondition() { List sourceFiles = getFiles(sourceFS); List targetFiles = getFiles(targetFS); assertEquals(1, sourceFiles.size()); assertEquals(1, targetFiles.size()); assertEquals(new ArrayList() {{ add("/readme.md"); }}, sourceFiles); assertEquals(new ArrayList() {{ add("/readme.md"); }}, targetFiles); } private List getFiles(FileSystem fs) { List files = new ArrayList<>(); Path root = fs.getRootDirectories().iterator().next(); Files.walkFileTree(root, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) throws IOException { files.add(path.toString()); return FileVisitResult.CONTINUE; } }); return files; } private void createFiles(FileSystem fs) { Path path = fs.getRootDirectories().iterator().next(); ioService.write(path.resolve("dataset1.csv"), "test"); ioService.write(path.resolve("definitions").resolve("dataset2.dset"), "test"); ioService.write(path.resolve("navtree.json"), "test"); ioService.write(path.resolve("perspective_layouts").resolve("aaa.txt"), "test"); ioService.write(path.resolve("bbb.txt"), "test"); ioService.write(path.resolve("page-abc").resolve("perspective_layout.json"), "test"); ioService.write(path.resolve("perspective_layout2.txt"), "test"); } private FileSystem createFileSystem() { return ioService.newFileSystem( URI.create("git://migration/temp" + new Date().getTime()), new HashMap() {{ put("init", Boolean.TRUE); }}); } @After public void cleanup() { for (FileSystemMetadata fsm : ioService.getFileSystemMetadata()) { URI uri = URI.create(fsm.getUri()); if (uri.getScheme().equals("git")) { JGitFileSystem fs = (JGitFileSystem) ioService.getFileSystem(uri); fs.getGit().getRepository().getDirectory().delete(); deleteFileSystem(fs); } } } private void deleteFileSystem(FileSystem fs) { try { FileUtils.deleteDirectory( ((JGitFileSystem) fs).getGit() .getRepository() .getDirectory() .getAbsoluteFile() .getParentFile()); } catch (java.io.IOException e) { e.printStackTrace(); } } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/java/org/dashbuilder/renderer/service/RendererSettingsServiceTest.java ================================================ package org.dashbuilder.renderer.service; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.dashbuilder.renderer.RendererSettings; import org.junit.Test; public class RendererSettingsServiceTest { private static final String SOME_UUID = "SOME_UUID"; @Test public void propertiesLoadTest() { RendererSettingsServiceImpl serviceImpl = new RendererSettingsServiceImpl(); System.setProperty(RendererSettingsService.DEFAULT_RENDERER_PROPERTY, SOME_UUID); System.setProperty(RendererSettingsService.OFFLINE_RENDERER_PROPERTY, "not valid property"); serviceImpl.loadSettings(); RendererSettings settings = serviceImpl.getSettings(); assertEquals(settings.getDefaultRenderer(), SOME_UUID); assertTrue(!settings.isOffline()); System.setProperty(RendererSettingsService.DEFAULT_RENDERER_PROPERTY, ""); System.setProperty(RendererSettingsService.OFFLINE_RENDERER_PROPERTY, "true"); serviceImpl.loadSettings(); settings = serviceImpl.getSettings(); assertTrue(settings.getDefaultRenderer().isEmpty()); assertTrue(settings.isOffline()); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/java/org/dashbuilder/transfer/DataTransferServicesTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.io.ByteArrayInputStream; import java.io.File; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.enterprise.event.Event; import org.dashbuilder.dataset.DataSetDefRegistryCDI; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentLoader; import org.dashbuilder.navigation.event.NavTreeChangedEvent; import org.dashbuilder.navigation.storage.NavTreeStorage; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.lesscss.deps.org.apache.commons.io.FileUtils; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.ext.plugin.event.PluginAdded; import org.uberfire.io.IOService; import org.uberfire.io.impl.IOServiceDotFileImpl; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileVisitResult; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.Paths; import org.uberfire.java.nio.file.SimpleFileVisitor; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import org.uberfire.rpc.SessionInfo; import org.uberfire.spaces.SpacesAPI; import static java.util.Arrays.asList; import static org.dashbuilder.transfer.DataTransferServices.COMPONENTS_EXPORT_PATH; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.Silent.class) public class DataTransferServicesTest { private IOService ioService; private FileSystem datasetsFS; private FileSystem perspectivesFS; private FileSystem navigationFS; private FileSystem systemFS; private DataTransferServices dataTransferServices; @Mock private DataSetDefRegistryCDI dataSetDefRegistryCDI; @Mock private Event dataSetDefRegisteredEvent; @Mock private Event pluginAddedEvent; @Mock SessionInfo sessionInfo; @Mock private Event navTreeChangedEvent; @Mock private NavTreeStorage navTreeStorage; @Mock DataSetDefJSONMarshaller dataSetDefJSONMarshaller; @Mock ComponentLoader externalComponentLoader; @Mock LayoutComponentHelper layoutComponentsHelper; Path componentsDir; @Before public void setup() { ioService = new IOServiceDotFileImpl(); componentsDir = Files.createTempDirectory("dashbuilder-components"); datasetsFS = createFileSystem("datasets"); perspectivesFS = createFileSystem("perspectives"); navigationFS = createFileSystem("navigation"); systemFS = createFileSystem("system"); when(dataSetDefRegistryCDI.getDataSetDefJsonMarshaller()).thenReturn(dataSetDefJSONMarshaller); when(externalComponentLoader.getExternalComponentsDir()).thenReturn(componentsDir.toString()); when(externalComponentLoader.isExternalComponentsEnabled()).thenReturn(true); dataTransferServices = new DataTransferServicesImpl(ioService, datasetsFS, perspectivesFS, navigationFS, systemFS, dataSetDefRegistryCDI, sessionInfo, dataSetDefRegisteredEvent, pluginAddedEvent, navTreeChangedEvent, navTreeStorage, externalComponentLoader, layoutComponentsHelper); } @After public void cleanFileSystems() { cleanFileSystem(datasetsFS); cleanFileSystem(perspectivesFS); cleanFileSystem(navigationFS); cleanFileSystem(systemFS); FileUtils.deleteQuietly(componentsDir.toFile()); } @Test @SuppressWarnings("serial") public void testDoExportEmptyFileSystems() throws Exception { String exportPath = dataTransferServices.doExport(DataTransferExportModel.exportAll()); assertTrue(exportPath.equals(getExpectedExportFileSystemPath())); assertEquals(new ArrayList() {{ add(getExpectedExportFilePath()); add("/readme.md"); }}, getFiles(systemFS)); ZipInputStream zis = getZipInputStream(); assertEquals(new ArrayList() {{ add(datasetsFS.getName() + "/readme.md"); add(perspectivesFS.getName() + "/readme.md"); add(navigationFS.getName() + "/readme.md"); add("VERSION"); }}, getFiles(zis)); } @Test @SuppressWarnings("serial") public void testDoExportNotEmptyFileSystems() throws Exception { createFile(datasetsFS, "definitions/dataset1.csv", "Test 1"); createFile(datasetsFS, "definitions/dataset1.dset", "Test ABC"); createFile(perspectivesFS, "page1/perspective_layout", "Test Page 1"); createFile(perspectivesFS, "page1/perspective_layout.plugin", "Test Page 1 Plugin"); createFile(navigationFS, "navtree.json", "{ }"); String exportPath = dataTransferServices.doExport(DataTransferExportModel.exportAll()); assertTrue(exportPath.equals(getExpectedExportFileSystemPath())); assertEquals(new ArrayList() {{ add(getExpectedExportFilePath()); add("/readme.md"); }}, getFiles(systemFS)); ZipInputStream zis = getZipInputStream(); assertEquals(new ArrayList() {{ add(datasetsFS.getName() + "/definitions/dataset1.csv"); add(datasetsFS.getName() + "/definitions/dataset1.dset"); add(datasetsFS.getName() + "/readme.md"); add(perspectivesFS.getName() + "/page1/perspective_layout"); add(perspectivesFS.getName() + "/page1/perspective_layout.plugin"); add(perspectivesFS.getName() + "/readme.md"); add(navigationFS.getName() + "/navtree.json"); add(navigationFS.getName() + "/readme.md"); add("VERSION"); }}, getFiles(zis)); } @Test @SuppressWarnings("serial") public void testDoExportFilteringDataSets() throws Exception { createFile(datasetsFS, "definitions/dataset1.csv", ""); createFile(datasetsFS, "definitions/dataset1.dset", ""); createFile(datasetsFS, "definitions/dataset2.dset", ""); createFile(perspectivesFS, "page1/perspective_layout", ""); createFile(perspectivesFS, "page1/perspective_layout.plugin", ""); createFile(navigationFS, "navtree.json", ""); DataSetDef def = mock(DataSetDef.class); when(def.getUUID()).thenReturn("dataset1"); DataTransferExportModel model = new DataTransferExportModel(Arrays.asList(def), Arrays.asList("page1", "page2"), true); String exportPath = dataTransferServices.doExport(model); assertTrue(exportPath.equals(getExpectedExportFileSystemPath())); ZipInputStream zis = getZipInputStream(); assertEquals(new ArrayList() {{ add(datasetsFS.getName() + "/definitions/dataset1.csv"); add(datasetsFS.getName() + "/definitions/dataset1.dset"); add(datasetsFS.getName() + "/readme.md"); add(perspectivesFS.getName() + "/page1/perspective_layout"); add(perspectivesFS.getName() + "/page1/perspective_layout.plugin"); add(perspectivesFS.getName() + "/readme.md"); add(navigationFS.getName() + "/navtree.json"); add(navigationFS.getName() + "/readme.md"); add("VERSION"); }}, getFiles(zis)); cleanFileSystems(); } @Test @SuppressWarnings("serial") public void testDoExportFilteringPages() throws Exception { createFile(datasetsFS, "definitions/dataset.csv", ""); createFile(datasetsFS, "definitions/dataset.dset", ""); createFile(perspectivesFS, "page1/perspective_layout", ""); createFile(perspectivesFS, "page1/perspective_layout.plugin", ""); createFile(perspectivesFS, "page2/perspective_layout", ""); createFile(perspectivesFS, "page2/perspective_layout.plugin", ""); createFile(navigationFS, "navtree.json", ""); DataSetDef def = mock(DataSetDef.class); when(def.getUUID()).thenReturn("dataset"); DataTransferExportModel model = new DataTransferExportModel(Arrays.asList(def), Arrays.asList("page2"), true); String exportPath = dataTransferServices.doExport(model); assertTrue(exportPath.equals(getExpectedExportFileSystemPath())); ZipInputStream zis = getZipInputStream(); assertEquals(new ArrayList() {{ add(datasetsFS.getName() + "/definitions/dataset.csv"); add(datasetsFS.getName() + "/definitions/dataset.dset"); add(datasetsFS.getName() + "/readme.md"); add(perspectivesFS.getName() + "/page2/perspective_layout"); add(perspectivesFS.getName() + "/page2/perspective_layout.plugin"); add(perspectivesFS.getName() + "/readme.md"); add(navigationFS.getName() + "/navtree.json"); add(navigationFS.getName() + "/readme.md"); add("VERSION"); }}, getFiles(zis)); cleanFileSystems(); } @Test @SuppressWarnings("serial") public void testDoExportWithoutNavigation() throws Exception { createFile(datasetsFS, "definitions/dataset.csv", ""); createFile(datasetsFS, "definitions/dataset.dset", ""); createFile(perspectivesFS, "page1/perspective_layout", ""); createFile(perspectivesFS, "page1/perspective_layout.plugin", ""); createFile(navigationFS, "navtree.json", ""); DataSetDef def = mock(DataSetDef.class); when(def.getUUID()).thenReturn("dataset"); DataTransferExportModel model = new DataTransferExportModel(Arrays.asList(def), Arrays.asList("page1"), false); String exportPath = dataTransferServices.doExport(model); assertTrue(exportPath.equals(getExpectedExportFileSystemPath())); ZipInputStream zis = getZipInputStream(); assertEquals(new ArrayList() {{ add(datasetsFS.getName() + "/definitions/dataset.csv"); add(datasetsFS.getName() + "/definitions/dataset.dset"); add(datasetsFS.getName() + "/readme.md"); add(perspectivesFS.getName() + "/page1/perspective_layout"); add(perspectivesFS.getName() + "/page1/perspective_layout.plugin"); add(perspectivesFS.getName() + "/readme.md"); add(navigationFS.getName() + "/readme.md"); add("VERSION"); }}, getFiles(zis)); cleanFileSystems(); } @Test public void testDoExportWithComponents() throws Exception { when(layoutComponentsHelper.findComponentsInTemplates((any()))).thenReturn(asList("c1")); createFile(perspectivesFS, "page1/perspective_layout", ""); createFile(perspectivesFS, "page1/perspective_layout.plugin", ""); createComponentFile("c1", "manifest.json", "manifest"); createComponentFile("c1", "index.html", "html"); createComponentFile("c1", "css/style.css", "style"); createComponentFile("c1", "js/index.js", "js"); // lost file in component Dir that should be ignored createComponentFile("lost", "lostfile", "ignore-me-import"); // Other component that is not used so it should not be exported createComponentFile("c2", "manifest.json", "manifest"); createComponentFile("c2", "index.html", "html"); createComponentFile("c2", "css/style.css", "style"); createComponentFile("c2", "js/index.js", "js"); dataTransferServices.doExport(DataTransferExportModel.exportAll()); ZipInputStream zis = getZipInputStream(); String[] expectedFiles = { datasetsFS.getName() + "/readme.md", perspectivesFS.getName() + "/page1/perspective_layout", perspectivesFS.getName() + "/page1/perspective_layout.plugin", perspectivesFS.getName() + "/readme.md", navigationFS.getName() + "/readme.md", COMPONENTS_EXPORT_PATH + "c1/js/index.js", COMPONENTS_EXPORT_PATH + "c1/css/style.css", COMPONENTS_EXPORT_PATH + "c1/index.html", COMPONENTS_EXPORT_PATH + "c1/manifest.json", "VERSION" }; Object[] actualList = getFiles(zis).toArray(); Arrays.sort(expectedFiles); Arrays.sort(actualList); assertArrayEquals(expectedFiles, actualList); cleanFileSystems(); } @Test @SuppressWarnings("serial") public void testDoExportIgnoringComponents() throws Exception { when(externalComponentLoader.isExternalComponentsEnabled()).thenReturn(false); when(externalComponentLoader.loadExternal()).thenReturn(asList(component("c1"))); createFile(perspectivesFS, "page1/perspective_layout", ""); createFile(perspectivesFS, "page1/perspective_layout.plugin", ""); createComponentFile("c1", "manifest.json", "manifest"); createComponentFile("c1", "index.html", "html"); createComponentFile("c1", "css/style.css", "style"); createComponentFile("c1", "js/index.js", "js"); dataTransferServices.doExport(DataTransferExportModel.exportAll()); ZipInputStream zis = getZipInputStream(); assertEquals(new ArrayList() {{ add(datasetsFS.getName() + "/readme.md"); add(perspectivesFS.getName() + "/page1/perspective_layout"); add(perspectivesFS.getName() + "/page1/perspective_layout.plugin"); add(perspectivesFS.getName() + "/readme.md"); add(navigationFS.getName() + "/readme.md"); add("VERSION"); }}, getFiles(zis)); cleanFileSystems(); } @Test @SuppressWarnings("serial") public void testDoExportWhenComponentsDirIsNotPresent() throws Exception { createFile(perspectivesFS, "page1/perspective_layout", ""); createFile(perspectivesFS, "page1/perspective_layout.plugin", ""); FileUtils.deleteQuietly(componentsDir.toFile()); dataTransferServices.doExport(DataTransferExportModel.exportAll()); ZipInputStream zis = getZipInputStream(); assertEquals(new ArrayList() {{ add(datasetsFS.getName() + "/readme.md"); add(perspectivesFS.getName() + "/page1/perspective_layout"); add(perspectivesFS.getName() + "/page1/perspective_layout.plugin"); add(perspectivesFS.getName() + "/readme.md"); add(navigationFS.getName() + "/readme.md"); add("VERSION"); }}, getFiles(zis)); cleanFileSystems(); } @Test @SuppressWarnings("serial") public void testDoImportNoZip() throws Exception { List filesImported = dataTransferServices.doImport(); assertEquals(new ArrayList(), filesImported); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(datasetsFS)); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(perspectivesFS)); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(navigationFS)); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(systemFS)); verify(dataSetDefRegisteredEvent, times(0)).fire(any()); verify(pluginAddedEvent, times(0)).fire(any()); verify(navTreeChangedEvent, times(0)).fire(any()); } @Test @SuppressWarnings("serial") public void testDoImportEmptyZip() throws Exception { moveZipToFileSystem("/empty.zip"); List filesImported = dataTransferServices.doImport(); assertEquals(new ArrayList(), filesImported); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(datasetsFS)); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(perspectivesFS)); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(navigationFS)); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(systemFS)); verify(dataSetDefRegisteredEvent, times(0)).fire(any()); verify(pluginAddedEvent, times(0)).fire(any()); verify(navTreeChangedEvent, times(0)).fire(any()); } @Test @SuppressWarnings("serial") public void testDoImportNotEmptyZip() throws Exception { moveZipToFileSystem("/import.zip"); List filesImported = dataTransferServices.doImport(); assertEquals(new ArrayList() {{ add("dashbuilder/datasets/readme.md"); add("dashbuilder/datasets/definitions/eb241039-1792-4d08-9596-b6c8d27dfe6b.csv"); add("dashbuilder/datasets/definitions/d1b24449-fe90-40d4-8cd7-f175b498c0bb.dset"); add("dashbuilder/datasets/definitions/8060a7f1-ef03-4ce9-a0a8-266301e79ff6.dset"); add("dashbuilder/datasets/definitions/eb241039-1792-4d08-9596-b6c8d27dfe6b.dset"); add("dashbuilder/datasets/definitions/7e68d20d-6807-4b86-8737-1d429afe9dbc.csv"); add("dashbuilder/datasets/definitions/d1b24449-fe90-40d4-8cd7-f175b498c0bb.csv"); add("dashbuilder/datasets/definitions/8060a7f1-ef03-4ce9-a0a8-266301e79ff6.csv"); add("dashbuilder/datasets/definitions/7e68d20d-6807-4b86-8737-1d429afe9dbc.dset"); add("dashbuilder/components/c2/manifest.json"); add("dashbuilder/components/c2/styles/level/styles.css"); add("dashbuilder/components/c2/index.html"); add("dashbuilder/components/c1/manifest.json"); add("dashbuilder/components/c1/images/db_logo.png"); add("dashbuilder/components/c1/scripts/index.js"); add("dashbuilder/components/c1/index.html"); add("dashbuilder/perspectives/page3/perspective_layout"); add("dashbuilder/perspectives/page3/perspective_layout.plugin"); add("dashbuilder/perspectives/readme.md"); add("dashbuilder/perspectives/page4/perspective_layout"); add("dashbuilder/perspectives/page4/perspective_layout.plugin"); add("dashbuilder/perspectives/page2/perspective_layout"); add("dashbuilder/perspectives/page2/perspective_layout.plugin"); add("dashbuilder/perspectives/page1/perspective_layout"); add("dashbuilder/perspectives/page1/perspective_layout.plugin"); add("dashbuilder/navigation/readme.md"); add("dashbuilder/navigation/navigation/navtree.json"); }}, filesImported); assertEquals(new ArrayList() {{ add("/definitions/7e68d20d-6807-4b86-8737-1d429afe9dbc.csv"); add("/definitions/7e68d20d-6807-4b86-8737-1d429afe9dbc.dset"); add("/definitions/8060a7f1-ef03-4ce9-a0a8-266301e79ff6.csv"); add("/definitions/8060a7f1-ef03-4ce9-a0a8-266301e79ff6.dset"); add("/definitions/d1b24449-fe90-40d4-8cd7-f175b498c0bb.csv"); add("/definitions/d1b24449-fe90-40d4-8cd7-f175b498c0bb.dset"); add("/definitions/eb241039-1792-4d08-9596-b6c8d27dfe6b.csv"); add("/definitions/eb241039-1792-4d08-9596-b6c8d27dfe6b.dset"); add("/readme.md"); }}, getFiles(datasetsFS)); assertEquals(new ArrayList() {{ add("/page1/perspective_layout"); add("/page1/perspective_layout.plugin"); add("/page2/perspective_layout"); add("/page2/perspective_layout.plugin"); add("/page3/perspective_layout"); add("/page3/perspective_layout.plugin"); add("/page4/perspective_layout"); add("/page4/perspective_layout.plugin"); add("/readme.md"); }}, getFiles(perspectivesFS)); assertEquals(new ArrayList() {{ add("/navigation/navtree.json"); add("/readme.md"); }}, getFiles(navigationFS)); assertEquals(new ArrayList() {{ add("/readme.md"); }}, getFiles(systemFS)); List expectedComponents = new ArrayList() {{ add("c1/index.html"); add("c1/scripts/index.js"); add("c1/images/db_logo.png"); add("c1/manifest.json"); add("c2/index.html"); add("c2/styles/level/styles.css"); add("c2/manifest.json"); }}; expectedComponents.removeAll(getFiles(componentsDir)); assertTrue(expectedComponents.isEmpty()); verify(dataSetDefRegisteredEvent, times(4)).fire(any()); verify(pluginAddedEvent, times(4)).fire(any()); verify(navTreeChangedEvent, times(1)).fire(any()); } @Test public void testAssetsToImport() throws Exception { final String PAGE_ID = "page"; final String DS_CSV = "ds.csv"; final String DS = "ds.dset"; final String DS_CONTENT = "TEST_CONTENT"; final String DS_NAME = "test_dataset"; final String PAGE = PAGE_ID + "/perspective_layout"; final String PAGE_PLUGIN = PAGE_ID + "/perspective_layout.plugin"; DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.isPublic()).thenReturn(true); when(dataSetDef.getName()).thenReturn(DS_NAME); when(dataSetDefJSONMarshaller.fromJson(DS_CONTENT)).thenReturn(dataSetDef); createFile(datasetsFS, DS, DS_CONTENT); createFile(datasetsFS, DS_CSV, ""); createFile(perspectivesFS, PAGE, ""); createFile(perspectivesFS, PAGE_PLUGIN, ""); ExportInfo exportInfo = dataTransferServices.exportInfo(); assertEquals(1, exportInfo.getDatasetsDefinitions().size()); assertEquals(DS_NAME, exportInfo.getDatasetsDefinitions().get(0).getName()); assertEquals(1, exportInfo.getPages().size()); assertEquals(PAGE_ID, exportInfo.getPages().get(0)); cleanFileSystems(); } @Test public void testAssetsToImportNoFiles() { ExportInfo assetsToExport = dataTransferServices.exportInfo(); assertTrue(assetsToExport.getDatasetsDefinitions().isEmpty()); assertTrue(assetsToExport.getPages().isEmpty()); } @SuppressWarnings("serial") private FileSystem createFileSystem(String name) { String path = new StringBuilder().append("git://dashbuilder") .append(File.separator) .append(name) .toString(); try { return ioService.newFileSystem(URI.create(path), new HashMap() {{ put("init", Boolean.TRUE); }}); } catch (Exception e) { return ioService.getFileSystem(URI.create(path)); } } @Test public void testShouldNotExposePrivateDS() throws Exception { final String DS = "ds.dset"; final String DS_CONTENT = "TEST_CONTENT"; final String DS_NAME = "test_dataset"; DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.isPublic()).thenReturn(false); when(dataSetDef.getName()).thenReturn(DS_NAME); when(dataSetDefJSONMarshaller.fromJson(DS_CONTENT)).thenReturn(dataSetDef); createFile(datasetsFS, DS, DS_CONTENT); ExportInfo assetsToExport = dataTransferServices.exportInfo(); assertTrue(assetsToExport.getDatasetsDefinitions().isEmpty()); cleanFileSystems(); } private Path createFile(FileSystem fs, String filename, String data) { Path path = fs.getRootDirectories().iterator().next(); Path filePath = path.resolve(filename); ioService.write(filePath, data); return filePath; } private Path createComponentFile(String componentId, String filename, String data) { Path componentPath = componentsDir.resolve(componentId); Path componentFile = componentPath.resolve(filename); componentFile.getParent().toFile().mkdirs(); ioService.write(componentFile, data); return componentFile; } private List getFiles(Path root) { List files = new ArrayList<>(); Files.walkFileTree(root, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) throws IOException { files.add(path.toString().replaceAll(componentsDir.toString() + "/", "")); return FileVisitResult.CONTINUE; } }); return files; } private List getFiles(FileSystem fs) { List files = new ArrayList<>(); Path root = fs.getRootDirectories().iterator().next(); Files.walkFileTree(root, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) throws IOException { files.add(path.toString()); return FileVisitResult.CONTINUE; } }); return files; } private List getFiles(ZipInputStream zis) { List files = new ArrayList<>(); ZipEntry entry = null; try { while ((entry = zis.getNextEntry()) != null) { files.add(entry.getName()); } } catch (Exception e) { e.printStackTrace(); } return files; } private String getExpectedExportFilePath() { return new StringBuilder().append(File.separator) .append(DataTransferServices.FILE_PATH) .append(File.separator) .append(DataTransferServices.EXPORT_FILE_NAME) .toString(); } private String getExpectedImportFilePath() { return new StringBuilder().append(File.separator) .append(DataTransferServices.FILE_PATH) .append(File.separator) .append(DataTransferServices.IMPORT_FILE_NAME) .toString(); } private String getExpectedExportFileSystemPath() { return new StringBuilder().append("git://") .append(systemFS.getName()) .append(getExpectedExportFilePath()) .toString(); } private void moveZipToFileSystem(String path) { URL url = DataTransferServicesTest.class.getResource(path); String sourceLocation = new StringBuilder().append(SpacesAPI.Scheme.FILE) .append("://") .append(url.toString()) .toString(); Path source = Paths.get(URI.create(sourceLocation)); Path target = systemFS.getRootDirectories() .iterator() .next() .resolve(DataTransferServices.FILE_PATH) .resolve(DataTransferServices.IMPORT_FILE_NAME); ioService.write(target, Files.readAllBytes(source)); } private void cleanFileSystem(FileSystem fs) { for (String file : getFiles(fs)) { if (file.endsWith("readme.md")) { continue; } String path = new StringBuilder().append("git://") .append(fs.getName()) .append(file) .toString(); ioService.delete(Paths.get(URI.create(path))); } } private ZipInputStream getZipInputStream() { Path path = Paths.get(URI.create(new StringBuilder().append("git://") .append(systemFS.getName()) .append(getExpectedExportFilePath()) .toString())); return new ZipInputStream(new ByteArrayInputStream(ioService.readAllBytes(path))); } public ExternalComponent component(String id) { return new ExternalComponent(id, id, "", false, Collections.emptyList()); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/java/org/dashbuilder/transfer/ExportModelValidationServiceImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.navigation.service.PerspectivePluginServices; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.ext.layout.editor.api.editor.LayoutColumn; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class ExportModelValidationServiceImplTest { ExportModelValidationServiceImpl dataTransferExportValidator; @Mock PerspectivePluginServices perspectivePluginServices; @Mock DisplayerSettingsJSONMarshaller marshaller; @Before public void init() { dataTransferExportValidator = new ExportModelValidationServiceImpl(perspectivePluginServices, marshaller); } @Test public void testTryingToExportPageWithMissingDataSet() { String page1 = "page1"; String ds1 = "ds1"; String json1 = "json1"; DisplayerSettings ds = registerDSMock(ds1); when(marshaller.fromJsonString(json1)).thenReturn(ds); LayoutTemplate ltForPage1 = createTemplate(json1); when(perspectivePluginServices.getLayoutTemplate(page1)).thenReturn(ltForPage1); DataTransferExportModel model = new DataTransferExportModel(Collections.emptyList(), Arrays.asList(page1), true); Map> missingDataSets = dataTransferExportValidator.checkMissingDatasets(model); assertTrue(missingDataSets.containsKey(page1)); assertEquals(ds1, missingDataSets.get(page1).get(0)); } @Test public void testSuccessExportWithAllDatasets() { String page1 = "page1"; String ds1 = "ds1"; String json1 = "json1"; DataSetDef def = mock(DataSetDef.class); when(def.getUUID()).thenReturn(ds1); DisplayerSettings ds = registerDSMock(ds1); when(marshaller.fromJsonString(json1)).thenReturn(ds); LayoutTemplate ltForPage1 = createTemplate(json1); when(perspectivePluginServices.getLayoutTemplate(page1)).thenReturn(ltForPage1); DataTransferExportModel model = new DataTransferExportModel(Arrays.asList(def), Arrays.asList(page1), true); Map> missingDataSets = dataTransferExportValidator.checkMissingDatasets(model); assertTrue(missingDataSets.isEmpty()); assertFalse(missingDataSets.containsKey(page1)); } private DisplayerSettings registerDSMock(String ds1) { DataSetLookup lookup = mock(DataSetLookup.class); when(lookup.getDataSetUUID()).thenReturn(ds1); DisplayerSettings ds = mock(DisplayerSettings.class); when(ds.getDataSetLookup()).thenReturn(lookup); return ds; } public LayoutTemplate createTemplate(String...jsonValues) { LayoutRow r1 = new LayoutRow(); LayoutColumn lc1r1 = new LayoutColumn(""); LayoutComponent cplc1r1 = new LayoutComponent(); lc1r1.add(cplc1r1); LayoutColumn lc2r1 = new LayoutColumn(""); LayoutComponent cplc2r1 = new LayoutComponent(); lc2r1.add(cplc2r1); r1.add(lc1r1); r1.add(lc2r1); List createdRows = new ArrayList<>(); for (String jsonValue : jsonValues) { LayoutRow row = new LayoutRow(); LayoutColumn lc1r = new LayoutColumn(""); LayoutComponent cp1lc1r = new LayoutComponent(); lc1r.add(cp1lc1r); LayoutColumn lc2r = new LayoutColumn(""); LayoutComponent lc2lc2r = new LayoutComponent(); lc2lc2r.addProperty("json", jsonValue); lc2r.add(lc2lc2r); row.add(lc1r); row.add(lc2r); createdRows.add(row); } LayoutTemplate lt = new LayoutTemplate(""); lt.addRow(r1); createdRows.forEach(lt::addRow); return lt; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/java/org/dashbuilder/transfer/LayoutComponentHelperTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.Arrays; import java.util.List; import org.dashbuilder.external.model.ExternalComponent; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.ext.layout.editor.api.PerspectiveServices; import org.uberfire.ext.layout.editor.api.editor.LayoutColumn; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static java.util.Collections.singletonList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class LayoutComponentHelperTest { @Mock PerspectiveServices perspectiveServices; @InjectMocks LayoutComponentHelper layoutComponentsHelper; @Test public void testComponentId() { String c1 = "c1"; String c2 = "c2"; LayoutTemplate lt = createLayoutTemplate("lt", c1, c2); when(perspectiveServices.listLayoutTemplates()).thenReturn(singletonList(lt)); List components = layoutComponentsHelper.findComponentsInTemplates(p -> true); assertEquals(2, components.size()); assertEquals(components, Arrays.asList(c1, c2)); } public void testNoComponentId() { LayoutTemplate lt = createLayoutTemplate("lt"); when(perspectiveServices.listLayoutTemplates()).thenReturn(singletonList(lt)); List components = layoutComponentsHelper.findComponentsInTemplates(p -> true); assertTrue(components.isEmpty()); } public void testPageFilter() { String c1 = "c1"; LayoutTemplate lt = createLayoutTemplate("lt", c1); when(perspectiveServices.listLayoutTemplates()).thenReturn(singletonList(lt)); List components = layoutComponentsHelper.findComponentsInTemplates(p -> false); assertTrue(components.isEmpty()); } private LayoutTemplate createLayoutTemplate(String name, String... componentIds) { LayoutTemplate lt = new LayoutTemplate(name); LayoutRow lr = new LayoutRow(); LayoutColumn lc = new LayoutColumn(""); lr.add(lc); lt.addRow(lr); for (String componentId : componentIds) { LayoutComponent lComp = new LayoutComponent(); lComp.addProperty(ExternalComponent.COMPONENT_ID_KEY, componentId); lc.add(lComp); } return lt; } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/java/org/dashbuilder/transfer/rest/DataTransferResourceTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer.rest; import java.io.IOException; import javax.ws.rs.core.Response; import org.dashbuilder.transfer.DataTransferServices; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.io.IOService; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class DataTransferResourceTest { @Mock private DataTransferServices dataTransferServices; @Mock private IOService ioService; @InjectMocks DataTransferResource dataTransferResource; @Test public void testSuccessExport() throws IOException { when(dataTransferServices.doExport(any())).thenReturn("file://."); Response response = dataTransferResource.export(); assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); } @Test public void testBadExport() throws IOException { when(dataTransferServices.doExport(any())).thenThrow(new IOException()); Response response = dataTransferResource.export(); assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus()); } } ================================================ FILE: dashbuilder/dashbuilder-backend/dashbuilder-services/src/test/resources/META-INF/services/org.uberfire.java.nio.file.spi.FileSystemProvider ================================================ # # Copyright 2019 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # org.uberfire.java.nio.fs.jgit.JGitFileSystemProvider org.uberfire.java.nio.fs.file.SimpleFileSystemProvider # file system provider, also default (1st) ================================================ FILE: dashbuilder/dashbuilder-backend/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT ../pom.xml dashbuilder-backend pom Dashbuilder Backend dashbuilder-dataset-cdi dashbuilder-navigation-backend dashbuilder-services dashbuilder-kie-server-backend dashbuilder-external-backend ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-cms-client jar Dashbuilder CMS Client Dashbuilder Content Manager System Client org.dashbuilder dashbuilder-common-client org.dashbuilder dashbuilder-navigation-api org.dashbuilder dashbuilder-navigation-client org.dashbuilder dashbuilder-services-api org.jboss.errai errai-common org.jboss.errai errai-ioc org.jboss.errai errai-ui com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 org.gwtbootstrap3 gwtbootstrap3-extras org.uberfire uberfire-js org.uberfire uberfire-server-all org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-api org.uberfire uberfire-backend-api org.uberfire uberfire-client-api provided org.uberfire uberfire-workbench-client provided org.uberfire uberfire-runtime-plugins-api org.uberfire uberfire-runtime-plugins-client provided org.uberfire uberfire-runtime-plugins-backend org.uberfire uberfire-layout-editor-client provided org.uberfire uberfire-layout-editor-api org.uberfire uberfire-layout-editor-backend org.uberfire uberfire-widgets-commons provided org.uberfire uberfire-simple-docks-client provided org.uberfire uberfire-commons-editor-client provided com.google.gwt.gwtmockito gwtmockito test org.uberfire uberfire-testing-utils test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/ContentManagerEntryPoint.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ui.shared.api.annotations.Bundle; @EntryPoint @Bundle("resources/i18n/ContentManagerConstants.properties") public class ContentManagerEntryPoint { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/layout/editor/PerspectiveDragComponent.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.layout.editor; import java.util.Map; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.client.cms.widget.PerspectiveWidget; import org.gwtbootstrap3.client.ui.Modal; import org.uberfire.ext.layout.editor.client.api.HasModalConfiguration; import org.uberfire.ext.layout.editor.client.api.ModalConfigurationContext; import org.uberfire.ext.layout.editor.client.api.RenderingContext; import org.uberfire.ext.plugin.client.perspective.editor.api.PerspectiveEditorCoreComponent; import org.uberfire.ext.plugin.model.Plugin; import static org.dashbuilder.navigation.layout.NavDragComponentSettings.PERSPECTIVE_ID; /** * Runtime perspective drag component. */ @Dependent public class PerspectiveDragComponent implements PerspectiveEditorCoreComponent, HasModalConfiguration { PerspectiveDragConfigModal perspectiveDragConfigModal; PerspectiveWidget perspectiveWidget; @Inject public PerspectiveDragComponent(PerspectiveDragConfigModal perspectiveDragConfigModal, PerspectiveWidget perspectiveWidget) { this.perspectiveDragConfigModal = perspectiveDragConfigModal; this.perspectiveWidget = perspectiveWidget; } @Override public String getDragComponentTitle() { return ContentManagerConstants.INSTANCE.perspectiveDragComponent(); } @Override public String getDragComponentIconClass() { return "fa fa-file-o"; } @Override public IsWidget getPreviewWidget(RenderingContext ctx) { return getShowWidget(ctx); } @Override public IsWidget getShowWidget(RenderingContext ctx) { Map properties = ctx.getComponent().getProperties(); String perspectiveId = properties.get(PERSPECTIVE_ID); perspectiveWidget.showPerspective(perspectiveId); return perspectiveWidget; } @Override public Modal getConfigurationModal(ModalConfigurationContext ctx) { Map properties = ctx.getComponentProperties(); String perspectiveId = properties.get(PERSPECTIVE_ID); perspectiveDragConfigModal.setOnOk(() -> perspectiveSelectionOk(ctx)); perspectiveDragConfigModal.setOnCancel(() -> perspectiveSelectionCancel(ctx)); perspectiveDragConfigModal.show(perspectiveId); return ((PerspectiveDragConfigModalView) perspectiveDragConfigModal.getView()).getModal(); } protected void perspectiveSelectionOk(ModalConfigurationContext ctx) { Plugin perspective = perspectiveDragConfigModal.getSelectedItem(); ctx.setComponentProperty(PERSPECTIVE_ID, perspective.getName()); ctx.configurationFinished(); } protected void perspectiveSelectionCancel(ModalConfigurationContext ctx) { ctx.configurationCancelled(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/layout/editor/PerspectiveDragConfigModal.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.layout.editor; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.UberView; import org.uberfire.ext.plugin.model.Plugin; @Dependent public class PerspectiveDragConfigModal implements IsWidget { public interface View extends UberView { void clearItems(); void addItem(String name, Command onSelect); void setCurrentSelection(String name); void setHelpText(String text); void show(); void hide(); } View view; PerspectivePluginManager perspectivePluginManager; PerspectiveTreeProvider perspectiveTreeProvider; Plugin selectedItem = null; Command onOk = null; Command onCancel = null; @Inject public PerspectiveDragConfigModal(View view, PerspectivePluginManager perspectivePluginManager, PerspectiveTreeProvider perspectiveTreeProvider) { this.view = view; this.perspectivePluginManager = perspectivePluginManager; this.perspectiveTreeProvider = perspectiveTreeProvider; this.view.init(this); this.view.setHelpText(ContentManagerConstants.INSTANCE.perspectiveDragComponentHelp()); } @Override public Widget asWidget() { return view.asWidget(); } public View getView() { return view; } public void setOnOk(Command onOk) { this.onOk = onOk; } public void setOnCancel(Command onCancel) { this.onCancel = onCancel; } public Plugin getSelectedItem() { return selectedItem; } public void show(String selectedPerspectiveId) { view.clearItems(); addItems(selectedPerspectiveId); view.show(); } private void addItems(String selectedItemId) { perspectivePluginManager.getPerspectivePlugins(plugins -> { for (Plugin plugin : plugins) { String perspectiveName = perspectiveTreeProvider.getPerspectiveName(plugin.getName()); view.addItem(perspectiveName, () -> onItemSelected(plugin)); if (selectedItemId != null && plugin.getName().equals(selectedItemId)) { view.setCurrentSelection(perspectiveName); } } }); } // View callbacks public void onItemSelected(Plugin plugin) { selectedItem = plugin; view.setCurrentSelection(selectedItem.getName()); } void onOk() { if (selectedItem != null) { view.hide(); if (onOk != null) { onOk.execute(); } } } void onCancel() { view.hide(); if (onCancel != null) { onCancel.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/layout/editor/PerspectiveDragConfigModalView.css ================================================ .uf-pdc-selector-body { margin: 15px; } .uf-pdc-selector-button { min-width: 200px; text-align: left; } .uf-pdc-selector-menu { margin-left: 20px; min-width: 200px; } .uf-pdc-selector-caret { float: right; margin-top: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/layout/editor/PerspectiveDragConfigModalView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/layout/editor/PerspectiveDragConfigModalView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.layout.editor; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.gwtbootstrap3.client.ui.Modal; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Label; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.TemplateWidgetMapper; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.SinkNative; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.editor.commons.client.file.popups.CommonModalBuilder; import org.uberfire.ext.widgets.common.client.common.popups.BaseModal; import org.uberfire.ext.widgets.common.client.common.popups.ButtonPressed; @Templated public class PerspectiveDragConfigModalView implements PerspectiveDragConfigModal.View { PerspectiveDragConfigModal presenter; BaseModal modal; ButtonPressed buttonPressed = ButtonPressed.CLOSE; @Inject @DataField Div body; @Inject @DataField Div footer; @DataField @Inject Span selectorHelp; @DataField @Inject Span currentSelection; @DataField @Inject UnorderedList selectorItems; @DataField @Inject Label navItemLabel; @Override public void init(PerspectiveDragConfigModal presenter) { this.presenter = presenter; currentSelection.setTextContent(ContentManagerConstants.INSTANCE.perspectiveDragSelectorHint()); navItemLabel.setTextContent(ContentManagerConstants.INSTANCE.perspectiveDragSelectorLabel()); modal = new CommonModalBuilder() .addHeader(ContentManagerConstants.INSTANCE.perspectiveDragComponentHeader()) .addBody( body ) .addFooter( footer ) .build(); modal.addHiddenHandler(hiddenEvent -> { if (ButtonPressed.CLOSE.equals(buttonPressed)) { presenter.onCancel(); } }); modal.setWidth( "960px" ); } public Modal getModal() { return modal; } @Override public Widget asWidget() { return TemplateWidgetMapper.get(modal); } @Override public void show() { modal.show(); } @Override public void hide() { modal.hide(); } @Override public void clearItems() { DOMUtil.removeAllChildren(selectorItems); } @Override public void setHelpText(String text) { selectorHelp.setTitle(text); } @Override public void setCurrentSelection(String name) { currentSelection.setTextContent(name); } @Override public void addItem(String name, Command onSelect) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.setInnerText(name); LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); selectorItems.appendChild((Node) li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if(Event.ONCLICK == event.getTypeInt()) { onSelect.execute(); } }); } @SinkNative(Event.ONCLICK) @EventHandler("okButton") public void okClick(final Event event) { buttonPressed = ButtonPressed.OK; presenter.onOk(); } @SinkNative(Event.ONCLICK) @EventHandler("cancelButton") public void cancelClick(final Event event) { buttonPressed = ButtonPressed.CANCEL; presenter.onCancel(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/perspective/ContentManagerPerspective.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.perspective; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.cms.screen.explorer.NavigationExplorerScreen; import org.dashbuilder.client.cms.screen.explorer.PerspectivesExplorerScreen; import org.dashbuilder.client.cms.screen.home.ContentManagerHomeScreen; import org.gwtbootstrap3.client.ui.constants.IconType; import org.jboss.errai.ioc.client.api.AfterInitialization; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.docks.UberfireDock; import org.uberfire.client.workbench.docks.UberfireDockPosition; import org.uberfire.client.workbench.docks.UberfireDocks; import org.uberfire.client.workbench.events.PlaceHiddenEvent; import org.uberfire.client.workbench.panels.impl.MultiListWorkbenchPanelPresenter; import org.uberfire.ext.layout.editor.client.LayoutComponentPaletteScreen; import org.uberfire.ext.layout.editor.client.LayoutEditorPropertiesScreen; import org.uberfire.ext.layout.editor.client.widgets.LayoutEditorPropertiesPresenter; import org.uberfire.ext.plugin.client.perspective.editor.PerspectiveEditorPresenter; import org.uberfire.ext.plugin.client.perspective.editor.events.PerspectiveEditorFocusEvent; import org.uberfire.lifecycle.OnOpen; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @ApplicationScoped @WorkbenchPerspective(identifier = ContentManagerPerspective.PERSPECTIVE_ID) public class ContentManagerPerspective { public static final String PERSPECTIVE_ID = "ContentManagerPerspective"; @Inject ContentManagerI18n i18n; @Inject UberfireDocks uberfireDocks; @Inject LayoutEditorPropertiesPresenter propertiesPresenter; UberfireDock perspectivesExplorerDock; UberfireDock navigationExplorerDock; UberfireDock componentPaletteDock; UberfireDock propertiesEditorDock; boolean perspectiveVisible = true; boolean propertiesEditorVisible = false; @Perspective public PerspectiveDefinition getPerspective() { return buildPerspective(); } private PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(MultiListWorkbenchPanelPresenter.class.getName()); perspective.setName(ContentManagerConstants.INSTANCE.contentManagerHome()); perspective.getRoot().addPart(ContentManagerHomeScreen.SCREEN_ID); return perspective; } @AfterInitialization public void init() { perspectivesExplorerDock = new UberfireDock(UberfireDockPosition.WEST, IconType.FILE_TEXT_O.toString(), new DefaultPlaceRequest(PerspectivesExplorerScreen.SCREEN_ID), PERSPECTIVE_ID).withSize(330) .withLabel(i18n.capitalizeFirst(i18n.getPerspectivesResourceName())); navigationExplorerDock = new UberfireDock(UberfireDockPosition.WEST, IconType.NAVICON.toString(), new DefaultPlaceRequest(NavigationExplorerScreen.SCREEN_ID), PERSPECTIVE_ID).withSize(330) .withLabel(ContentManagerConstants.INSTANCE.contentExplorerNavigation()); componentPaletteDock = new UberfireDock(UberfireDockPosition.WEST, IconType.CUBES.toString(), new DefaultPlaceRequest(LayoutComponentPaletteScreen.SCREEN_ID), PERSPECTIVE_ID).withSize(330) .withLabel(ContentManagerConstants.INSTANCE.componentPalette()); propertiesEditorDock = new UberfireDock(UberfireDockPosition.EAST, IconType.PENCIL.toString(), new DefaultPlaceRequest(LayoutEditorPropertiesScreen.SCREEN_ID), PERSPECTIVE_ID).withSize(300) .withLabel(ContentManagerConstants.INSTANCE.propertiesEditor()); uberfireDocks.add(perspectivesExplorerDock); uberfireDocks.add(navigationExplorerDock); } private void refreshWestDocks(boolean show, UberfireDock dockToOpen) { if (show && !perspectiveVisible) { uberfireDocks.add(componentPaletteDock); perspectiveVisible = true; } if (!show && perspectiveVisible) { uberfireDocks.remove(componentPaletteDock); perspectiveVisible = false; } uberfireDocks.show(UberfireDockPosition.WEST, PERSPECTIVE_ID); if (dockToOpen != null) { uberfireDocks.open(dockToOpen); } } private void refreshEastDocks(boolean show, UberfireDock dockToOpen) { if (show && !propertiesEditorVisible) { uberfireDocks.add(propertiesEditorDock); propertiesEditorVisible = true; uberfireDocks.show(UberfireDockPosition.EAST, PERSPECTIVE_ID); if (dockToOpen != null) { uberfireDocks.open(dockToOpen); } } if (!show && propertiesEditorVisible) { uberfireDocks.remove(propertiesEditorDock); propertiesEditorVisible = false; uberfireDocks.hide(UberfireDockPosition.EAST, PERSPECTIVE_ID); } } @OnOpen public void onOpen() { refreshWestDocks(false, perspectivesExplorerDock); } public void onPerspectiveEditorFocus(@Observes PerspectiveEditorFocusEvent event) { refreshWestDocks(true, componentPaletteDock); refreshEastDocks(true, propertiesEditorDock); propertiesPresenter.edit(event.getLayoutEditor()); } public void onPerspectiveEditorHidden(@Observes PlaceHiddenEvent event) { String placeId = event.getPlace().getIdentifier(); if (PerspectiveEditorPresenter.ID.equals(placeId)) { refreshWestDocks(false, null); refreshEastDocks(false, null); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/perspective/DataTransferPerspective.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.perspective; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.cms.screen.transfer.DataTransferScreen; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @ApplicationScoped @WorkbenchPerspective(identifier = DataTransferPerspective.ID) public class DataTransferPerspective { public static final String ID = "DataTransferPerspective"; public static final String NAME = "DataTransfer"; @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl( StaticWorkbenchPanelPresenter.class.getName()); perspective.getRoot().addPart( new PartDefinitionImpl( new DefaultPlaceRequest(DataTransferScreen.ID))); perspective.setName(NAME); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/resources/i18n/ContentManagerConstants.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface ContentManagerConstants extends Messages { public static final ContentManagerConstants INSTANCE = GWT.create(ContentManagerConstants.class); String contentExplorerNew(); String contentExplorerNavigation(); String navigationTreeItem(); String contentExplorerTopMenu(); String contentManagerHome(); String contentManagerHomeTitle(); String contentManagerHomeWelcome(); String contentManagerHomeCreate(); String contentManagerNavigationChanged(); String contentManagerHomeNewPerspective(String resourceType); String componentPalette(); String propertiesEditor(); String perspective(); String perspectives(); String noPerspectives(); String perspectiveDragComponent(); String perspectiveDragComponentHeader(); String perspectiveDragComponentHelp(); String perspectiveDragSelectorHint(); String perspectiveDragSelectorLabel(); String perspectiveDragNotFoundError(); String perspectiveInfiniteRecursionError(); String newPerspectivePopUpViewName(); String newPerspectivePopUpViewNameHelp(); String newPerspectivePopUpViewStyle(); String newPerspectivePopUpViewStyleHelp(); String newPerspectivePopUpViewFluid(); String newPerspectivePopUpViewPage(); String newPerspectivePopUpViewCancel(); String newPerspectivePopUpViewOk(); String newPerspectivePopUpViewTitle(); String newPerspectivePopUpViewErrorEmptyName(); String newPerspectivePopUpViewErrorInvalidName(); String newPerspectivePopUpViewErrorDuplicatedName(); String workbenchPartTitle(); String dataTransferPopUpViewTitle(); String importResultMessageOK(int count); String importResultMessageNoData(); String exportOK(); String importOK(); String exportError(); String importError(); String exportText(); String importText(); String dataTransferExportPopUpViewTitle(); String dataTransferExportError(); String loadAssetsToExport(); String pageLabel(); String pagesLabel(); String datasetLabel(); String datasetsLabel(); String exportWizardTitle(); String loadingExportWizard(); String preparingExportDownload(); String pageMissingDataSets(String page); String validatingExport(); String exportWizardHeadingSuccess(); String exportWizardHeadingError(); String noPagesExported(); String missingDependencies(); String nothingToExport(); String navigationHelpText(); String validationError(); String openHelpText(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/resources/i18n/ContentManagerI18n.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.resources.i18n; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class ContentManagerI18n { String contentExplorerNew = ContentManagerConstants.INSTANCE.contentExplorerNew(); String contentExplorerNavigation = ContentManagerConstants.INSTANCE.contentExplorerNavigation(); String contentExplorerTopMenu = ContentManagerConstants.INSTANCE.contentExplorerTopMenu(); String contentManagerHome = ContentManagerConstants.INSTANCE.contentManagerHome(); String contentManagerHomeTitle = ContentManagerConstants.INSTANCE.contentManagerHomeTitle(); String contentManagerHomeWelcome = ContentManagerConstants.INSTANCE.contentManagerHomeWelcome(); String contentManagerHomeCreate = ContentManagerConstants.INSTANCE.contentManagerHomeCreate(); String contentManagerNavigationChanged = ContentManagerConstants.INSTANCE.contentManagerNavigationChanged(); String perspectiveResourceName = ContentManagerConstants.INSTANCE.perspective(); String perspectivesResourceName = ContentManagerConstants.INSTANCE.perspectives(); String noPerspectives = ContentManagerConstants.INSTANCE.noPerspectives(); public String capitalizeFirst(String input) { return input.substring(0, 1).toUpperCase() + input.substring(1); } public String lowerCaseFirst(String input) { return input.substring(0, 1).toLowerCase() + input.substring(1); } public String getContentExplorerNavigation() { return contentExplorerNavigation; } public void setContentExplorerNavigation(String contentExplorerNavigation) { this.contentExplorerNavigation = contentExplorerNavigation; } public String getContentExplorerTopMenu() { return contentExplorerTopMenu; } public void setContentExplorerTopMenu(String contentExplorerTopMenu) { this.contentExplorerTopMenu = contentExplorerTopMenu; } public String getContentExplorerNew() { return contentExplorerNew; } public void setContentExplorerNew(String contentExplorerNew) { this.contentExplorerNew = contentExplorerNew; } public String getContentManagerHome() { return contentManagerHome; } public void setContentManagerHome(String contentManagerHome) { this.contentManagerHome = contentManagerHome; } public String getContentManagerHomeTitle() { return contentManagerHomeTitle; } public void setContentManagerHomeTitle(String contentManagerHomeTitle) { this.contentManagerHomeTitle = contentManagerHomeTitle; } public String getContentManagerHomeWelcome() { return contentManagerHomeWelcome; } public void setContentManagerHomeWelcome(String contentManagerHomeWelcome) { this.contentManagerHomeWelcome = contentManagerHomeWelcome; } public String getContentManagerHomeCreate() { return contentManagerHomeCreate; } public void setContentManagerHomeCreate(String contentManagerHomeCreate) { this.contentManagerHomeCreate = contentManagerHomeCreate; } public String getContentManagerHomeNewPerspectiveLink() { String resType = capitalizeFirst(perspectiveResourceName); return ContentManagerConstants.INSTANCE.contentManagerHomeNewPerspective(resType); } public String getContentManagerHomeNewPerspectiveButton() { String resType = capitalizeFirst(perspectiveResourceName); return capitalizeFirst(ContentManagerConstants.INSTANCE.contentManagerHomeNewPerspective(resType)); } public String getContentManagerNavigationChanged() { return contentManagerNavigationChanged; } public void setContentManagerNavigationChanged(String contentManagerNavigationChanged) { this.contentManagerNavigationChanged = contentManagerNavigationChanged; } public String getPerspectiveResourceName() { return perspectiveResourceName; } public String getPerspectivesResourceName() { return perspectivesResourceName; } public void setPerspectiveResourceName(String perspectiveResourceName) { this.perspectiveResourceName = perspectiveResourceName; } public void setPerspectivesResourceName(String perspectivesResourceName) { this.perspectivesResourceName = perspectivesResourceName; } public String getNoPerspectives() { return noPerspectives; } public void setNoPerspectives(String noPerspectives) { this.noPerspectives = noPerspectives; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/explorer/NavigationExplorerScreen.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.explorer; import java.util.function.Consumer; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.event.NavTreeLoadedEvent; import org.dashbuilder.navigation.event.NavTreeChangedEvent; import org.dashbuilder.navigation.event.PerspectivePluginsChangedEvent; import org.dashbuilder.client.navigation.widget.editor.NavTreeEditor; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.common.client.api.IsElement; import org.uberfire.backend.events.AuthorizationPolicySavedEvent; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.workbench.events.NotificationEvent; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.Menus; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; @ApplicationScoped @WorkbenchScreen(identifier = NavigationExplorerScreen.SCREEN_ID) public class NavigationExplorerScreen { public static final String SCREEN_ID = "NavigationExplorerScreen"; NavigationManager navigationManager; NavTreeEditor navTreeEditor; ContentManagerI18n i18n; Event workbenchNotification; public NavigationExplorerScreen() { } @Inject public NavigationExplorerScreen(NavigationManager navigationManager, NavTreeEditor navTreeEditor, ContentManagerI18n i18n, Event workbenchNotification) { this.navigationManager = navigationManager; this.navTreeEditor = navTreeEditor; this.i18n = i18n; this.workbenchNotification = workbenchNotification; } @PostConstruct void init() { navTreeEditor.setOnSaveCommand(this::onNavTreeSaved); navTreeEditor.getSettings().setLiteralPerspective(i18n.capitalizeFirst(i18n.getPerspectiveResourceName())); navTreeEditor.getSettings().setGotoPerspectiveEnabled(true); if (navTreeEditor.getNavTree() == null && navigationManager.getNavTree() != null) { navTreeEditor.edit(navigationManager.getNavTree()); } } @WorkbenchPartTitle public String getTitle() { return i18n.getContentExplorerNavigation(); } @WorkbenchPartView public IsElement getView() { return navTreeEditor; } @WorkbenchMenu public void getMenus(final Consumer menusConsumer) { menusConsumer.accept(MenuFactory.newTopLevelMenu(i18n.getContentExplorerNew()) .respondsWith(this::createNewNavigationTree) .endMenu() .build()); } public NavTreeEditor getNavTreeEditor() { return navTreeEditor; } public void createNewNavigationTree() { navTreeEditor.newTree(); } void onNavTreeLoaded(@Observes NavTreeLoadedEvent event) { NavTree navTree = event.getNavTree(); if (navTree != null) { navTreeEditor.edit(navTree); } } void onPerspectivesChanged(@Observes PerspectivePluginsChangedEvent event) { NavTree navTree = navigationManager.getNavTree(); if (navTree != null) { navTreeEditor.edit(navTree); } } public void onNavTreeChanged(@Observes final NavTreeChangedEvent event) { NavTree navTree = event.getNavTree(); if (navTree != null) { navigationManager.update(navTree); navTreeEditor.edit(navTree); } } void onNavTreeSaved() { workbenchNotification.fire(new NotificationEvent(i18n.getContentManagerNavigationChanged(), NotificationEvent.NotificationType.SUCCESS)); } void onAuthzPolicyChanged(@Observes final AuthorizationPolicySavedEvent event) { NavTree navTree = navigationManager.getNavTree(); if (navTree != null) { navTreeEditor.edit(navTree); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/explorer/PerspectivesExplorerScreen.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.explorer; import java.util.function.Consumer; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.cms.widget.NewPerspectivePopUp; import org.dashbuilder.client.cms.widget.PerspectivesExplorer; import org.jboss.errai.common.client.api.IsElement; import org.uberfire.backend.events.AuthorizationPolicySavedEvent; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.authz.PerspectiveAction; import org.uberfire.lifecycle.OnStartup; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.Menus; @Dependent @WorkbenchScreen(identifier = PerspectivesExplorerScreen.SCREEN_ID) public class PerspectivesExplorerScreen { public static final String SCREEN_ID = "PerspectivesExplorerScreen"; PerspectivesExplorer perspectivesExplorer; NewPerspectivePopUp newPerspectivePopUp; ContentManagerI18n i18n; public PerspectivesExplorerScreen() { } @Inject public PerspectivesExplorerScreen(PerspectivesExplorer perspectivesExplorer, NewPerspectivePopUp newPerspectivePopUp, ContentManagerI18n i18n) { this.perspectivesExplorer = perspectivesExplorer; this.newPerspectivePopUp = newPerspectivePopUp; this.i18n = i18n; } @OnStartup public void init() { perspectivesExplorer.show(); } @WorkbenchPartTitle public String getTitle() { return i18n.capitalizeFirst(i18n.getPerspectivesResourceName()); } @WorkbenchPartView public IsElement getView() { return perspectivesExplorer; } @WorkbenchMenu public void getMenus(final Consumer menusConsumer) { menusConsumer.accept(MenuFactory.newTopLevelMenu(i18n.getContentExplorerNew()) .withPermission(ActivityResourceType.PERSPECTIVE, PerspectiveAction.CREATE) .respondsWith(this::createNewPerspective) .endMenu() .build()); } public void createNewPerspective() { newPerspectivePopUp.show(); } void onAuthzPolicyChanged(@Observes final AuthorizationPolicySavedEvent event) { perspectivesExplorer.show(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/home/ContentManagerHomeScreen.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.home; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.cms.screen.explorer.PerspectivesExplorerScreen; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.UberView; import org.uberfire.ext.plugin.client.security.PluginController; @Dependent @WorkbenchScreen(identifier = ContentManagerHomeScreen.SCREEN_ID) public class ContentManagerHomeScreen { public static final String SCREEN_ID = "ContentManagerHomeScreen"; public interface View extends UberView { void setPerspectiveCreationVisible(boolean visible); } View view; PerspectivesExplorerScreen perspectivesExplorerScreen; PluginController pluginController; ContentManagerI18n i18n; @Inject public ContentManagerHomeScreen(View view, PerspectivesExplorerScreen perspectivesExplorerScreen, PluginController pluginController, ContentManagerI18n i18n) { this.view = view; this.perspectivesExplorerScreen = perspectivesExplorerScreen; this.pluginController = pluginController; this.i18n = i18n; } @PostConstruct private void init() { view.init(this); view.setPerspectiveCreationVisible(pluginController.canCreatePerspectives()); } @WorkbenchPartTitle public String getTitle() { return i18n.getContentManagerHome(); } @WorkbenchPartView public Widget getWidget() { return view.asWidget(); } public void createNewPerspective() { if (pluginController.canCreatePerspectives()) { perspectivesExplorerScreen.createNewPerspective(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/home/ContentManagerHomeView.html ================================================

  

================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/home/ContentManagerHomeView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.home; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.user.client.ui.Composite; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.jboss.errai.common.client.dom.Anchor; import org.jboss.errai.common.client.dom.Button; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class ContentManagerHomeView extends Composite implements ContentManagerHomeScreen.View { @Inject ContentManagerI18n i18n; @Inject @DataField Span titleSpan; @Inject @DataField Span welcomeSpan; @Inject @DataField Span createSpan; @Inject @DataField Anchor createPerspectiveAnchor; @Inject @DataField Button createPerspectiveButton; ContentManagerHomeScreen presenter; @Override public void init(ContentManagerHomeScreen presenter) { this.presenter = presenter; titleSpan.setTextContent(i18n.getContentManagerHomeTitle()); welcomeSpan.setTextContent(i18n.getContentManagerHomeWelcome()); createSpan.setTextContent(i18n.getContentManagerHomeCreate()); createPerspectiveAnchor.setTextContent(i18n.getContentManagerHomeNewPerspectiveLink()); createPerspectiveButton.setTextContent(i18n.getContentManagerHomeNewPerspectiveButton()); } @Override public void setPerspectiveCreationVisible(boolean visible) { if (visible) { createSpan.getStyle().removeProperty("display"); createPerspectiveAnchor.getStyle().removeProperty("display"); createPerspectiveButton.getStyle().removeProperty("display"); } else { createSpan.getStyle().setProperty("display", "none"); createPerspectiveAnchor.getStyle().setProperty("display", "none"); createPerspectiveButton.getStyle().setProperty("display", "none"); } } @EventHandler("createPerspectiveButton") public void createPerspectiveButton(final ClickEvent event) { presenter.createNewPerspective(); } @EventHandler("createPerspectiveAnchor") public void createPerspectiveAnchor( final ClickEvent event ) { presenter.createNewPerspective(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/DataTransferPopUp.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.uberfire.client.mvp.UberElemental; @ApplicationScoped public class DataTransferPopUp { private View view; public DataTransferPopUp() { } @Inject public DataTransferPopUp( final DataTransferPopUpView view) { this.view = view; } @PostConstruct public void init() { view.init(this); } public void show(List filesImported) { view.show(filesImported); } public interface View extends UberElemental { void show(List filesImported); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/DataTransferPopUpView.html ================================================

================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/DataTransferPopUpView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.jboss.errai.common.client.api.elemental2.IsElement; import org.jboss.errai.common.client.dom.elemental2.Elemental2DomUtil; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.editor.commons.client.file.popups.CommonModalBuilder; import org.uberfire.ext.widgets.common.client.common.popups.BaseModal; import com.google.gwt.user.client.DOM; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import com.google.gwt.dom.client.Element; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLParagraphElement; import elemental2.dom.HTMLUListElement; import elemental2.dom.Node; import jsinterop.base.Js; @Templated @Dependent public class DataTransferPopUpView implements DataTransferPopUp.View, IsElement { private BaseModal modal; private ContentManagerConstants i18n = ContentManagerConstants.INSTANCE; private HTMLDivElement root; private HTMLDivElement body; private HTMLParagraphElement filesImportedMessage; private HTMLUListElement filesImportedList; private Elemental2DomUtil elem2Dom; public DataTransferPopUpView() { } @Inject public DataTransferPopUpView( final @DataField HTMLDivElement root, final @DataField HTMLDivElement body, final @DataField HTMLParagraphElement filesImportedMessage, final @DataField HTMLUListElement filesImportedList, final Elemental2DomUtil elem2Dom) { this.root = root; this.body = body; this.filesImportedMessage = filesImportedMessage; this.filesImportedList = filesImportedList; this.elem2Dom = elem2Dom; } @Override public void init(DataTransferPopUp presenter) { modal = new CommonModalBuilder() .addHeader(i18n.dataTransferPopUpViewTitle()) .addBody(body) .build(); } @Override public HTMLElement getElement() { return root; } @Override public void show(List filesImported) { modal.setTitle(i18n.dataTransferPopUpViewTitle()); elem2Dom.removeAllElementChildren(filesImportedList); int size = filesImported.size(); if (size == 0) { filesImportedMessage.textContent = i18n.importResultMessageNoData(); } else { filesImportedMessage.textContent = i18n.importResultMessageOK(size); filesImported.forEach(fileImported -> { Element element = DOM.createElement("li"); element.setClassName("list-group-item"); element.setInnerText(fileImported); filesImportedList.appendChild((Node) Js.cast(element)); }); } modal.show(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/DataTransferScreen.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import java.util.List; import javax.annotation.PostConstruct; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.ErrorCallback; import org.jboss.errai.common.client.api.RemoteCallback; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.UberElemental; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.mvp.ParameterizedCommand; import org.dashbuilder.transfer.ExportInfo; import org.dashbuilder.transfer.DataTransferExportModel; import org.dashbuilder.transfer.DataTransferServices; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.client.cms.screen.transfer.export.wizard.ExportWizard; @ApplicationScoped @WorkbenchScreen(identifier = DataTransferScreen.ID) public class DataTransferScreen { public static final String ID = "DataTransferScreen"; private View view; private Caller dataTransferServices; private ContentManagerConstants i18n = ContentManagerConstants.INSTANCE; private DataTransferPopUp popUp; private ExportWizard exportWizard; private BusyIndicatorView busyIndicatorView; protected ParameterizedCommand gradualExportCallback; public DataTransferScreen() {} @Inject public DataTransferScreen( final View view, final DataTransferPopUp popUp, final Caller dataTransferServices, final ExportWizard exportWizard, final BusyIndicatorView busyIndicatorView) { this.view = view; this.popUp = popUp; this.dataTransferServices = dataTransferServices; this.exportWizard = exportWizard; this.busyIndicatorView = busyIndicatorView; } @WorkbenchPartTitle public String title() { return i18n.workbenchPartTitle(); } @WorkbenchPartView public View part() { return view; } @PostConstruct public void init() { view.init(this); exportWizard.setDownloadCallback(this::callExportService); exportWizard.setOpenCallback(this::openExportedModel); } public void doExport() { callExportService(DataTransferExportModel.exportAll()); } public void doGradualExport() { busyIndicatorView.showBusyIndicator(i18n.loadingExportWizard()); dataTransferServices.call((ExportInfo v) -> { busyIndicatorView.hideBusyIndicator(); exportWizard.start(v); }, (message, error) -> { busyIndicatorView.hideBusyIndicator(); view.exportError(error); return false; }).exportInfo(); } public void doImport() { try { dataTransferServices.call((RemoteCallback>) imported -> { view.importOK(); popUp.show(imported); }, (ErrorCallback) (message, throwable) -> { view.importError(throwable); return false; }).doImport(); } catch (Exception e) { view.importError(e); } } public interface View extends UberElemental { void importOK(); void exportOK(); void importError(Throwable throwable); void exportError(Throwable throwable); void download(String path); void openUrl(String path); } public String getFilePath() { return DataTransferServices.FILE_PATH; } public String getExportFileName() { return DataTransferServices.EXPORT_FILE_NAME; } public String getImportFileName() { return DataTransferServices.IMPORT_FILE_NAME; } private void callExportService(DataTransferExportModel dataTransferExportModel) { busyIndicatorView.showBusyIndicator(i18n.preparingExportDownload()); try { dataTransferServices.call((RemoteCallback) path -> { busyIndicatorView.hideBusyIndicator(); view.exportOK(); view.download(path); }, (ErrorCallback) (message, throwable) -> { busyIndicatorView.hideBusyIndicator(); view.exportError(throwable); return false; }).doExport(dataTransferExportModel); } catch (Exception e) { view.exportError(e); } } private void openExportedModel(DataTransferExportModel dataTransferExportModel) { busyIndicatorView.showBusyIndicator(i18n.preparingExportDownload()); try { dataTransferServices.call((RemoteCallback) modelUrl -> { busyIndicatorView.hideBusyIndicator(); view.exportOK(); view.openUrl(modelUrl); }, (ErrorCallback) (message, throwable) -> { busyIndicatorView.hideBusyIndicator(); view.exportError(throwable); return false; }).generateExportUrl(dataTransferExportModel); } catch (Exception e) { view.exportError(e); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/DataTransferView.css ================================================ @charset "UTF-8"; .data-transfer-view .card-pf-view { height: 200px; position: relative; } .data-transfer-view .card-pf-items:last-child { position: absolute; bottom: 15px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/DataTransferView.html ================================================

================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/DataTransferView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import elemental2.dom.DomGlobal; import elemental2.dom.HTMLButtonElement; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.client.cms.screen.transfer.export.wizard.widget.PagesTable; import org.dashbuilder.common.client.backend.PathUrlFactory; import org.dashbuilder.common.client.editor.file.FileUploadEditor; import org.dashbuilder.common.client.editor.file.FileUploadEditor.FileUploadEditorCallback; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.jboss.errai.common.client.api.elemental2.IsElement; import org.jboss.errai.common.client.dom.elemental2.Elemental2DomUtil; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.spaces.SpacesAPI; import org.uberfire.workbench.events.NotificationEvent; @Templated public class DataTransferView implements DataTransferScreen.View, IsElement { private static final Logger LOGGER = LoggerFactory.getLogger(DataTransferView.class); private DataTransferScreen presenter; private ContentManagerConstants i18n = ContentManagerConstants.INSTANCE; private HTMLDivElement root; private HTMLDivElement fileUploadContainer; private HTMLButtonElement btnImport; private FileUploadEditor fileUploadEditor; private Elemental2DomUtil elem2Dom; private Event workbenchNotification; private PathUrlFactory pathUrlFactory; @Inject PagesTable pagesTable; public DataTransferView() { } @Inject public DataTransferView( final @DataField HTMLDivElement root, final @DataField HTMLDivElement fileUploadContainer, final @DataField HTMLButtonElement btnImport, final @DataField HTMLButtonElement btnExport, final @DataField HTMLButtonElement btnGradualExport, final FileUploadEditor fileUploadEditor, final Elemental2DomUtil elem2Dom, final Event workbenchNotification, final PathUrlFactory pathUrlFactory) { this.root = root; this.fileUploadContainer = fileUploadContainer; this.btnImport = btnImport; this.fileUploadEditor = fileUploadEditor; this.elem2Dom = elem2Dom; this.workbenchNotification = workbenchNotification; this.pathUrlFactory = pathUrlFactory; } @Override public void init(DataTransferScreen presenter) { this.presenter = presenter; btnImport.disabled = true; elem2Dom.appendWidgetToElement(fileUploadContainer, fileUploadEditor.asWidget()); fileUploadEditor.setAccept(".zip"); fileUploadEditor.configure("fileUpload", new FileUploadEditorCallback() { @Override public String getUploadFileUrl() { String path = new StringBuilder() .append(SpacesAPI.Scheme.DEFAULT) .append("://") .append("system/system") .append("/") .append(presenter.getFilePath()) .append("/") .append(presenter.getImportFileName()) .toString(); return pathUrlFactory.getUploadFileUrl(path); } @Override public String getUploadFileName() { return presenter.getImportFileName(); } }); } @Override public HTMLElement getElement() { return root; } @Override public void download(String path) { DomGlobal.window.open( pathUrlFactory.getDownloadFileUrl(path)); } @Override public void exportError(Throwable throwable) { LOGGER.error(throwable.getMessage(), throwable); workbenchNotification.fire( new NotificationEvent( i18n.exportError(), NotificationEvent.NotificationType.ERROR)); } @Override public void importError(Throwable throwable) { btnImport.disabled = true; fileUploadEditor.view.clear(); LOGGER.error(throwable.getMessage(), throwable); workbenchNotification.fire( new NotificationEvent( i18n.importError(), NotificationEvent.NotificationType.ERROR)); } @Override public void importOK() { btnImport.disabled = true; fileUploadEditor.view.clear(); workbenchNotification.fire( new NotificationEvent( i18n.importOK(), NotificationEvent.NotificationType.SUCCESS)); } @Override public void exportOK() { workbenchNotification.fire( new NotificationEvent( i18n.exportOK(), NotificationEvent.NotificationType.SUCCESS)); } @EventHandler("btnImport") public void onImport(ClickEvent event) { presenter.doImport(); } @EventHandler("btnExport") public void onExport(ClickEvent event) { presenter.doExport(); } @EventHandler("btnGradualExport") public void onGradualExport(ClickEvent event) { presenter.doGradualExport(); } void newFileUploaded(@Observes ValueChangeEvent valueChangeEvent) { if (valueChangeEvent.getContext() == fileUploadEditor) { btnImport.disabled = false; } } @Override public void openUrl(String url) { DomGlobal.window.open(url, "_blank"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/DataSetsWizardPage.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.screen.transfer.export.wizard.widget.DataSetsTable; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.uberfire.client.callbacks.Callback; import org.uberfire.ext.widgets.core.client.wizards.WizardPage; @ApplicationScoped public class DataSetsWizardPage implements WizardPage { @Inject DataSetsTable dataSetsTable; @Override public Widget asWidget() { return ElementWrapperWidget.getWidget(dataSetsTable.getElement()); } @Override public String getTitle() { return "Select Datasets"; } @Override public void isComplete(Callback callback) { callback.callback(true); } @Override public void initialise() {} @Override public void prepareView() { dataSetsTable.refresh(); } public void setDataSets(List datasetDefinitions) { dataSetsTable.setData(datasetDefinitions); } public List getSelectedDataSetDefs() { return dataSetsTable.getSelectedData(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/ExportSummaryWizardPage.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard; import java.util.List; import java.util.Map; import java.util.function.Supplier; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.transfer.ExportInfo; import org.dashbuilder.transfer.DataTransferExportModel; import org.dashbuilder.transfer.ExportModelValidationService; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.uberfire.client.callbacks.Callback; import org.uberfire.client.mvp.UberElemental; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.ext.widgets.core.client.wizards.WizardPage; import org.uberfire.mvp.Command; import org.uberfire.mvp.ParameterizedCommand; import static java.util.stream.Collectors.toList; @ApplicationScoped public class ExportSummaryWizardPage implements WizardPage { ContentManagerConstants i18n = ContentManagerConstants.INSTANCE; @Inject View view; @Inject Caller exportModelValidationService; @Inject private BusyIndicatorView busyIndicatorView; ExportInfo exportInfo; private Supplier exportModelSupplier; private ParameterizedCommand dataTransferExportModelCallback; private DataTransferExportModel exportModel; private Command goToDataSetsCommand = () -> { }; private Command goToPagesCommand = () -> { }; private ParameterizedCommand dataTransferOpenModelCallback; public interface View extends UberElemental { void success(DataTransferExportModel dataTransferExportModel); void validationErrors(DataTransferExportModel dataTransferExportModel, Map> pageDependencies); void exportError(DataTransferExportModel dataTransferExportModel, String message); void emptyState(); void validationError(Throwable error); void showOpenExport(boolean externalServerAvailable); } @PostConstruct public void init() { view.init(this); } @Override public Widget asWidget() { return ElementWrapperWidget.getWidget(view.getElement()); } @Override public String getTitle() { return i18n.exportWizardTitle(); } @Override public void isComplete(Callback callback) { callback.callback(true); } @Override public void initialise() { view.init(this); } @Override public void prepareView() { validateAndUpdateView(); } public void setGoToDataSetsCommand(Command goToDatasets) { this.goToDataSetsCommand = goToDatasets; } public void setGoToPagesCommand(Command goToPages) { this.goToPagesCommand = goToPages; } public void setExportSummary(Supplier exportModelSupplier) { this.exportModelSupplier = exportModelSupplier; } public void setDownloadCallback(ParameterizedCommand dataTransferExportModelCallback) { this.dataTransferExportModelCallback = dataTransferExportModelCallback; } public void setOpenCallback(ParameterizedCommand dataTransferOpenModelCallback) { this.dataTransferOpenModelCallback = dataTransferOpenModelCallback; } void confirmDownload() { dataTransferExportModelCallback.execute(exportModel); } public void openExport() { dataTransferOpenModelCallback.execute(exportModel); } public void goToDataSetsPage() { goToDataSetsCommand.execute(); } public void goToPagesPage() { goToPagesCommand.execute(); } private void validateAndUpdateView() { exportModel = exportModelSupplier.get(); view.showOpenExport(exportInfo.isExternalServerAvailable()); if (exportModel.getPages().isEmpty() && exportModel.getDatasetDefinitions().isEmpty()) { view.exportError(exportModel, i18n.nothingToExport()); return; } if (exportModel.getPages().isEmpty()) { view.exportError(exportModel, i18n.noPagesExported()); return; } view.emptyState(); busyIndicatorView.showBusyIndicator(i18n.validatingExport()); exportModelValidationService.call((Map> validation) -> { busyIndicatorView.hideBusyIndicator(); if (validation.isEmpty()) { view.success(exportModel); } else { remapMissingDependencies(validation); view.validationErrors(exportModel, validation); } }, (message, error) -> { busyIndicatorView.hideBusyIndicator(); view.validationError(error); return false; }).checkMissingDatasets(exportModel); } void remapMissingDependencies(Map> validation) { if (exportInfo == null) { return; } List datasets = exportInfo.getDatasetsDefinitions(); validation.replaceAll((page, deps) -> { return deps.stream() .map(uuid -> datasets.stream() .filter(ds -> ds.getUUID().equals(uuid)) .map(ds -> ds.getName()).findAny().orElse(uuid)) .collect(toList()); }); } public void setExportInfo(ExportInfo exportInfo) { this.exportInfo = exportInfo; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/ExportSummaryWizardPageView.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #exportWizardSummary { width: 100%; height: 600px; } .assetsSummaryContainer { text-align: left; padding-top: 20px; } .errorMsg { overflow: auto; max-height: 120px; text-align: left; padding-left: 10px; margin-top: 20px; } .summaryContainer { background-color: transparent; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/ExportSummaryWizardPageView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/ExportSummaryWizardPageView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard; import java.util.List; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.inject.Named; import com.google.gwt.dom.client.Style.VerticalAlign; import com.google.gwt.event.dom.client.ClickEvent; import elemental2.dom.Element; import elemental2.dom.HTMLAnchorElement; import elemental2.dom.HTMLButtonElement; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLHeadingElement; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.client.cms.screen.util.DomFactory; import org.dashbuilder.transfer.DataTransferExportModel; import org.jboss.errai.common.client.dom.elemental2.Elemental2DomUtil; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.client.views.pfly.widgets.HelpIcon; import org.uberfire.workbench.events.NotificationEvent; @Templated @ApplicationScoped public class ExportSummaryWizardPageView implements ExportSummaryWizardPage.View { private static final Logger LOGGER = LoggerFactory.getLogger(ExportSummaryWizardPageView.class); ContentManagerConstants i18n = ContentManagerConstants.INSTANCE; @Inject @DataField HTMLDivElement exportWizardSummary; @Inject @DataField @Named("span") HTMLElement datasetsInformation; @Inject @DataField @Named("span") HTMLElement pagesInformation; @Inject @DataField HTMLAnchorElement datasetsInfoAnchor; @Inject @DataField HTMLAnchorElement pagesInfoAnchor; @Inject @DataField HTMLButtonElement downloadExport; @Inject @DataField HTMLButtonElement openExport; @Inject @DataField HTMLDivElement actionsContainer; @Inject @DataField @Named("h1") HTMLHeadingElement exportHeading; @Inject @DataField @Named("span") HTMLElement iconSpan; @Inject @DataField HTMLDivElement alertContainer; @Inject @DataField HTMLDivElement navigationSummaryContainer; @Inject DomFactory domFactory; @Inject Elemental2DomUtil elementalUtil; @Inject private Event wbNotification; private ExportSummaryWizardPage presenter; private HelpIcon openHelp; @Override public void init(ExportSummaryWizardPage presenter) { this.presenter = presenter; alertContainer.hidden = true; openHelp = new HelpIcon(); openHelp.setHelpContent(i18n.openHelpText()); openHelp.getElement().getStyle().setVerticalAlign(VerticalAlign.SUPER); elementalUtil.appendWidgetToElement(actionsContainer, openHelp); HelpIcon navigationhelp = new HelpIcon(); navigationhelp.setHelpContent(i18n.navigationHelpText()); elementalUtil.appendWidgetToElement(navigationSummaryContainer, navigationhelp); } @Override public HTMLElement getElement() { return exportWizardSummary; } @EventHandler("downloadExport") public void downloadAction(ClickEvent click) { presenter.confirmDownload(); } @EventHandler("openExport") public void openAction(ClickEvent click) { presenter.openExport(); } @EventHandler("datasetsInfoAnchor") public void datasetsInfoAnchorClicked(ClickEvent click) { presenter.goToDataSetsPage(); } @EventHandler("pagesInfoAnchor") public void pagesInfoAnchorClicked(ClickEvent click) { presenter.goToPagesPage(); } @Override public void success(DataTransferExportModel dataTransferExportModel) { successState(); showSummary(dataTransferExportModel); } @Override public void validationErrors(DataTransferExportModel dataTransferExportModel, Map> pageDependencies) { errorState(); Element errorHeader = domFactory.element("strong"); errorHeader.textContent = i18n.missingDependencies(); alertContainer.appendChild(errorHeader); Element pageList = domFactory.element("ul"); pageDependencies.forEach((page, ds) -> { Element li = domFactory.listItem(i18n.pageMissingDataSets(page)); li.appendChild(pageMissingDataSetsList(ds)); pageList.appendChild(li); }); alertContainer.appendChild(pageList); showSummary(dataTransferExportModel); } @Override public void exportError(DataTransferExportModel dataTransferExportModel, String warningMessage) { errorState(); alertContainer.textContent = warningMessage; showSummary(dataTransferExportModel); } private void showSummary(DataTransferExportModel dataTransferExportModel) { pagesInformation.textContent = checkPlural(dataTransferExportModel.getPages().size(), i18n.pageLabel(), i18n.pagesLabel()); datasetsInformation.textContent = checkPlural(dataTransferExportModel.getDatasetDefinitions().size(), i18n.datasetLabel(), i18n.datasetsLabel()); } private String checkPlural(int size, String text, String pluralText) { String result = size + " "; return size == 1 ? result + text : result + pluralText; } private Element pageMissingDataSetsList(List datasets) { Element list = domFactory.element("ul"); datasets.stream().map(domFactory::listItem).forEach(list::appendChild); return list; } @Override public void emptyState() { state("pficon-running", "", true, true); pagesInformation.textContent = ""; datasetsInformation.textContent = ""; } @Override public void validationError(Throwable throwable) { LOGGER.error(throwable.getMessage(), throwable); wbNotification.fire(new NotificationEvent(i18n.validationError(), NotificationEvent.NotificationType.ERROR)); } @Override public void showOpenExport(boolean externalServerAvailable) { openExport.style.visibility = externalServerAvailable ? "visible" : "hidden"; openHelp.setVisible(externalServerAvailable); } private void errorState() { state("pficon pficon-error-circle-o", i18n.exportWizardHeadingError(), false, true); alertContainer.innerHTML = ""; } private void successState() { state("pficon pficon-ok", i18n.exportWizardHeadingSuccess(), true, false); } private void state(String iconSpanClass, String headingText, boolean hideAlert, boolean hideDownload) { iconSpan.className = iconSpanClass; exportHeading.textContent = headingText; alertContainer.hidden = hideAlert; downloadExport.disabled = hideDownload; openExport.disabled = hideDownload; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/ExportWizard.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.transfer.ExportInfo; import org.dashbuilder.transfer.DataTransferExportModel; import org.uberfire.client.callbacks.Callback; import org.uberfire.ext.widgets.core.client.wizards.AbstractWizard; import org.uberfire.ext.widgets.core.client.wizards.WizardPage; import org.uberfire.ext.widgets.core.client.wizards.WizardPageSelectedEvent; import org.uberfire.mvp.ParameterizedCommand; @ApplicationScoped public class ExportWizard extends AbstractWizard { ContentManagerConstants i18n = ContentManagerConstants.INSTANCE; @Inject DataSetsWizardPage dataSetsWizardPage; @Inject PagesWizardPage pagesWizardPage; @Inject ExportSummaryWizardPage exportSummaryWizardPage; @Inject Event wizardPageSelectedEvent; private List wizardPages; private boolean canConclude; @PostConstruct void init() { wizardPages = new ArrayList<>(); wizardPages.add(dataSetsWizardPage); wizardPages.add(pagesWizardPage); wizardPages.add(exportSummaryWizardPage); exportSummaryWizardPage.setExportSummary(this::getDataTransferExportModel); exportSummaryWizardPage.setGoToDataSetsCommand(() -> goTo(dataSetsWizardPage)); exportSummaryWizardPage.setGoToPagesCommand(() -> goTo(pagesWizardPage)); } public void start(ExportInfo exportInfo) { dataSetsWizardPage.setDataSets(exportInfo.getDatasetsDefinitions()); pagesWizardPage.setPages(exportInfo.getPages()); exportSummaryWizardPage.setExportInfo(exportInfo); this.start(); } @Override public List getPages() { return wizardPages; } @Override public Widget getPageWidget(int pageNumber) { return wizardPages.get(pageNumber).asWidget(); } @Override public String getTitle() { return i18n.exportWizardTitle(); } @Override public int getPreferredWidth() { return 900; } @Override public int getPreferredHeight() { return 600; } @Override public void isComplete(Callback callback) { callback.callback(canConclude); } private void goTo(WizardPage page) { wizardPageSelectedEvent.fire(new WizardPageSelectedEvent(page)); } public DataTransferExportModel getDataTransferExportModel() { return new DataTransferExportModel(dataSetsWizardPage.getSelectedDataSetDefs(), pagesWizardPage.getSelectedPages(), true); } public void setDownloadCallback(ParameterizedCommand dataTransferExportModelCallback) { exportSummaryWizardPage.setDownloadCallback(dataTransferExportModelCallback); } public void setOpenCallback(ParameterizedCommand dataTransferExportModelCallback) { exportSummaryWizardPage.setOpenCallback(dataTransferExportModelCallback); } @Override public void pageSelected(int pageNumber) { super.pageSelected(pageNumber); WizardPage page = getPages().get(pageNumber); page.prepareView(); this.canConclude = page == exportSummaryWizardPage; checkPagesState(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/PagesWizardPage.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.screen.transfer.export.wizard.widget.PagesTable; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.uberfire.client.callbacks.Callback; import org.uberfire.ext.widgets.core.client.wizards.WizardPage; @ApplicationScoped public class PagesWizardPage implements WizardPage { @Inject PagesTable pagesTable; @Override public Widget asWidget() { return ElementWrapperWidget.getWidget(pagesTable.getElement()); } @Override public String getTitle() { return "Select Pages"; } @Override public void isComplete(Callback callback) { callback.callback(true); } @Override public void initialise() { // EMPTY } @Override public void prepareView() { pagesTable.refresh(); } public void setPages(List pages) { pagesTable.setData(pages); } public List getSelectedPages() { return pagesTable.getSelectedData(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/widget/AssetsTableAbstractPresenter.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard.widget; import java.util.List; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import elemental2.dom.HTMLElement; import org.jboss.errai.ioc.client.api.ManagedInstance; public abstract class AssetsTableAbstractPresenter implements AssetsTableView.Presenter { @Inject AssetsTableView view; @Inject ManagedInstance viewManagedInstance; private List data; @PostConstruct public void init() { view = viewManagedInstance.get(); view.init(this); } @Override public List getData() { return data; } @Override public void setData(List data) { this.data = data; view.update(); } @Override public List getSelectedData() { return (List) view.getSelectedAssets(); } public HTMLElement getElement() { return view.getElement(); } public void refresh() { view.clearFilter(); } @PreDestroy public void destroyView() { viewManagedInstance.destroyAll(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/widget/AssetsTableView.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #assetTableWidgetRoot { overflow: scroll; max-width: 680px; max-height: 600px; min-height: 600px; } .assets-table>thead>tr>th:first-child { width: 5%; } .assets-table>tbody>tr>td:first-child { width: 5%; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/widget/AssetsTableView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/widget/AssetsTableView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard.widget; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.KeyUpEvent; import elemental2.dom.Element; import elemental2.dom.HTMLCollection; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLInputElement; import elemental2.dom.HTMLTableCellElement; import elemental2.dom.HTMLTableElement; import elemental2.dom.HTMLTableRowElement; import elemental2.dom.NodeList; import org.dashbuilder.client.cms.screen.util.DomFactory; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.mvp.UberElemental; @Dependent @Templated public class AssetsTableView implements UberElemental { @Inject DomFactory domFactory; @Inject @DataField HTMLDivElement assetTableWidgetRoot; @Inject @DataField HTMLInputElement searchAssets; @Inject @DataField HTMLTableElement assetsTable; @Inject @DataField HTMLInputElement selectAllAssets; @Inject @DataField HTMLTableRowElement assetsTableHeaderRow; Presenter presenter; public interface Presenter { List getData(); List getSelectedData(); String[] getHeaders(); String[] toRow(T t); void setData(List data); default String[][] rows() { List data = getData(); String[][] rows = new String[data.size()][]; for (int i = 0; i < rows.length; i++) { rows[i] = toRow(data.get(i)); } return rows; } } @Override public void init(Presenter presenter) { this.presenter = presenter; buildHeaders(presenter.getHeaders()); } public void update() { assetsTable.tBodies.getAt(0).innerHTML = ""; selectAllAssets.checked = true; Arrays.stream(presenter.rows()) .map(this::toRow) .forEach(this::appendRow); } public List getSelectedAssets() { List data = presenter.getData(); HTMLCollection rows = assetsTable.tBodies.getAt(0).rows; return IntStream.range(0, rows.getLength()) .filter(i -> { Element checkBox = rows.getAt(i).querySelector("td > input[type=checkbox]"); return ((HTMLInputElement) checkBox).checked; }).mapToObj(data::get) .collect(Collectors.toList()); } @Override public HTMLElement getElement() { return assetTableWidgetRoot; } @EventHandler("selectAllAssets") void selectAll(ClickEvent event) { allInputsForTable().forEach(chk -> chk.checked = selectAllAssets.checked); } @EventHandler("searchAssets") void onFilter(KeyUpEvent keyDown) { filterTable(); } public void clearFilter() { searchAssets.value = ""; filterTable(); } void appendRow(HTMLTableRowElement row) { assetsTable.tBodies.getAt(0).appendChild(row); } HTMLTableRowElement toRow(String[] cells) { HTMLTableRowElement row = domFactory.tableRow(); // first cell is always a check box row.appendChild(createRowSelectorCell()); Arrays.stream(cells) .map(this::createCell) .forEach(row::appendChild); return row; } void filterTable() { String query = searchAssets.value.trim().toLowerCase(); HTMLCollection rows = assetsTable.tBodies.getAt(0).rows; IntStream.range(0, rows.getLength()).mapToObj(rows::getAt).forEach(row -> { row.hidden = false; if (!query.isEmpty()) { row.hidden = IntStream.range(0, row.cells.getLength()) .mapToObj(row.cells::getAt) .noneMatch(c -> c.textContent.toLowerCase().contains(query)); } }); } private HTMLInputElement createCheckBox() { HTMLInputElement checkbox = domFactory.input(); checkbox.type = "checkbox"; checkbox.checked = true; return checkbox; } private HTMLTableCellElement createCell(String content) { HTMLTableCellElement cell = domFactory.tableCell(); cell.innerHTML = content; return cell; } private Element createHeaderCell(String content) { Element cell = domFactory.element("th"); cell.innerHTML = content; return cell; } private HTMLTableCellElement createRowSelectorCell() { HTMLTableCellElement tableCell = domFactory.tableCell(); HTMLInputElement rowChk = createCheckBox(); rowChk.onclick = e -> { selectAllAssets.checked = allInputsForTable().allMatch(input -> rowChk.checked); return null; }; tableCell.appendChild(rowChk); return tableCell; } private Stream allInputsForTable() { // asArray throws cast exception NodeList items = assetsTable.querySelectorAll("tbody > tr > td:first-of-type > input[type=checkbox]"); return IntStream.range(0, items.getLength()).mapToObj(i -> (HTMLInputElement) items.getAt(i)); } private void buildHeaders(String[] headers) { Arrays.stream(headers) .map(this::createHeaderCell) .forEach(assetsTableHeaderRow::appendChild); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/widget/DataSetsTable.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard.widget; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.dataset.def.DataSetDef; @ApplicationScoped public class DataSetsTable extends AssetsTableAbstractPresenter { private static final String[] HEADERS = {"UUID", "Name", "Type"}; @Override public String[] getHeaders() { return HEADERS; } @Override public String[] toRow(DataSetDef dataSetDef) { return new String[]{ dataSetDef.getUUID(), dataSetDef.getName(), dataSetDef.getProvider().getName() }; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/widget/PagesTable.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard.widget; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class PagesTable extends AssetsTableAbstractPresenter { private static final String[] HEADERS = {"Name"}; @Override public String[] getHeaders() { return HEADERS; } @Override public String[] toRow(String t) { return new String[]{t}; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/screen/util/DomFactory.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.util; import javax.enterprise.context.ApplicationScoped; import elemental2.dom.DomGlobal; import elemental2.dom.Element; import elemental2.dom.HTMLInputElement; import elemental2.dom.HTMLTableCellElement; import elemental2.dom.HTMLTableRowElement; /** * Create DOM Elements. Can be mocked in tests. * */ @ApplicationScoped public class DomFactory { public Element element(String elementType) { return DomGlobal.document.createElement(elementType); } public Element listItem(String text) { Element li = DomGlobal.document.createElement("li"); li.textContent = text; return li; } public HTMLInputElement input() { return (HTMLInputElement) DomGlobal.document.createElement("input"); } public HTMLTableCellElement tableCell() { return (HTMLTableCellElement) DomGlobal.document.createElement("td"); } public HTMLTableRowElement tableRow() { return (HTMLTableRowElement) DomGlobal.document.createElement("tr"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/NewPerspectivePopUp.java ================================================ /* * Copyright 2015 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElement; import org.uberfire.ext.editor.commons.client.validation.ValidationErrorReason; import org.uberfire.ext.editor.commons.client.validation.ValidatorWithReasonCallback; import org.uberfire.ext.layout.editor.api.PerspectiveServices; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.plugin.client.validation.PluginNameValidator; import org.uberfire.ext.plugin.exception.PluginAlreadyExists; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; @ApplicationScoped public class NewPerspectivePopUp implements IsElement { public interface View extends UberElement { void show(); void hide(); String getName(); String getStyle(); void errorEmptyName(); void errorInvalidName(); void errorDuplicatedName(); } private Caller perspectiveServices; private PlaceManager placeManager; private PluginNameValidator pluginNameValidator; private NewPerspectivePopUpView view; // For proxying protected NewPerspectivePopUp() { } @Inject public NewPerspectivePopUp(NewPerspectivePopUpView view, Caller perspectiveServices, PluginNameValidator pluginNameValidator, PlaceManager placeManager) { this.view = view; this.perspectiveServices = perspectiveServices; this.pluginNameValidator = pluginNameValidator; this.placeManager = placeManager; this.view.init(this); } @Override public HTMLElement getElement() { return view.getElement(); } protected PlaceRequest getPathPlaceRequest(Plugin response) { return new PathPlaceRequest(response.getPath()) .addParameter("name", response.getName()); } public void show() { view.show(); } public void hide() { view.hide(); } // View actions public void onOK() { String layoutName = view.getName(); LayoutTemplate.Style layoutStyle = LayoutTemplate.Style.valueOf(view.getStyle()); pluginNameValidator.validate(layoutName + ".plugin", new ValidatorWithReasonCallback() { @Override public void onFailure(final String reason) { if (ValidationErrorReason.EMPTY_NAME.name().equals(reason)) { view.errorEmptyName(); } else if (ValidationErrorReason.DUPLICATED_NAME.name().equals(reason)) { view.errorDuplicatedName(); } else { view.errorInvalidName(); } } @Override public void onSuccess() { perspectiveServices.call( (Plugin response) -> { placeManager.goTo(getPathPlaceRequest(response)); hide(); }, (message, throwable) -> { if (throwable instanceof PluginAlreadyExists) { view.errorDuplicatedName(); } else { view.errorInvalidName(); } return false; } ).createNewPerspective(layoutName, layoutStyle); } @Override public void onFailure() { view.errorInvalidName(); } }); } public void onCancel() { hide(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/NewPerspectivePopUpView.css ================================================ .uf-np-popup-name-label { margin-right: 5px; } .uf-np-popup-name-input { width: 150px; } .uf-np-popup-style-label { margin-right: 5px; } .uf-np-popup-style-select { width: 150px; height: 25px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/NewPerspectivePopUpView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/NewPerspectivePopUpView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.user.client.Event; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.gwtbootstrap3.client.ui.Modal; import org.jboss.errai.common.client.dom.Button; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Input; import org.jboss.errai.common.client.dom.Option; import org.jboss.errai.common.client.dom.Select; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.SinkNative; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.editor.commons.client.file.popups.CommonModalBuilder; import org.uberfire.ext.widgets.common.client.common.popups.BaseModal; import org.uberfire.ext.widgets.common.client.common.popups.ButtonPressed; @Templated @Dependent public class NewPerspectivePopUpView implements NewPerspectivePopUp.View, IsElement { NewPerspectivePopUp presenter; BaseModal modal; ButtonPressed buttonPressed = ButtonPressed.CLOSE; ContentManagerConstants i18n = ContentManagerConstants.INSTANCE; @Inject @DataField Div body; @Inject @DataField Div footer; @Inject @DataField Div formDiv; @DataField @Inject Input nameInput; @DataField @Inject Span nameLabel; @DataField @Inject Span nameHelp; @Inject @DataField Span nameErrorLabel; @DataField @Inject Select styleSelect; @DataField @Inject Span styleLabel; @DataField @Inject Span styleHelp; @DataField @Inject Option fluidOption; @DataField @Inject Option pageOption; @DataField @Inject Button okButton; @DataField @Inject Button cancelButton; @Override public void init(NewPerspectivePopUp presenter) { this.presenter = presenter; modal = new CommonModalBuilder() .addHeader(i18n.newPerspectivePopUpViewTitle()) .addBody(body) .addFooter(footer) .build(); modal.addHiddenHandler(hiddenEvent -> { if (ButtonPressed.CLOSE.equals(buttonPressed)) { presenter.onCancel(); } }); } public Modal getModal() { return modal; } @Override public void show() { nameInput.setValue(""); nameErrorLabel.setTextContent(""); formDiv.setClassName("form-group"); fluidOption.setSelected(true); pageOption.setSelected(false); nameLabel.setTextContent(i18n.newPerspectivePopUpViewName()); nameHelp.setTitle(i18n.newPerspectivePopUpViewNameHelp()); styleLabel.setTextContent(i18n.newPerspectivePopUpViewStyle()); styleHelp.setTitle(i18n.newPerspectivePopUpViewStyleHelp()); okButton.setTextContent(i18n.newPerspectivePopUpViewOk()); cancelButton.setTextContent(i18n.newPerspectivePopUpViewCancel()); fluidOption.setTextContent(i18n.newPerspectivePopUpViewFluid()); pageOption.setTextContent(i18n.newPerspectivePopUpViewPage()); modal.setTitle(i18n.newPerspectivePopUpViewTitle()); modal.show(); nameInput.focus(); } @Override public void hide() { modal.hide(); } @Override public String getName() { return nameInput.getValue(); } @Override public String getStyle() { String val = styleSelect.getValue(); return val; } @Override public void errorEmptyName() { showNameError(i18n.newPerspectivePopUpViewErrorEmptyName()); } @Override public void errorInvalidName() { showNameError(i18n.newPerspectivePopUpViewErrorInvalidName()); } @Override public void errorDuplicatedName() { showNameError(i18n.newPerspectivePopUpViewErrorDuplicatedName()); } private void showNameError(String error) { formDiv.setClassName("form-group has-error"); nameErrorLabel.setTextContent(error); } @SinkNative(Event.ONCLICK) @EventHandler("okButton") public void okClick(final Event event) { buttonPressed = ButtonPressed.OK; presenter.onOK(); } @SinkNative(Event.ONMOUSEDOWN) @EventHandler("nameInput") public void nameInputEnter(final Event event) { if (event.getKeyCode() == KeyCodes.KEY_ENTER) { buttonPressed = ButtonPressed.OK; presenter.onOK(); } } @SinkNative(Event.ONCLICK) @EventHandler("cancelButton") public void cancelClick(final Event event) { buttonPressed = ButtonPressed.CANCEL; presenter.onCancel(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/PerspectiveWidget.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.uberfire.client.mvp.UberView; import org.uberfire.ext.plugin.event.PluginDeleted; import org.uberfire.ext.plugin.event.PluginSaved; import org.uberfire.ext.plugin.model.Plugin; /** * Runtime perspective widget */ @Dependent public class PerspectiveWidget implements IsWidget { public interface View extends UberView { void showContent(IsWidget widget); void notFoundError(); void infiniteRecursionError(); } View view; PerspectivePluginManager perspectivePluginManager; String perspectiveId; @Inject public PerspectiveWidget(View view, PerspectivePluginManager perspectivePluginManager) { this.view = view; this.perspectivePluginManager = perspectivePluginManager; } @Override public Widget asWidget() { return view.asWidget(); } public void showPerspective(String id) { perspectiveId = id; if (id == null || !perspectivePluginManager.existsPerspectivePlugin(id)) { view.notFoundError(); } else { perspectivePluginManager.buildPerspectiveWidget(id, view::showContent, this::onDeadlock); } } private void onDeadlock(LayoutRecursionIssue issue) { view.infiniteRecursionError(); } private void refreshPerspective(Plugin plugin) { if (perspectiveId != null && perspectiveId.equals(plugin.getName())) { showPerspective(perspectiveId); } } // Capture changes on the perspective public void onPlugInSaved(@Observes final PluginSaved event) { refreshPerspective(event.getPlugin()); } public void onPlugInDeleted(@Observes final PluginDeleted event) { refreshPerspective(event.getPlugin()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/PerspectiveWidgetView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/PerspectiveWidgetView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import javax.inject.Inject; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerConstants; import org.dashbuilder.common.client.widgets.AlertBox; import org.jboss.errai.common.client.dom.CSSStyleDeclaration; import org.jboss.errai.common.client.ui.ElementWrapperWidget; public class PerspectiveWidgetView implements PerspectiveWidget.View, IsWidget { FlowPanel mainPanel = new FlowPanel(); PerspectiveWidget presenter; AlertBox alertBox; @Inject public PerspectiveWidgetView(AlertBox alertBox) { this.alertBox = alertBox; alertBox.setLevel(AlertBox.Level.WARNING); alertBox.setCloseEnabled(false); CSSStyleDeclaration style = alertBox.getElement().getStyle(); style.setProperty("width", "30%"); style.setProperty("margin", "10px"); } @Override public void init(PerspectiveWidget presenter) { this.presenter = presenter; } @Override public Widget asWidget() { return mainPanel; } @Override public void showContent(IsWidget widget) { mainPanel.clear(); mainPanel.add(widget); } @Override public void notFoundError() { alertBox.setMessage(ContentManagerConstants.INSTANCE.perspectiveDragNotFoundError()); mainPanel.clear(); mainPanel.add(ElementWrapperWidget.getWidget(alertBox.getElement())); } @Override public void infiniteRecursionError() { alertBox.setMessage(ContentManagerConstants.INSTANCE.perspectiveInfiniteRecursionError()); mainPanel.clear(); mainPanel.add(ElementWrapperWidget.getWidget(alertBox.getElement())); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/PerspectivesExplorer.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import java.util.List; import java.util.stream.Collectors; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.navigation.event.PerspectivePluginsChangedEvent; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElement; import org.uberfire.ext.plugin.client.security.PluginController; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; @Dependent public class PerspectivesExplorer implements IsElement { public interface View extends UberElement { void clear(); void addPerspective(String name, Command onClicked); void showEmpty(String message); } View view; PerspectivePluginManager perspectivePluginManager; PlaceManager placeManager; PluginController pluginController; ContentManagerI18n i18n; @Inject public PerspectivesExplorer(View view, PerspectivePluginManager perspectivePluginManager, PluginController pluginController, PlaceManager placeManager, ContentManagerI18n i18n) { this.view = view; this.perspectivePluginManager = perspectivePluginManager; this.pluginController = pluginController; this.placeManager = placeManager; this.i18n = i18n; this.view.init(this); } @Override public HTMLElement getElement() { return view.getElement(); } public void show() { view.clear(); perspectivePluginManager.getPerspectivePlugins(perspectivePlugins -> { List filteredPlugins = perspectivePlugins.stream() .filter(pluginController::canRead) .sorted((p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName())) .collect(Collectors.toList()); if (filteredPlugins.isEmpty()) { view.showEmpty(i18n.getNoPerspectives()); } else { filteredPlugins.forEach(p -> view.addPerspective(p.getName(), () -> onPerspectiveClick(p))); } }); } public void onPerspectiveClick(Plugin plugin) { PlaceRequest placeRequest = new PathPlaceRequest(plugin.getPath()).addParameter("name", plugin.getName()); placeManager.goTo(placeRequest); } public void onPerspectivePluginsChanged(@Observes final PerspectivePluginsChangedEvent event) { show(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/PerspectivesExplorerView.css ================================================ .uf-cms-perspectives-panel { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/PerspectivesExplorerView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/java/org/dashbuilder/client/cms/widget/PerspectivesExplorerView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.SpanElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.mvp.Command; @Templated public class PerspectivesExplorerView implements IsElement, PerspectivesExplorer.View { @Inject @DataField Div perspectivesDiv; PerspectivesExplorer presenter; @Override public void init(PerspectivesExplorer presenter) { this.presenter = presenter; } @Override public void clear() { DOMUtil.removeAllChildren(perspectivesDiv); } private DivElement createItemDiv(Element[] items) { DivElement mi = Document.get().createDivElement(); mi.setClassName("list-view-pf-main-info"); mi.getStyle().setPaddingTop(5, Style.Unit.PX); mi.getStyle().setPaddingBottom(5, Style.Unit.PX); for (Element item : items) { mi.appendChild(item); } DivElement gi = Document.get().createDivElement(); gi.setClassName("list-group-item"); gi.appendChild(mi); return gi; } @Override public void addPerspective(String name, Command onClicked) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.getStyle().setCursor(Style.Cursor.POINTER); anchor.getStyle().setColor("black"); anchor.getStyle().setProperty("fontSize", "larger"); anchor.setInnerText(name); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if (Event.ONCLICK == event.getTypeInt()) { onClicked.execute(); } }); SpanElement icon = Document.get().createSpanElement(); icon.getStyle().setMarginRight(10, Style.Unit.PX); icon.setClassName("fa fa-file-text-o"); icon.getStyle().setProperty("fontSize", "larger"); DivElement gi = createItemDiv(new Element[]{icon, anchor}); perspectivesDiv.appendChild((Node) gi); } @Override public void showEmpty(String message) { SpanElement span = Document.get().createSpanElement(); span.setInnerText(message); DivElement gi = createItemDiv(new Element[]{span}); perspectivesDiv.appendChild((Node) gi); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/org/dashbuilder/ContentManagerClient.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/org/dashbuilder/client/cms/resources/i18n/ContentManagerConstants.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # contentExplorerNew=New contentExplorerNavigation=Navigation contentExplorerTopMenu=Top Menu navigationTreeItem=Navigation Tree contentManagerHome=Content Manager contentManagerHomeTitle=Content Management contentManagerHomeWelcome=From here you can create & customize both the application content and its navigation menus. contentManagerHomeCreate=You can start by creating a contentManagerHomeNewPerspective=new {0} contentManagerNavigationChanged=Navigation changed succesfully componentPalette=Components propertiesEditor=Properties perspective=page perspectives=pages noPerspectives=No pages perspectiveDragComponent=Page perspectiveDragComponentHeader=Page Selector perspectiveDragComponentHelp=The selected page will be fully displayed inside the component''s display area. perspectiveDragSelectorHint=- Select Page - perspectiveDragSelectorLabel=Page perspectiveDragNotFoundError=The page is either not configured or not found. perspectiveInfiniteRecursionError=The content is not displayed to avoid an infinite loop. In general the page you selected for this component must not contain references (directly nor indirectly) to this page. newPerspectivePopUpViewName=Name newPerspectivePopUpViewNameHelp=The name of the page. Please make sure is not empty and it doesn''t already exist. newPerspectivePopUpViewStyle=Style newPerspectivePopUpViewStyleHelp=The ''Fluid'' option acts more as a classical web page, showing a vertical scrollbar when the page exceeds the available height. Select ''Page'' only if you want to force the page to always fit the window''s 100% height. newPerspectivePopUpViewFluid=Fluid newPerspectivePopUpViewPage=Page newPerspectivePopUpViewCancel=Cancel newPerspectivePopUpViewOk=Ok newPerspectivePopUpViewTitle=New Page ... newPerspectivePopUpViewErrorEmptyName=Name is mandatory newPerspectivePopUpViewErrorInvalidName=Invalid page name newPerspectivePopUpViewErrorDuplicatedName=Page name already exists workbenchPartTitle=Dashbuilder Data Transfer DataTransferView.import=Import DataTransferView.export=Export all DataTransferView.gradualExport=Custom export dataTransferPopUpViewTitle=Dashbuilder Data Transfer importResultMessageOK=Data uploaded successfully, {0} files imported. importResultMessageNoData=No data available on Zip archive. exportOK=Data exported successfully. importOK=Data imported successfully. exportError=Data export error. Check logs for more details. importError=Data import error. Check logs for more details. exportText=Export dashbuilder related data (datasets, perspectives and navigation) to a ZIP file. importText=Import dashbuilder related data (datasets, perspectives and navigation) from a ZIP file. dataTransferExportPopUpViewTitle=Select Assets to Export dataTransferExportError=Error retrieving list of assets to export loadAssetsToExport=Export Wizard pageLabel=page datasetLabel=dataset pagesLabel=pages datasetsLabel=datasets ExportSummaryWizardPageView.download=Download ExportSummaryWizardPageView.open=Open ExportSummaryWizardPageView.navigation=Navigation ExportSummaryWizardPageView.errorHighlightedMessage=Missing Dependencies! ExportSummaryWizardPageView.summary=Summary exportWizardTitle=Export Wizard loadingExportWizard=Loading Export Wizard preparingExportDownload=Preparing Export Download pageMissingDataSets=Page {0} datasets: validatingExport=Validating Export exportWizardHeadingSuccess=Your export is ready exportWizardHeadingError=Error creating export noPagesExported=No page was selected to export missingDependencies=Some dependencies were not fulfilled: nothingToExport=No page or dataset was selected to export navigationHelpText=Navigation is always exported. validationError=Export validation error. Check logs. openHelpText=Open in the connected Dashbuilder Standalone Server ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/org/dashbuilder/client/cms/resources/i18n/ContentManagerConstants_es.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # contentExplorerNew=Nuevo contentExplorerNavigation=Navegación contentExplorerTopMenu=Menú superior navigationTreeItem=Árbol de navegación contentManagerHome=Administrador de contenido contentManagerHomeTitle=Gestión de contenido contentManagerHomeWelcome=Desde aquí, puede crear y personalizar tanto el contenido de la aplicación como sus menús de navegación. contentManagerHomeCreate=Puede empezar creando un contentManagerHomeNewPerspective=nuevo {0} contentManagerNavigationChanged=La navegación se modificó correctamente componentPalette=Componentes propertiesEditor=Propiedades perspective=página perspectives=páginas noPerspectives=No hay páginas perspectiveDragComponent=Página perspectiveDragComponentHeader=Selector de página perspectiveDragComponentHelp=La página seleccionada se mostrará por completo dentro del área de visualización del componente. perspectiveDragSelectorHint=- Seleccionar página - perspectiveDragSelectorLabel=Página perspectiveDragNotFoundError=La página no está configurada o no se encuentra. perspectiveInfiniteRecursionError=El contenido no se muestra para evitar un bucle infinito. En general, la página que ha seleccionado para este componente no debe contener referencias (directas o indirectas) a esta página. newPerspectivePopUpViewName=Nombre newPerspectivePopUpViewNameHelp=El nombre de la página. Asegúrese de que no esté vacío y que aún no exista. newPerspectivePopUpViewStyle=Estilo newPerspectivePopUpViewStyleHelp=La opción “Fluido” actúa más como una página web clásica en la que se muestra una barra de desplazamiento vertical cuando la página supera la altura disponible. Seleccione “Página” solo si quiere forzar la página para que se ajuste siempre al 100 % de la altura de la ventana. newPerspectivePopUpViewFluid=Fluido newPerspectivePopUpViewPage=Página newPerspectivePopUpViewCancel=Cancelar newPerspectivePopUpViewOk=Aceptar newPerspectivePopUpViewTitle=Nueva página… newPerspectivePopUpViewErrorEmptyName=El nombre es obligatorio newPerspectivePopUpViewErrorInvalidName=Nombre de página no válido newPerspectivePopUpViewErrorDuplicatedName=El nombre de la página ya existe workbenchPartTitle=Transferencia de datos de Dashbuilder DataTransferView.import=Importar DataTransferView.export=Exportar EPC DataTransferView.gradualExport=Exportación personalizada dataTransferPopUpViewTitle=Transferencia de datos de Dashbuilder importResultMessageOK=Los datos se cargaron correctamente; {0} archivos importados. importResultMessageNoData=No hay datos disponibles en el archivo Zip. exportOK=Los datos se exportaron correctamente. importOK=Los datos se importaron correctamente. exportError=Error de exportación de datos. Revise los registros para obtener más detalles. importError=Error de importación de datos. Revise los registros para obtener más detalles. exportText=Exportar datos relacionados con dashbuilder (conjuntos de datos, perspectivas y navegación) a un archivo ZIP. importText=Importar datos relacionados con dashbuilder (conjuntos de datos, perspectivas y navegación) desde un archivo ZIP. dataTransferExportPopUpViewTitle=Seleccione los activos a exportar dataTransferExportError=Error al recuperar la lista de activos a exportar loadAssetsToExport=Asistente de exportación pageLabel=página datasetLabel=conjunto de datos pagesLabel=páginas datasetsLabel=conjuntos de datos ExportSummaryWizardPageView.download=Descargar ExportSummaryWizardPageView.open=Abrir ExportSummaryWizardPageView.navigation=Navegación ExportSummaryWizardPageView.errorHighlightedMessage=Administrar dependencias… ExportSummaryWizardPageView.summary=Resumen exportWizardTitle=Asistente de exportación loadingExportWizard=Carga del Asistente de Exportación preparingExportDownload=Preparación de la descarga de la exportación pageMissingDataSets=Página {0} conjuntos de datos: validatingExport=Validación de la exportación exportWizardHeadingSuccess=Su exportación está lista exportWizardHeadingError=Error al crear la exportación noPagesExported=No se ha seleccionado ninguna página para exportar missingDependencies=Algunas dependencias no se cumplieron: nothingToExport=No se ha seleccionado ninguna página o conjunto de datos para exportar navigationHelpText=La navegación siempre se exporta. validationError=Error de validación de JSON: Comprueba los registros. openHelpText=Abrir en el servidor autónomo Dashbuilder conectado ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/org/dashbuilder/client/cms/resources/i18n/ContentManagerConstants_fr.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # contentExplorerNew=Nouveau contentExplorerNavigation=Navigation contentExplorerTopMenu=Menu supérieur navigationTreeItem=Arborescence de navigation contentManagerHome=Gestionnaire de contenu contentManagerHomeTitle=Gestion du contenu contentManagerHomeWelcome=À partir d''ici, vous pouvez créer et personnaliser le contenu de l''application et ses menus de navigation. contentManagerHomeCreate=Vous pouvez commencer par créer un contentManagerHomeNewPerspective=nouveau {0} contentManagerNavigationChanged=La navigation a été modifiée componentPalette=Composants propertiesEditor=Propriétés perspective=page perspectives=pages noPerspectives=Aucune page perspectiveDragComponent=Page perspectiveDragComponentHeader=Sélecteur de page perspectiveDragComponentHelp=La page sélectionnée sera entièrement affichée dans la zone d''affichage du composant. perspectiveDragSelectorHint=- Sélectionner une page - perspectiveDragSelectorLabel=Page perspectiveDragNotFoundError=La page n''est pas configurée ou est introuvable. perspectiveInfiniteRecursionError=Le contenu n''est pas affiché pour éviter une boucle infinie. En règle générale, la page que vous avez sélectionnée pour ce composant ne doit pas contenir de références (directes ou indirectes) à cette page. newPerspectivePopUpViewName=Nom newPerspectivePopUpViewNameHelp=Nom de la page. Assurez-vous qu''elle n''est pas vide et qu''elle n''existe pas encore. newPerspectivePopUpViewStyle=Style newPerspectivePopUpViewStyleHelp=L''option ''Fluide'' fonctionne davantage comme une page Web classique, en affichant une barre de défilement verticale lorsque la page dépasse la hauteur disponible. Sélectionnez "Page" uniquement si vous souhaitez que la page s''adapte toujours à la hauteur complète (100 %) de la fenêtre. newPerspectivePopUpViewFluid=Fluide newPerspectivePopUpViewPage=Page newPerspectivePopUpViewCancel=Annuler newPerspectivePopUpViewOk=OK newPerspectivePopUpViewTitle=Nouvelle page… newPerspectivePopUpViewErrorEmptyName=Le nom est obligatoire newPerspectivePopUpViewErrorInvalidName=Nom de page non valide newPerspectivePopUpViewErrorDuplicatedName=Le nom de la page existe déjà workbenchPartTitle=Transfert de données Dashbuilder DataTransferView.import=Importer DataTransferView.export=Exporter tout DataTransferView.gradualExport=Personnaliser Exportation dataTransferPopUpViewTitle=Transfert de données Dashbuilder importResultMessageOK=Données envoyés avec succès, {0} fichiers importés. importResultMessageNoData=Aucune donnée disponible dans l''archive ZIP. exportOK=Les données ont été exportées. importOK=Les données ont été importées. exportError=Erreur d''exportation des données. Consultez les journaux pour plus de détails. importError=Erreur d''importation des données. Consultez les journaux pour plus de détails. exportText=Exportez les données relatives à Dashbuilder (ensembles de données, perspectives et navigation) vers un fichier ZIP. importText=Importez les données relatives à Dashbuilder (ensembles de données, perspectives et navigation) depuis un fichier ZIP. dataTransferExportPopUpViewTitle=Sélectionnez les ressources à exporter dataTransferExportError=Erreur lors de l''extraction de la liste des ressources à exporter loadAssetsToExport=Assistant d''exportation pageLabel=page datasetLabel=ensemble de données pagesLabel=pages datasetsLabel=ensembles de données ExportSummaryWizardPageView.download=Télécharger ExportSummaryWizardPageView.open=Ouvrir ExportSummaryWizardPageView.navigation=Navigation ExportSummaryWizardPageView.errorHighlightedMessage=Dépendances manquantes ! ExportSummaryWizardPageView.summary=Résumé exportWizardTitle=Assistant d''exportation loadingExportWizard=Chargement de l''assistant d''exportation preparingExportDownload=Préparation au téléchargement de l''exportation pageMissingDataSets=Page {0} des ensembles de données : validatingExport=Validation de l''exportation exportWizardHeadingSuccess=Votre exportation est prête exportWizardHeadingError=Erreur en créant l''exportation noPagesExported=Aucune page n''a été sélectionnée pour l''exportation missingDependencies=Certaines dépendances n''ont pas été remplies : nothingToExport=Aucune page ou ensemble de données n''a été sélectionné pour l''exportation navigationHelpText=La navigation est toujours exportée. validationError=Erreur de validation d''exportation. Vérifiez les journaux. openHelpText=Ouvert dans le serveur autonome Dashbuilder connecté ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/org/dashbuilder/client/cms/resources/i18n/ContentManagerConstants_it.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # contentExplorerNew=Nuovo contentExplorerNavigation=Navigazione contentExplorerTopMenu=Menu Principale navigationTreeItem=Albero di Navigazione contentManagerHome=Gestore dei Contenuti contentManagerHomeTitle=Gestione dei Contenuti contentManagerHomeWelcome=Da qui puoi creare e personalizzare sia il contenuto dell''applicazione che i suoi menu di navigazione. contentManagerHomeCreate=Puoi iniziare creando una contentManagerHomeNewPerspective=nuova {0} contentManagerNavigationChanged=Navigazione modificata con successo componentPalette=Componenti propertiesEditor=Proprietà perspective=pagina perspectives=pagine noPerspectives=Nessuna pagina perspectiveDragComponent=Pagina perspectiveDragComponentHeader=Selettore di Pagina perspectiveDragComponentHelp=La pagina selezionata verrà visualizzata completamente all''interno dell''area di visualizzazione del componente. perspectiveDragSelectorHint=- Seleziona Pagina - perspectiveDragSelectorLabel=Pagina perspectiveDragNotFoundError=La pagina non è configurata o non è stata trovata. perspectiveInfiniteRecursionError=Il contenuto non viene visualizzato per evitare un ciclo infinito. In generale, la pagina selezionata per questo componente non deve contenere riferimenti (diretti o indiretti) a questa pagina. newPerspectivePopUpViewName=Nome newPerspectivePopUpViewNameHelp=Il nome della pagina. Assicurati che non sia vuoto e che non esista già. newPerspectivePopUpViewStyle=Stile newPerspectivePopUpViewStyleHelp=L''opzione "Fluid" funziona come una pagina web classica, mostrando una barra di scorrimento verticale quando la pagina supera l''altezza disponibile. Seleziona "Pagina" solo se vuoi forzare la pagina a occupare sempre il 100% dell''altezza della finestra. newPerspectivePopUpViewFluid=Fluida newPerspectivePopUpViewPage=Pagina newPerspectivePopUpViewCancel=Annulla newPerspectivePopUpViewOk=Ok newPerspectivePopUpViewTitle=Nuova Pagina ... newPerspectivePopUpViewErrorEmptyName=Il nome è obbligatorio newPerspectivePopUpViewErrorInvalidName=Nome pagina non valido newPerspectivePopUpViewErrorDuplicatedName=Il nome della pagina esiste già workbenchPartTitle=Trasferimento Dati Dashbuilder DataTransferView.import=Importa DataTransferView.export=Esporta tutto DataTransferView.gradualExport=Esportazione personalizzata dataTransferPopUpViewTitle=Trasferimento Dati Dashbuilder importResultMessageOK=Dati caricati con successo, {0} file importati. importResultMessageNoData=Nessun dato disponibile nell''archivio Zip. exportOK=Dati esportati con successo. importOK=Dati importati con successo. exportError=Errore durante l''esportazione dei dati. Controlla i log per ulteriori dettagli. importError=Errore durante l''importazione dei dati. Controlla i log per ulteriori dettagli. exportText=Esporta i dati correlati a Dashbuilder (dataset, pagine e navigazione) in un file ZIP. importText=Importa i dati correlati a Dashbuilder (dataset, pagine e navigazione) da un file ZIP. dataTransferExportPopUpViewTitle=Seleziona Elementi da Esportare dataTransferExportError=Errore durante il recupero dell''elenco degli elementi da esportare loadAssetsToExport=Wizard di Esportazione pageLabel=pagina datasetLabel=dataset pagesLabel=pagine datasetsLabel=dataset ExportSummaryWizardPageView.download=Scarica ExportSummaryWizardPageView.open=Apri ExportSummaryWizardPageView.navigation=Navigazione ExportSummaryWizardPageView.errorHighlightedMessage=Dipendenze Mancanti! ExportSummaryWizardPageView.summary=Sommario exportWizardTitle=Wizard di Esportazione loadingExportWizard=Caricamento Wizard di Esportazione preparingExportDownload=Preparazione Download Esportazione pageMissingDataSets=Pagina {0} dataset: validatingExport=Validazione Esportazione exportWizardHeadingSuccess=La tua esportazione è pronta exportWizardHeadingError=Errore durante la creazione dell''esportazione noPagesExported=Nessuna pagina è stata selezionata per l''esportazione missingDependencies=Alcune dipendenze non sono state soddisfatte: nothingToExport=Nessuna pagina o dataset è stato selezionato per l''esportazione navigationHelpText=La navigazione viene sempre esportata. validationError=Errore di validazione dell''esportazione. Controlla i log. openHelpText=Apri nel server autonomo di Dashbuilder connesso ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/main/resources/org/dashbuilder/client/cms/resources/i18n/ContentManagerConstants_ja.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # contentExplorerNew=新規 contentExplorerNavigation=ナビゲーション contentExplorerTopMenu=トップメニュー navigationTreeItem=ナビゲーションツリー contentManagerHome=コンテンツマネージャー contentManagerHomeTitle=コンテンツ管理 contentManagerHomeWelcome=アプリケーションコンテンツとナビゲーションメニューを作成、カスタマイズできます。 contentManagerHomeCreate=次のものが作成可能です contentManagerHomeNewPerspective=新規 {0} contentManagerNavigationChanged=ナビゲーションは変更されました componentPalette=コンポーネント propertiesEditor=プロパティー perspective=ページ perspectives=ページ noPerspectives=ページがありません perspectiveDragComponent=ページ perspectiveDragComponentHeader=ページセレクター perspectiveDragComponentHelp=選択されたページはコンポーネントの表示エリアに完全に表示されます。 perspectiveDragSelectorHint=- ページの選択 - perspectiveDragSelectorLabel=ページ perspectiveDragNotFoundError=ページが設定されていない、または見つかりません。 perspectiveInfiniteRecursionError=無限ループを避けるためこのコンテンツは表示されません。一般的には、このコンポーネントに対して選択したページは、このページへの (直接もしくは間接的な) 参照を含むことはできません。 newPerspectivePopUpViewName=名前 newPerspectivePopUpViewNameHelp=ページの名前空欄でないことと、名前がすでに存在していないことを確認してください。 newPerspectivePopUpViewStyle=スタイル newPerspectivePopUpViewStyleHelp=「Fluid」オプションは、従来の web ページのように、ページの高さが利用可能な高さよりも長くなると、垂直バーが表示されます。ページの高さを常にウィンドウの高さに一致させる場合は「ページ」を選択してください。 newPerspectivePopUpViewFluid=流動 newPerspectivePopUpViewPage=ページ newPerspectivePopUpViewCancel=キャンセル newPerspectivePopUpViewOk=OK newPerspectivePopUpViewTitle=新規ページ ... newPerspectivePopUpViewErrorEmptyName=名前は必須項目です newPerspectivePopUpViewErrorInvalidName=無効なページ名 newPerspectivePopUpViewErrorDuplicatedName=ページ名がすでに存在します workbenchPartTitle=Dashbuilder のデータ転送 DataTransferView.import=インポート DataTransferView.export=すべてエクスポート DataTransferView.gradualExport=カスタムエクスポート dataTransferPopUpViewTitle=Dashbuilder のデータ転送 importResultMessageOK=データが正常にアップロードされ、{0} 個のファイルがインポートされました。 importResultMessageNoData=Zip アーカイブに利用可能なデータはありません。 exportOK=データが正常にエクスポートされました。 importOK=データが正常にインポートされました。 exportError=データのエクスポートエラー。詳細は、ログを確認してください。 importError=データのインポートエラー。詳細は、ログを確認してください。 exportText=Dashbuilder 関連のデータ (データセット、パースペクティブ、ナビゲーション) を Zip ファイルにエクスポートします。 importText=Dashbuilder 関連のデータ (データセット、パースペクティブ、ナビゲーション) を Zip ファイルからインポートします。 dataTransferExportPopUpViewTitle=エクスポートするアセットを選択します dataTransferExportError=エクスポートするアセット一覧の取得中にエラー loadAssetsToExport=エクスポートウィザード pageLabel=ページ datasetLabel=データセット pagesLabel=ページ datasetsLabel=データセット ExportSummaryWizardPageView.download=ダウンロード ExportSummaryWizardPageView.open=開く ExportSummaryWizardPageView.navigation=ナビゲーション ExportSummaryWizardPageView.errorHighlightedMessage=依存関係がありません! ExportSummaryWizardPageView.summary=要約 exportWizardTitle=エクスポートウィザード loadingExportWizard=エクスポートウィザードの読み込み preparingExportDownload=エクスポートのダウンロードの準備 pageMissingDataSets=ページ {0} データセット: validatingExport=エクスポートの検証 exportWizardHeadingSuccess=エクスポートの準備ができました exportWizardHeadingError=エクスポートの作成中にエラー noPagesExported=エクスポートするページが選択されていません missingDependencies=一部の依存関係が満たされませんでした: nothingToExport=エクスポートするページまたはデータセットが選択されていません navigationHelpText=ナビゲーションは常にエクスポートされます。 validationError=エクスポート検証エラー:ログを確認してください。 openHelpText=接続された Dashbuilder スタンドアロンサーバーで開きます ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/test/java/org/dashbuilder/client/cms/perspective/ContentManagerPerspectiveTest.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.perspective; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.uberfire.client.workbench.docks.UberfireDockPosition; import org.uberfire.client.workbench.docks.UberfireDocks; import org.uberfire.client.workbench.events.PerspectiveChange; import org.uberfire.client.workbench.events.PlaceHiddenEvent; import org.uberfire.ext.layout.editor.client.api.LayoutEditor; import org.uberfire.ext.layout.editor.client.widgets.LayoutEditorPropertiesPresenter; import org.uberfire.ext.plugin.client.perspective.editor.PerspectiveEditorPresenter; import org.uberfire.ext.plugin.client.perspective.editor.events.PerspectiveEditorFocusEvent; import org.uberfire.mvp.impl.DefaultPlaceRequest; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class ContentManagerPerspectiveTest { @Mock ContentManagerI18n i18n; @Mock UberfireDocks uberfireDocks; @Mock PerspectiveChange perspectiveChangeEvent; @Mock LayoutEditorPropertiesPresenter propertiesPresenter; @Mock LayoutEditor layoutEditor; @InjectMocks ContentManagerPerspective perspective; @Before public void setUp() { when(perspectiveChangeEvent.getIdentifier()).thenReturn("anotherPerspective"); perspective.init(); perspective.onOpen(); } @Test public void testInit() { verify(uberfireDocks).add(perspective.perspectivesExplorerDock); verify(uberfireDocks).add(perspective.navigationExplorerDock); verify(uberfireDocks).remove(perspective.componentPaletteDock); verify(uberfireDocks).open(perspective.perspectivesExplorerDock); verify(uberfireDocks).show(UberfireDockPosition.WEST, ContentManagerPerspective.PERSPECTIVE_ID); } @Test public void testOnLayoutEditorFocus() { reset(uberfireDocks); perspective.onPerspectiveEditorFocus(new PerspectiveEditorFocusEvent(layoutEditor)); verify(uberfireDocks).add(perspective.componentPaletteDock); verify(uberfireDocks).open(perspective.componentPaletteDock); verify(uberfireDocks).show(UberfireDockPosition.WEST, ContentManagerPerspective.PERSPECTIVE_ID); } @Test public void testOnLayoutEditorHidden() { perspective.onPerspectiveEditorFocus(new PerspectiveEditorFocusEvent(layoutEditor)); reset(uberfireDocks); perspective.onPerspectiveEditorHidden(new PlaceHiddenEvent(new DefaultPlaceRequest(PerspectiveEditorPresenter.ID))); verify(uberfireDocks).remove(perspective.componentPaletteDock); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/test/java/org/dashbuilder/client/cms/screen/explorer/NavigationExplorerScreenTest.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.explorer; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.event.NavTreeLoadedEvent; import org.dashbuilder.navigation.event.PerspectivePluginsChangedEvent; import org.dashbuilder.client.navigation.widget.editor.NavItemEditorSettings; import org.dashbuilder.client.navigation.widget.editor.NavTreeEditor; import org.dashbuilder.navigation.NavTree; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import org.uberfire.workbench.events.NotificationEvent; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class NavigationExplorerScreenTest { @Mock NavigationManager navigationManager; @Mock NavTreeEditor navTreeEditor; @Mock NavItemEditorSettings navItemEditorSettings; @Mock EventSourceMock notificationEvent; @Mock ContentManagerI18n i18n; @Mock NavTree navTree; NavigationExplorerScreen navigationExplorerScreen; @Before public void setUp() { when(navTreeEditor.getSettings()).thenReturn(navItemEditorSettings); navigationExplorerScreen = new NavigationExplorerScreen(navigationManager, navTreeEditor, i18n, notificationEvent); } @Test public void testInitTreeAlreadySet() { when(navigationManager.getNavTree()).thenReturn(navTree); navigationExplorerScreen.init(); verify(navTreeEditor).edit(navTree); } @Test public void testOnNavTreeLoaded() { navigationExplorerScreen.init(); navigationExplorerScreen.onNavTreeLoaded(new NavTreeLoadedEvent(navTree)); verify(navTreeEditor).edit(navTree); } @Test public void testOnPerspectivesChanged() { navigationExplorerScreen.init(); when(navigationManager.getNavTree()).thenReturn(navTree); navigationExplorerScreen.onPerspectivesChanged(new PerspectivePluginsChangedEvent()); verify(navTreeEditor, times(1)).edit(any(NavTree.class)); } @Test public void testOnPerspectivesChangedWithNullNavTree() { navigationExplorerScreen.init(); navigationExplorerScreen.onPerspectivesChanged(new PerspectivePluginsChangedEvent()); verify(navTreeEditor, times(0)).edit(any(NavTree.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/test/java/org/dashbuilder/client/cms/screen/transfer/DataTransferScreenTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.dashbuilder.client.cms.screen.transfer.export.wizard.ExportWizard; import org.dashbuilder.transfer.DataTransferExportModel; import org.dashbuilder.transfer.DataTransferServices; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.mocks.CallerMock; import com.google.gwtmockito.GwtMockitoTestRunner; @RunWith(GwtMockitoTestRunner.class) public class DataTransferScreenTest { @Mock private DataTransferScreen.View view; @Mock private DataTransferServices dataTransferServices; @Mock private DataTransferPopUp dataTransferPopUp; @Mock private ExportWizard exportWizard; @Mock BusyIndicatorView busyIndicatorView; private DataTransferScreen dataTransferScreen; private CallerMock dataTransferServicesCaller; @Before public void prepare() { dataTransferServicesCaller = new CallerMock<>(dataTransferServices); dataTransferScreen = new DataTransferScreen( view, dataTransferPopUp, dataTransferServicesCaller, exportWizard, busyIndicatorView); } @Test public void doExportTest() throws Exception { String path = "path"; DataTransferExportModel exportAll = DataTransferExportModel.exportAll(); when(dataTransferServices.doExport(exportAll)).thenReturn(path); dataTransferScreen.init(); dataTransferScreen.doExport(); verify(dataTransferServices).doExport(exportAll); verify(view).exportOK(); verify(view).download(path); } @Test public void doExportFailureTest() throws Exception { IOException exception = new IOException(); DataTransferExportModel exportAll = DataTransferExportModel.exportAll(); when(dataTransferServices.doExport(exportAll)).thenThrow(exception); dataTransferScreen.doExport(); verify(dataTransferServices).doExport(exportAll); verify(view).exportError(exception); } @Test public void doImportTest() throws Exception { List list = new ArrayList<>(); when(dataTransferServices.doImport()).thenReturn(list); dataTransferScreen.doImport(); verify(dataTransferServices).doImport(); verify(view).importOK(); verify(dataTransferPopUp).show(list); } @Test public void doImportFailureTest() throws Exception { Exception exception = new Exception(); when(dataTransferServices.doImport()).thenThrow(exception); dataTransferScreen.doImport(); verify(dataTransferServices).doImport(); verify(view).importError(exception); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/test/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/ExportSummaryWizardPageTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard; import java.util.Collections; import java.util.HashMap; import java.util.List; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.transfer.ExportInfo; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; @RunWith(GwtMockitoTestRunner.class) public class ExportSummaryWizardPageTest { ExportSummaryWizardPage exportWizardSummaryPage; @Before public void init() { exportWizardSummaryPage = new ExportSummaryWizardPage(); } @Test public void testRemapMissingDependencies() { String UUID = "uuid"; String NAME = "name"; String PAGE = "page"; DataSetDef def1 = new DataSetDef(); def1.setUUID(UUID); def1.setName(NAME); HashMap> validation = new HashMap<>(); validation.put(PAGE, Collections.singletonList(UUID)); ExportInfo exportInfo = new ExportInfo(Collections.singletonList(def1), Collections.emptyList(), false); exportWizardSummaryPage.setExportInfo(exportInfo); exportWizardSummaryPage.remapMissingDependencies(validation); assertEquals(NAME, validation.get(PAGE).get(0)); } @Test public void testRemapMissingDependenciesWithoutDatasetDef() { String UUID = "uuid"; String PAGE = "page"; HashMap> validation = new HashMap<>(); validation.put(PAGE, Collections.singletonList(UUID)); exportWizardSummaryPage.remapMissingDependencies(validation); assertEquals(UUID, validation.get(PAGE).get(0)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/test/java/org/dashbuilder/client/cms/screen/transfer/export/wizard/widget/AssetsTableViewTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.screen.transfer.export.wizard.widget; import java.util.Arrays; import java.util.List; import com.google.gwtmockito.GwtMockitoTestRunner; import elemental2.dom.HTMLCollection; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLInputElement; import elemental2.dom.HTMLTableCellElement; import elemental2.dom.HTMLTableElement; import elemental2.dom.HTMLTableRowElement; import elemental2.dom.HTMLTableSectionElement; import org.dashbuilder.client.cms.screen.util.DomFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class AssetsTableViewTest { @Mock DomFactory domFactory; @Mock HTMLTableRowElement assetsTableHeaderRow; @Mock HTMLInputElement searchAssets; @Mock HTMLInputElement selectAllAssets; @InjectMocks AssetsTableView assetsTableView; private MockAssetsTablePresenter presenter; @Before public void prepare() { presenter = new MockAssetsTablePresenter(); when(domFactory.tableCell()).thenReturn(new HTMLTableCellElement()); when(domFactory.input()).thenReturn(new HTMLInputElement()); when(domFactory.tableRow()).thenReturn(new HTMLTableRowElement()); when(domFactory.element(any())).thenReturn(new HTMLElement()); assetsTableView.assetsTable = buildHTMLTable(); assetsTableView.init(presenter); presenter.view = assetsTableView; } @Test public void testTableRowsCreated() { List assets = Arrays.asList("asset1", "asset2"); presenter.setData(assets); HTMLTableSectionElement assetsTable = assetsTableView.assetsTable.tBodies.getAt(0); Mockito.verify(assetsTable, times(assets.size())).appendChild(any()); } @Test public void testFilterTable() { HTMLInputElement filter = assetsTableView.searchAssets; HTMLTableElement table = assetsTableView.assetsTable; HTMLCollection rows = mock(HTMLCollection.class); HTMLTableRowElement[] actualRows = { mock(HTMLTableRowElement.class), mock(HTMLTableRowElement.class) }; HTMLCollection firstRowCells = mock(HTMLCollection.class); HTMLCollection secondRowCells = mock(HTMLCollection.class); HTMLTableCellElement tableCellElement1 = mock(HTMLTableCellElement.class), tableCellElement2 = mock(HTMLTableCellElement.class); tableCellElement1.textContent = "Abc"; tableCellElement2.textContent = "dEfx"; when(firstRowCells.getAt(0)).thenReturn(tableCellElement1); when(firstRowCells.getAt(1)).thenReturn(tableCellElement2); HTMLTableCellElement tableCellElement3 = mock(HTMLTableCellElement.class), tableCellElement4 = mock(HTMLTableCellElement.class); tableCellElement3.textContent = "gHi"; tableCellElement4.textContent = "jKlX"; when(secondRowCells.getAt(0)).thenReturn(tableCellElement3); when(secondRowCells.getAt(1)).thenReturn(tableCellElement4); actualRows[0].cells = firstRowCells; actualRows[1].cells = secondRowCells; when(actualRows[0].cells.getLength()).thenReturn(2); when(actualRows[1].cells.getLength()).thenReturn(2); for (int i = 0; i < actualRows.length; i++) { when(rows.getAt(i)).thenReturn(actualRows[i]); } when(rows.getLength()).thenReturn(actualRows.length); table.tBodies.getAt(0).rows = rows; filter.value = "abC"; assetsTableView.filterTable(); assertTrue(actualRows[1].hidden); assertFalse(actualRows[0].hidden); filter.value = "jkL"; assetsTableView.filterTable(); assertTrue(actualRows[0].hidden); assertFalse(actualRows[1].hidden); filter.value = "X"; assetsTableView.filterTable(); assertFalse(actualRows[0].hidden); assertFalse(actualRows[1].hidden); filter.value = "z"; assetsTableView.filterTable(); assertTrue(actualRows[0].hidden); assertTrue(actualRows[1].hidden); } private HTMLTableElement buildHTMLTable() { HTMLTableElement table = new HTMLTableElement(); HTMLCollection tableBodies = mock(HTMLCollection.class); HTMLTableSectionElement tableBody = mock(HTMLTableSectionElement.class); table.tBodies = tableBodies; when(tableBodies.getAt(0)).thenReturn(tableBody); return table; } class MockAssetsTablePresenter extends AssetsTableAbstractPresenter { @Override public String[] getHeaders() { return new String[]{"test"}; } @Override public String[] toRow(String t) { return new String[]{t}; } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/test/java/org/dashbuilder/client/cms/widget/NewPerspectivePopUpTest.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.editor.commons.client.validation.ValidatorCallback; import org.uberfire.ext.layout.editor.api.PerspectiveServices; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.plugin.client.validation.PluginNameValidator; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.mocks.CallerMock; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class NewPerspectivePopUpTest { @Mock private NewPerspectivePopUpView view; @Mock private PlaceManager placeManager; @Mock private PerspectiveServices perspectiveServices; @Mock private PathPlaceRequest pathPlaceRequest; private PluginNameValidator pluginNameValidator; private NewPerspectivePopUp presenter; private boolean validationError = false; @Before public void setUp() { pluginNameValidator = spy(new PluginNameValidator() { @Override public void validate(String value, ValidatorCallback callback) { if (validationError) { callback.onFailure(); } else { callback.onSuccess(); } } }); presenter = new NewPerspectivePopUp(view, new CallerMock<>(perspectiveServices), pluginNameValidator, placeManager) { @Override protected PlaceRequest getPathPlaceRequest(Plugin response) { return pathPlaceRequest; } }; } @Test public void testSuccessfulValidation() { this.validationError = false; when(view.getName()).thenReturn("newPerspective"); when(view.getStyle()).thenReturn(LayoutTemplate.Style.FLUID.toString()); presenter.onOK(); verify(pluginNameValidator).validate(eq("newPerspective.plugin"), any(ValidatorCallback.class)); verify(perspectiveServices).createNewPerspective("newPerspective", LayoutTemplate.Style.FLUID); verify(placeManager).goTo(pathPlaceRequest); verify(view).hide(); } @Test public void testFailedValidation() { this.validationError = true; when(view.getName()).thenReturn("invalid*"); when(view.getStyle()).thenReturn(LayoutTemplate.Style.FLUID.toString()); presenter.onOK(); verify(pluginNameValidator).validate(eq("invalid*.plugin"), any(ValidatorCallback.class)); verify(perspectiveServices, never()).createNewPerspective(anyString(), any()); verify(view).errorInvalidName(); verify(view, never()).hide(); } @Test public void testPopupCanceled() { presenter.onCancel(); verify(pluginNameValidator, never()).validate(anyString(), any(ValidatorCallback.class)); verify(perspectiveServices, never()).createNewPerspective(anyString(),any()); verify(view).hide(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-cms-client/src/test/java/org/dashbuilder/client/cms/widget/PerspectivesExplorerTest.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.cms.widget; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.plugin.client.security.PluginController; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.ext.plugin.model.PluginType; import org.uberfire.mvp.ParameterizedCommand; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class PerspectivesExplorerTest { @Mock PerspectivesExplorer.View viewM; @Mock PerspectivePluginManager perspectivePluginManagerM; @Mock PlaceManager placeManagerM; @Mock PluginController pluginControllerM; @Mock ContentManagerI18n i18nM; PerspectivesExplorer perspectivesExplorer; Plugin a = mkPlugin("a"), b = mkPlugin("B"), c = mkPlugin("cEE"); List pluginList = Arrays.asList(b, c, a); private Plugin mkPlugin(String name) { return new Plugin(name, PluginType.PERSPECTIVE, null); } @Before public void setUp() { doAnswer(invocationOnMock -> { ParameterizedCommand> callback = invocationOnMock.getArgument(0, ParameterizedCommand.class); callback.execute(pluginList); return null; }).when(perspectivePluginManagerM).getPerspectivePlugins(any()); perspectivesExplorer = new PerspectivesExplorer(viewM, perspectivePluginManagerM, pluginControllerM, placeManagerM, i18nM); } @Test public void testPerspectiveListEmpty() { pluginList = new ArrayList<>(); perspectivesExplorer.show(); verify(viewM).clear(); verify(viewM).showEmpty(any()); } @Test public void testPerspectivesAvailable() { when(pluginControllerM.canRead(any())).thenReturn(true); perspectivesExplorer.show(); InOrder inOrder = inOrder(viewM); inOrder.verify(viewM).clear(); inOrder.verify(viewM).addPerspective(eq("a"), any()); inOrder.verify(viewM).addPerspective(eq("B"), any()); inOrder.verify(viewM).addPerspective(eq("cEE"), any()); } @Test public void testPerspectiveReadAccessDenied() { when(pluginControllerM.canRead(a)).thenReturn(true); when(pluginControllerM.canRead(b)).thenReturn(true); perspectivesExplorer.show(); InOrder inOrder = inOrder(viewM); inOrder.verify(viewM).clear(); inOrder.verify(viewM).addPerspective(eq("a"), any()); inOrder.verify(viewM).addPerspective(eq("B"), any()); inOrder.verify(viewM, never()).addPerspective(eq("cEE"), any()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-common-client jar Dashbuilder Common Client Dashbuilder Common Client org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-json org.jboss.errai errai-common org.jboss.errai errai-ioc org.jboss.errai errai-ui com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 org.gwtbootstrap3 gwtbootstrap3-extras org.uberfire uberfire-api org.uberfire uberfire-client-api org.uberfire uberfire-widgets-commons com.google.gwt.gwtmockito gwtmockito test org.uberfire uberfire-testing-utils test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/CollectionUtils.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; public class CollectionUtils { /** Constant to avoid repeated object creation */ private static Integer INTEGER_ONE = new Integer(1); /** * Returns a {@link Collection} containing the intersection * of the given {@link Collection}s. *

* The cardinality of each element in the returned {@link Collection} * will be equal to the minimum of the cardinality of that element * in the two given {@link Collection}s. * * @param a the first collection, must not be null * @param b the second collection, must not be null * @return the intersection of the two collections */ public static Collection intersection(final Collection a, final Collection b) { ArrayList list = new ArrayList(); Map mapa = getCardinalityMap(a); Map mapb = getCardinalityMap(b); Set elts = new HashSet(a); elts.addAll(b); Iterator it = elts.iterator(); while(it.hasNext()) { Object obj = it.next(); for(int i=0,m=Math.min(getFreq(obj,mapa),getFreq(obj,mapb));i * Only those elements present in the collection will appear as * keys in the map. * * @param coll the collection to get the cardinality map for, must not be null * @return the populated cardinality map */ public static Map getCardinalityMap(final Collection coll) { Map count = new HashMap(); for (Iterator it = coll.iterator(); it.hasNext();) { Object obj = it.next(); Integer c = (Integer) (count.get(obj)); if (c == null) { count.put(obj,INTEGER_ONE); } else { count.put(obj,new Integer(c.intValue() + 1)); } } return count; } private static final int getFreq(final Object obj, final Map freqMap) { Integer count = (Integer) freqMap.get(obj); if (count != null) { return count.intValue(); } return 0; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/JsonSourceViewer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlexTable; import org.dashbuilder.json.JsonArray; import org.dashbuilder.json.JsonObject; import org.dashbuilder.json.JsonString; import org.dashbuilder.json.JsonValue; public class JsonSourceViewer extends Composite { private final static String INDENT = " "; public FlexTable table; public JsonSourceViewer() { this.table = new FlexTable(); initWidget( table ); } public void setContent(JsonObject jsonSource) { clearContent(); String jsonSourceString = formatJsonObjectAsString(jsonSource, ""); final String[] rows = jsonSourceString.split( "\n" ); for ( int i = 0; i < rows.length; i++ ) { String escaped = replaceLeadingWhitespaces( rows [ i ] ); table.setHTML( i, 0, escaped ); } } private String replaceLeadingWhitespaces( String text ) { String s = text.trim(); if ( s.length() == 0) return ""; StringBuilder sb = new StringBuilder(""); int i = 0; while ( ' ' == text.charAt( i ) ) { sb.append( " " ); i++; } sb.append(text.substring(i)); return sb.toString(); } private void clearContent() { table.removeAllRows(); } private String formatJsonValueAsString(JsonValue jsonValue, String indent) { if (jsonValue == null) { return ""; } if (jsonValue instanceof JsonObject) { return formatJsonObjectAsString((JsonObject) jsonValue, indent); } else if (jsonValue instanceof JsonArray) { return formatJsonArrayAsString((JsonArray) jsonValue, indent); } else if (jsonValue instanceof JsonString) { return "\"" + ((JsonString) jsonValue).getString() + "\""; } else { return jsonValue.asString(); } } private String formatJsonObjectAsString(JsonObject jsonObject, String indent) { if ( jsonObject == null ) return ""; String newIndent = indent + INDENT; StringBuilder sb = new StringBuilder( "{" ); String[] keys = jsonObject.keys(); for ( int i = 0; i < keys.length; i++ ) { sb.append("\n"); sb.append(newIndent).append("\"").append(keys[i]).append("\"").append(": "); sb.append(newIndent).append(formatJsonValueAsString(jsonObject.get(keys[i]), newIndent)); sb.append(i == keys.length - 1 ? "" : ",").append("\n"); } sb.append(indent).append("}"); return sb.toString(); } private String formatJsonArrayAsString(JsonArray jsonArray, String indent) { if (jsonArray == null) { return ""; } String newIndent = indent + INDENT; StringBuilder sb = new StringBuilder("["); for (int i = 0; i < jsonArray.length(); i++) { sb.append("\n"); sb.append(newIndent ).append(formatJsonValueAsString(jsonArray.get(i), newIndent )); sb.append(i == jsonArray.length() - 1 ? "\n" : ", "); } sb.append(indent).append("]"); return sb.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/SpacerWidget.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client; import java.lang.String; import com.google.gwt.user.client.ui.HTML; public class SpacerWidget extends HTML { public static SpacerWidget SINGLE = new SpacerWidget( " " ); public static SpacerWidget DOUBLE = new SpacerWidget( "  " ); private SpacerWidget( String spaces ) { super( spaces ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/StringTemplateBuilder.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client; import java.util.HashSet; import java.util.Set; public class StringTemplateBuilder { protected String keyPrefix; protected String keySufix; protected Set keySet = new HashSet<>(); protected String sourceCode; public StringTemplateBuilder() { this("${", "}"); } public StringTemplateBuilder(String keyPrefix, String keySufix) { this.keyPrefix = keyPrefix; this.keySufix = keySufix; } public void setTemplate(String template) { this.sourceCode = template; this.extractKeys(); } public String getKeyPrefix() { return keyPrefix; } public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; } public String getKeySufix() { return keySufix; } public void setKeySufix(String keySufix) { this.keySufix = keySufix; } public String build() { return sourceCode; } public Set keys() { return keySet; } public String asVar(String key) { return getKeyPrefix() + key + getKeySufix(); } public StringTemplateBuilder replace(String key, String value) { sourceCode = sourceCode.replace(keyPrefix + key + keySufix, value); return this; } protected void extractKeys() { this.keySet.clear(); if (sourceCode != null) { int idx = 0; int end = 0; while (idx != -1 && end != -1) { idx = sourceCode.indexOf(keyPrefix, end); end = sourceCode.indexOf(keySufix, idx+keyPrefix.length()); if (idx != -1 && end != -1) { String key = sourceCode.substring(idx + 2, end); keySet.add(key); } } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/StringUtils.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; public class StringUtils { /** *

Checks if a String is empty ("") or null.

* *
     * StringUtils.isEmpty(null)      = true
     * StringUtils.isEmpty("")        = true
     * StringUtils.isEmpty(" ")       = false
     * StringUtils.isEmpty("bob")     = false
     * StringUtils.isEmpty("  bob  ") = false
     * 
* *

NOTE: This method changed in Lang version 2.0. * It no longer trims the String. * That functionality is available in isBlank().

* * @param str the String to check, may be null * @return true if the String is empty or null */ public static boolean isEmpty(String str) { return str == null || str.length() == 0; } /** *

Checks if a String is whitespace, empty ("") or null.

* *
     * StringUtils.isBlank(null)      = true
     * StringUtils.isBlank("")        = true
     * StringUtils.isBlank(" ")       = true
     * StringUtils.isBlank("bob")     = false
     * StringUtils.isBlank("  bob  ") = false
     * 
* * @param str the String to check, may be null * @return true if the String is null, empty or whitespace */ public static boolean isBlank(String str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if (!Character.isSpace(str.charAt(i))) { return false; } } return true; } /** *

Joins the elements of the provided array into a single String * containing the provided list of elements.

* *

No delimiter is added before or after the list. * A null separator is the same as an empty String (""). * Null objects or empty strings within the array are represented by * empty strings.

* *
     * StringUtils.join(null, *)                = null
     * StringUtils.join([], *)                  = ""
     * StringUtils.join([null], *)              = ""
     * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"
     * StringUtils.join(["a", "b", "c"], null)  = "abc"
     * StringUtils.join(["a", "b", "c"], "")    = "abc"
     * StringUtils.join([null, "", "a"], ',')   = ",,a"
     * 
* * @param array the array of values to join together, may be null * @param separator the separator character to use, null treated as "" * @return the joined String, null if null array input */ public static String join(Object[] array, String separator) { if (array == null) { return null; } StringBuilder builder = new StringBuilder(); for (int i = 0; i < array.length; i++) { Object o = array[i]; if (i > 0) { builder.append(separator); } builder.append(o); } return builder.toString(); } /** * Joins a collection of string with a given delimiter. * * @param strings The collection of strings to join. * @param delimiter The delimiter to use to join them. * @return The string built by joining the string with the delimiter. */ public static String join(Collection strings, String delimiter) { StringBuilder builder = new StringBuilder(); Iterator iter = strings.iterator(); while (iter.hasNext()) { builder.append(iter.next()); if (!iter.hasNext()) { break; } builder.append(delimiter); } return builder.toString(); } /** *

Splits the provided text into an array, separator specified. * This is an alternative to using StringTokenizer.

* *

The separator is not included in the returned String array. * Adjacent separators are treated as one separator. * For more control over the split use the StrTokenizer class.

* *

A {@code null} input String returns {@code null}.

* *
     * StringUtils.split(null, *)         = null
     * StringUtils.split("", *)           = []
     * StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
     * StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
     * StringUtils.split("a:b:c", '.')    = ["a:b:c"]
     * StringUtils.split("a b c", ' ')    = ["a", "b", "c"]
     * 
* * @param str the String to parse, may be null * @param separatorChar the character used as the delimiter * @return an list of parsed Strings, {@code null} if null String input */ public static List split(String str, char separatorChar) { List list = new ArrayList(); if (str == null || str.length() == 0) { return list; } if (str.indexOf(separatorChar) == -1) { list.add(str); return list; } int start = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == separatorChar) { String token = str.substring(start, i).trim(); if (token.length() > 0) { list.add(token); } start = i+1; } } String token = str.substring(start, str.length()).trim(); if (token.length() > 0) { list.add(token); } return list; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/backend/PathUrlFactory.java ================================================ package org.dashbuilder.common.client.backend; import javax.enterprise.context.ApplicationScoped; import com.google.gwt.core.client.GWT; import com.google.gwt.http.client.URL; import org.uberfire.backend.vfs.Path; /** * Factory for the generation of URL for accessing GIT files on backend. */ @ApplicationScoped public class PathUrlFactory { private static final String UPLOAD_SERVLET_URL = "defaulteditor/upload"; private static final String DOWNLOAD_SERVLET_URL = "defaulteditor/download"; private String getUrl(String context, String path) { return new StringBuilder(GWT.getModuleBaseURL()) .append(context) .append("?") .append("path") .append("=") .append(URL.encode(path)) .toString(); } /** *

Returns the download URL for a given file provided by a servlet method.

* @param path The path of the file. */ public String getDownloadFileUrl(final Path path) { return getUrl(DOWNLOAD_SERVLET_URL, path.toURI()); } /** *

Returns the download URL for a given file provided by a servlet method.

* @param path The path of the file. */ public String getDownloadFileUrl(final String path) { return getUrl(DOWNLOAD_SERVLET_URL, path); } /** *

Returns the upload URL for a given file provided by a servlet method.

* @param path The path of the file. */ public String getUploadFileUrl(String path) { return getUrl(UPLOAD_SERVLET_URL, path); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/HasConstrainedValue.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.Editor; /** *

Editor that accepts a set of predefined values.

* * @since 0.4.0 */ public interface HasConstrainedValue { /** *

Sets acceptable values for the editor.

*

If no acceptable values set BEFORE editing a T instance, the editor can either disable /remove/modify the editor's value/s or just not edit any value.

* * @param acceptableValues Acceptable values for the editor. */ @Editor.Ignore void setAcceptableValues(T acceptableValues); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/HasEditMode.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.Editor; /** *

Indicates that an editor can be used as read-only or as edit mode.

* * @since 0.4.0 */ public interface HasEditMode { /** *

Enables or disables the edition.

*/ @Editor.Ignore void isEditMode(boolean isEdit); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/HasRestrictedValue.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.Editor; /** *

Editor that restrict a set of predefined values to use.

* * @since 0.4.0 */ public interface HasRestrictedValue { /** * Specify the value that is restricted to use. * @param value */ @Editor.Ignore void onValueRestricted(T value); /** * Specify the value that was restricted for using but it can be used again. * @param value */ @Editor.Ignore void onValueUnRestricted(T value); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/LeafAttributeEditor.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.HasEditorErrors; import com.google.gwt.editor.client.LeafValueEditor; /** *

Editor contract for generic attributes.

* * @since 0.4.0 */ public interface LeafAttributeEditor extends HasEditorErrors, LeafValueEditor { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/ToggleSwitchEditor.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.EditorError; import com.google.gwt.editor.client.HasEditorErrors; import com.google.gwt.editor.client.LeafValueEditor; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import java.util.List; /** *

Provides an editor for Boolean values using a toggle switch for the view.

*

It displays the editor errors using a bootstrap tooltip.

* * @since 0.4.0 */ @Dependent public class ToggleSwitchEditor implements IsWidget, LeafAttributeEditor { public interface View extends UberView { View setValue(Boolean value); View setEnabled(Boolean value); View showError(final SafeHtml message); View clearError(); } Event> valueChangeEvent; public View view; Boolean value; @Inject public ToggleSwitchEditor(final View view, final Event> valueChangeEvent) { this.view = view; this.valueChangeEvent = valueChangeEvent; } @PostConstruct public void init() { view.init(this); } public void setEnabled(final boolean isEnabled) { view.setEnabled(isEnabled); } @Override public void showErrors(List errors) { StringBuilder sb = new StringBuilder(); for (EditorError error : errors) { if (error.getEditor() == this) { sb.append("\n").append(error.getMessage()); } } boolean hasErrors = sb.length() > 0; if (!hasErrors) { view.clearError(); return; } // Show the errors. view.showError(new SafeHtmlBuilder().appendEscaped(sb.substring(1)).toSafeHtml()); } @Override public Widget asWidget() { return view.asWidget(); } @Override public void setValue(Boolean value) { this.value = value; view.setValue(value); } @Override public Boolean getValue() { return value; } void onValueChanged(final Boolean value) { // Check value is not same one as current. if (this.value != null && this.value.equals(value)) return; // Clear error messages on the view. view.clearError(); // Set the new value. Boolean before = this.value; this.value = value; // Fire the value change event. valueChangeEvent.fire(new org.dashbuilder.common.client.event.ValueChangeEvent(this, before, this.value)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/ToggleSwitchEditorView.java ================================================ package org.dashbuilder.common.client.editor; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.editor.client.Editor; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.extras.toggleswitch.client.ui.ToggleSwitch; /** *

The ValueBoxEditor view.

* * @since 0.4.0 */ @Dependent public class ToggleSwitchEditorView extends Composite implements ToggleSwitchEditor.View { private static final String STYLE_ERROR = " control-group has-error "; interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } @UiField @Editor.Ignore HTMLPanel contents; @UiField @Editor.Ignore ToggleSwitch toggleSwitch; @UiField @Editor.Ignore Tooltip errorTooltip; ToggleSwitchEditor presenter; @Override public void init(final ToggleSwitchEditor presenter) { this.presenter = presenter; } @UiConstructor public ToggleSwitchEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); toggleSwitch.addValueChangeHandler(new ValueChangeHandler() { @Override public void onValueChange(final ValueChangeEvent event) { presenter.onValueChanged(event.getValue()); } }); } @Override public ToggleSwitchEditor.View setValue(final Boolean value) { toggleSwitch.setValue(value); return this; } @Override public ToggleSwitchEditor.View setEnabled(final Boolean isEnabled) { // Only set the boolean value is it's different from the current one, if not, the ToggleSwitch remains always disabled, probably due to a gwtboostrap bug. if (toggleSwitch.isEnabled() != isEnabled) { toggleSwitch.setEnabled(isEnabled); } return this; } @Override public ToggleSwitchEditor.View showError(final SafeHtml message) { contents.addStyleName(STYLE_ERROR); errorTooltip.setTitle(message.asString()); return this; } @Override public ToggleSwitchEditor.View clearError() { contents.removeStyleName(STYLE_ERROR); errorTooltip.setTitle(""); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/ToggleSwitchEditorView.ui.xml ================================================ .contents { border: none; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/ValueBoxEditor.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.EditorError; import com.google.gwt.editor.client.HasEditorErrors; import com.google.gwt.editor.client.LeafValueEditor; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.uibinder.client.UiChild; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.ValueBoxBase; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import java.util.List; /** *

Provides an editor for a ValueBoxBase widget of type T.

*

It displays the editor errors using a bootstrap tooltip.

* * @since 0.4.0 */ @Dependent public class ValueBoxEditor implements IsWidget, LeafAttributeEditor { public interface View extends UberView> { @UiChild(limit = 1, tagname = "valuebox") void setValueBox(final ValueBoxBase widget); View addHelpContent(final String title, final String content, final Placement placement); View setValue(T value); View showError(final SafeHtml message); View clearError(); } Event> valueChangeEvent; public View view; T value; @Inject public ValueBoxEditor(final View view, final Event> valueChangeEvent) { this.view = view; this.valueChangeEvent = valueChangeEvent; } @PostConstruct public void init() { view.init(this); } public void addHelpContent(final String title, final String content, final Placement placement) { view.addHelpContent(title, content, placement); } @Override public void showErrors(List errors) { StringBuilder sb = new StringBuilder(); for (final EditorError error : errors) { if (error.getEditor() == this) { sb.append("\n").append(error.getMessage()); } } boolean hasErrors = sb.length() > 0; if (!hasErrors) { view.clearError(); return; } // Show the errors. view.showError(new SafeHtmlBuilder().appendEscaped(sb.substring(1)).toSafeHtml()); } @Override public Widget asWidget() { return view.asWidget(); } @Override public void setValue(T value) { this.value = value; view.setValue(value); } @Override public T getValue() { return value; } void onValueChanged(final T value) { // Check value is not same one as current. if (this.value != null && this.value.equals(value)) return; // Clear error messages on the view. view.clearError(); // Set the new value. T before = this.value; this.value = value; // Fire the value change event. valueChangeEvent.fire(new org.dashbuilder.common.client.event.ValueChangeEvent(this, before, this.value)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/ValueBoxEditorView.java ================================================ package org.dashbuilder.common.client.editor; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.editor.client.Editor; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.ValueBoxBase; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.client.ui.constants.Placement; /** *

The ValueBoxEditor view.

* * @since 0.4.0 */ @Dependent public class ValueBoxEditorView extends Composite implements ValueBoxEditor.View { private static final String STYLE_ERROR = " control-group has-error "; interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } @UiField SimplePanel contents; @UiField @Editor.Ignore Tooltip errorTooltip; ValueBoxEditor presenter; ValueBoxBase widget; @Override public void init(final ValueBoxEditor presenter) { this.presenter = presenter; } @UiConstructor public ValueBoxEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public void setValueBox(final ValueBoxBase widget) { this.widget = widget; widget.addValueChangeHandler(new ValueChangeHandler() { @Override public void onValueChange(final ValueChangeEvent event) { presenter.onValueChanged(event.getValue()); } }); contents.add(widget); } @Override public ValueBoxEditor.View setValue(T value) { widget.setValue(value); return this; } @Override public ValueBoxEditor.View showError(SafeHtml message) { contents.addStyleName(STYLE_ERROR); errorTooltip.setTitle(message.asString()); return this; } @Override public ValueBoxEditor.View clearError() { contents.removeStyleName(STYLE_ERROR); errorTooltip.setTitle(""); return this; } public ValueBoxEditor.View addHelpContent(final String title, final String content, final Placement placement) { final Tooltip tooltip = new Tooltip(widget); tooltip.setContainer("body"); tooltip.setShowDelayMs(1000); tooltip.setPlacement(placement); tooltip.setTitle(content); contents.add(tooltip); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/ValueBoxEditorView.ui.xml ================================================ .contents { display: inline; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/file/FileUploadEditor.java ================================================ package org.dashbuilder.common.client.editor.file; import com.google.gwt.editor.client.EditorError; import com.google.gwt.editor.client.HasEditorErrors; import com.google.gwt.editor.client.LeafValueEditor; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.common.client.resources.i18n.DashbuilderCommonConstants; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import org.uberfire.workbench.events.NotificationEvent; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import java.util.List; import static org.uberfire.workbench.events.NotificationEvent.NotificationType.ERROR; import static org.uberfire.workbench.events.NotificationEvent.NotificationType.SUCCESS; /** *

Presenter for editor component that wraps a gwt bootstrap file upload component an additionally provides:

*
    *
  • Error messages - Show validation error messages.
  • *
  • Dashbuilder File Upload Servlet integration - It uses the UF Dashbuilder servlet for uploading files and provides a listener to obtain the uploaded file path.
  • *
* * @since 0.4.0 */ @Dependent public class FileUploadEditor implements IsWidget, LeafAttributeEditor { public interface View extends UberView { View addHelpContent(final String title, final String content, final Placement placement); View setFileUploadName(String name); View setFileUploadVisible(boolean visible); View setFileLabelText(String text); View setFileLabelVisible(boolean visible); View setLoadingImageVisible(boolean visible); String getFileName(); View setFormAction(String action); View submit(); View showError(final SafeHtml message); View clearError(); View setAccept(String type); View clear(); } public interface FileUploadEditorCallback { String getUploadFileName(); String getUploadFileUrl(); } Event workbenchNotification; Event> valueChangeEvent; public View view; String value; FileUploadEditorCallback callback; @Inject public FileUploadEditor(final Event> valueChangeEvent, final Event workbenchNotification, final View view) { this.valueChangeEvent = valueChangeEvent; this.workbenchNotification = workbenchNotification; this.view = view; } @PostConstruct public void init() { view.init(this); view.setLoadingImageVisible(false); view.setFileUploadName("fileUpload"); } public void configure(final String fileUploadName, final FileUploadEditorCallback callback) { view.setFileUploadName(fileUploadName); this.callback = callback; } public void addHelpContent(final String title, final String content, final Placement placement) { view.addHelpContent(title, content, placement); } @Override public void showErrors(List errors) { StringBuilder sb = new StringBuilder(); for (EditorError error : errors) { if (error.getEditor() == this) { sb.append("\n").append(error.getMessage()); } } boolean hasErrors = sb.length() > 0; if (!hasErrors) { view.clearError(); return; } // Show the errors. view.showError(new SafeHtmlBuilder().appendEscaped(sb.substring(1)).toSafeHtml()); } @Override public Widget asWidget() { return view.asWidget(); } @Override public void setValue(final String value) { this.value = value; if ( !isNullOrEmpty( view.getFileName() ) ) { view.setFileLabelVisible(false); } else if ( !isNullOrEmpty( value ) ) { int slash = value.lastIndexOf( "/" ) != -1 ? value.lastIndexOf( "/" ) : value.lastIndexOf( "\\" ); if ( slash == -1 ) { view.setFileLabelText( value ); } else { view.setFileLabelText( value.substring( slash + 1 ) ); } view.setFileLabelVisible(true); } } @Override public String getValue() { return value; } String getUploadFileName() { assert callback != null; return callback.getUploadFileName(); } String getUploadFileUrl() { assert callback != null; return callback.getUploadFileUrl(); } boolean onSubmit() { final String fileName = view.getFileName(); if ( isNullOrEmpty( fileName ) ) { return false; } else { view.setFileUploadVisible(false); view.setLoadingImageVisible(true); } return true; } void onSubmitComplete(final String results) { view.clearError(); view.setFileUploadVisible(true); view.setLoadingImageVisible(false); onValueChanged(view.getFileName()); // Show wb notification. if ( "OK".equalsIgnoreCase( results ) ) { workbenchNotification.fire(new NotificationEvent(DashbuilderCommonConstants.INSTANCE.uploadSuccessful(), SUCCESS)); } else if ( "FAIL".equalsIgnoreCase( results ) ) { workbenchNotification.fire(new NotificationEvent(DashbuilderCommonConstants.INSTANCE.uploadFailed(), ERROR)); } else if ( "FAIL - ALREADY EXISTS".equalsIgnoreCase( results ) ) { workbenchNotification.fire(new NotificationEvent(DashbuilderCommonConstants.INSTANCE.uploadFailedAlreadyExists(), ERROR)); } } void fileUploadHandler() { final String _f = getUploadFileName(); final String _a = getUploadFileUrl(); view.setFormAction( _a ); setValue( _f ); view.setFileLabelVisible(false); view.submit(); } private boolean isNullOrEmpty( final String fileName ) { return fileName == null || "".equals( fileName ); } void onValueChanged(final String value) { // Check value is not same one as current. if (this.value != null && this.value.equals(value)) return; // Clear error messages on the view. view.clearError(); // Set the new value. String before = this.value; this.value = value; // Fire the value change event. valueChangeEvent.fire(new org.dashbuilder.common.client.event.ValueChangeEvent(this, before, this.value)); } public void setAccept(String type) { view.setAccept(type); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/file/FileUploadEditorView.java ================================================ package org.dashbuilder.common.client.editor.file; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.editor.client.Editor; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.ext.widgets.common.client.common.FileUpload; import org.uberfire.mvp.Command; /** *

The FileUploadEditor view.

* * @since 0.4.0 */ @Dependent public class FileUploadEditorView extends Composite implements FileUploadEditor.View { private static final String STYLE_ERROR = " control-group has-error "; interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } @UiField @Editor.Ignore FlowPanel mainPanel; @UiField @Editor.Ignore FormPanel formPanel; @UiField @Editor.Ignore Tooltip errorTooltip; @UiField(provided = true) @Editor.Ignore org.uberfire.ext.widgets.common.client.common.FileUpload fileUpload; @UiField @Editor.Ignore org.gwtbootstrap3.client.ui.Label fileLabel; @UiField org.gwtbootstrap3.client.ui.Icon loadingIcon; FileUploadEditor presenter; @Override public void init(final FileUploadEditor presenter) { this.presenter = presenter; } @UiConstructor public FileUploadEditorView() { fileUpload = createFileUpload(); initWidget(Binder.BINDER.createAndBindUi(this)); initFormPanel(); } private FileUpload createFileUpload() { return new FileUpload( new Command() { @Override public void execute() { presenter.fileUploadHandler(); } }, true ); } private void initFormPanel() { formPanel.setEncoding( FormPanel.ENCODING_MULTIPART ); formPanel.setMethod( FormPanel.METHOD_POST ); formPanel.setWidget( fileUpload ); formPanel.addSubmitHandler(new FormPanel.SubmitHandler() { @Override public void onSubmit(final FormPanel.SubmitEvent event) { final boolean isFireEvent = presenter.onSubmit(); if (!isFireEvent) { event.cancel(); } } }); formPanel.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() { @Override public void onSubmitComplete(final FormPanel.SubmitCompleteEvent event) { presenter.onSubmitComplete(event.getResults()); } }); } @Override public FileUploadEditor.View addHelpContent(final String title, final String content, final Placement placement) { final Tooltip tooltip = new Tooltip(fileUpload); tooltip.setContainer("body"); tooltip.setShowDelayMs(1000); tooltip.setPlacement(placement); tooltip.setTitle(content); formPanel.add(tooltip); return this; } @Override public FileUploadEditor.View setFileUploadName(final String name) { fileUpload.setName(name); return this; } @Override public FileUploadEditor.View setFileUploadVisible(final boolean visible) { fileUpload.setVisible(visible); return this; } @Override public FileUploadEditor.View setFileLabelText(final String text) { fileLabel.setText(text); return this; } @Override public FileUploadEditor.View setFileLabelVisible(final boolean visible) { fileLabel.setVisible(visible); return this; } @Override public FileUploadEditor.View setLoadingImageVisible(final boolean visible) { loadingIcon.setVisible(visible); return this; } @Override public String getFileName() { return fileUpload.getFilename(); } @Override public FileUploadEditor.View setFormAction(final String action) { formPanel.setAction( action ); return this; } @Override public FileUploadEditor.View submit() { formPanel.submit(); return this; } @Override public FileUploadEditor.View showError(final SafeHtml message) { mainPanel.addStyleName(STYLE_ERROR); errorTooltip.setTitle(message.asString()); return this; } @Override public FileUploadEditor.View clearError() { mainPanel.removeStyleName(STYLE_ERROR); errorTooltip.setTitle(""); return this; } @Override public FileUploadEditor.View setAccept(String type) { fileUpload.setAccept(type); return this; } @Override public FileUploadEditor.View clear() { fileUpload.clear(); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/file/FileUploadEditorView.ui.xml ================================================ .mainPanel { margin-bottom: 5px; } .form { margin-bottom: -3px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/DropDownEditor.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.editor.list; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import org.uberfire.ext.widgets.common.client.dropdown.LiveSearchCallback; import org.uberfire.ext.widgets.common.client.dropdown.LiveSearchDropDown; import org.uberfire.ext.widgets.common.client.dropdown.LiveSearchResults; import org.uberfire.ext.widgets.common.client.dropdown.LiveSearchService; import org.uberfire.ext.widgets.common.client.dropdown.SingleLiveSearchSelectionHandler; @Dependent public class DropDownEditor implements IsWidget, LeafAttributeEditor { public interface View extends UberView { View addHelpContent(final String title, final String content, final Placement placement); View setDropDown(LiveSearchDropDown dropDown); View showError(final SafeHtml message); View clearError(); } public class Entry { private String value; private String hint; public Entry(String value, String hint) { this.value = value; this.hint = hint; } public String getValue() { return value; } public String getHint() { return hint; } } public View view; LiveSearchDropDown dropDown; LiveSearchService searchService = new LiveSearchService() { @Override public void search(String pattern, int maxResults, LiveSearchCallback callback) { getDropDownEntries(pattern, maxResults, callback); } @Override public void searchEntry(String key, LiveSearchCallback callback) { } }; SingleLiveSearchSelectionHandler selectionHandler = new SingleLiveSearchSelectionHandler<>(); Event> valueChangeEvent; Collection entries = new ArrayList<>(); String selectorHint; String value; @Inject public DropDownEditor(final View view, final LiveSearchDropDown dropDown, final Event> valueChangeEvent) { this.view = view; this.dropDown = dropDown; this.valueChangeEvent = valueChangeEvent; } @PostConstruct public void init() { view.init(this); view.setDropDown(dropDown); dropDown.setClearSelectionEnabled(false); dropDown.setSearchEnabled(false); dropDown.init(searchService, selectionHandler); dropDown.setOnChange(this::onEntrySelected); } @Override public Widget asWidget() { return view.asWidget(); } public void getDropDownEntries(String pattern, int maxResults, LiveSearchCallback callback) { final LiveSearchResults results = new LiveSearchResults(); entries.stream() .filter(e -> e.getHint().contains(pattern)) .forEach(e -> results.add(e.getValue(), e.getHint())); callback.afterSearch(results); } public void getExactEntry(String key, LiveSearchCallback callback) { final LiveSearchResults results = new LiveSearchResults(1); entries.stream() .filter(e -> e.getValue().equals(key)) .findAny() .ifPresent(e -> results.add(e.getValue(), e.getHint())); callback.afterSearch(results); } public void onEntrySelected() { String oldValue = value; value = getSelectedValue(); valueChangeEvent.fire(new ValueChangeEvent<>(this, oldValue, value)); } public String getSelectedValue() { String hint = selectionHandler.getSelectedValue(); Entry entry = getEntryByHint(hint); return entry.getValue(); } private Entry getEntryByHint(String hint) { for (Entry entry : entries) { if (entry.getHint().equals(hint)) { return entry; } } return null; } private Entry getEntryByValue(String value) { for (Entry entry : entries) { if (entry.getValue().equals(value)) { return entry; } } return null; } public void setSelectHint(String hint) { selectorHint = hint; dropDown.setSelectorHint(hint); } public Entry newEntry(final String value, String hint) { return new Entry(value, hint); } public void setEntries(final Collection entries) { this.entries.clear(); if (entries != null) { for (Entry entry : entries) { this.entries.add(entry); if (entry.getValue().equals(value)) { this.dropDown.setSelectedItem(entry.getValue()); } } } } public void addHelpContent(final String title, final String content, final Placement placement) { view.addHelpContent(title, content, placement); } public void clear() { this.entries.clear(); this.value = null; this.dropDown.clear(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public void showErrors(final List errors) { StringBuilder sb = new StringBuilder(); for (EditorError error : errors) { if (error.getEditor().equals(this)) { sb.append("\n").append(error.getMessage()); } } boolean hasErrors = sb.length() > 0; if (!hasErrors) { view.clearError(); return; } // Show the errors. view.showError(new SafeHtmlBuilder().appendEscaped(sb.substring(1)).toSafeHtml()); } @Override public String getValue() { return value; } @Override public void setValue(final String value) { this.value = value; Entry entry = getEntryByValue(value); if (entry != null) { this.dropDown.setSelectedItem(value); } else { this.dropDown.setSelectedItem(selectorHint); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/DropDownEditorView.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.editor.list; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.editor.client.Editor; import com.google.gwt.resources.client.CssResource; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.ext.widgets.common.client.dropdown.LiveSearchDropDown; @Dependent public class DropDownEditorView extends Composite implements DropDownEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } interface DropDownEditorViewStyle extends CssResource { String errorPanel(); String errorPanelWithError(); } @UiField DropDownEditorViewStyle style; @UiField @Editor.Ignore HTMLPanel errorPanel; @UiField @Editor.Ignore FlowPanel helpPanel; @UiField @Editor.Ignore Tooltip errorTooltip; LiveSearchDropDown dropDown; DropDownEditor presenter; @Override public void init(final DropDownEditor presenter) { this.presenter = presenter; } @UiConstructor public DropDownEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public DropDownEditorView setDropDown(LiveSearchDropDown dropDown) { this.dropDown = dropDown; helpPanel.add(dropDown); return this; } @Override public DropDownEditorView addHelpContent(String title, String content, Placement placement) { final Tooltip tooltip = new Tooltip(dropDown.asWidget()); tooltip.setContainer("body"); tooltip.setShowDelayMs(1000); tooltip.setPlacement(placement); tooltip.setTitle(content); helpPanel.add(tooltip); return this; } @Override public DropDownEditorView showError(SafeHtml message) { errorTooltip.setTitle(message.asString()); errorPanel.removeStyleName(style.errorPanel()); errorPanel.addStyleName(style.errorPanelWithError()); return this; } @Override public DropDownEditorView clearError() { errorTooltip.setTitle(""); errorPanel.removeStyleName(style.errorPanelWithError()); errorPanel.addStyleName(style.errorPanel()); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/DropDownEditorView.ui.xml ================================================ .errorPanel { border: none; } .errorPanelWithError { border-style: solid; border-color: red; border-width: 1px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/DropDownImageListEditor.java ================================================ package org.dashbuilder.common.client.editor.list; import org.dashbuilder.common.client.editor.HasEditMode; import org.dashbuilder.common.client.event.ValueChangeEvent; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; /** *

Images are shown using a drop down selector.

* * @param The edited type. * * @since 0.4.0 */ @Dependent public class DropDownImageListEditor extends ImageListEditor implements HasEditMode { boolean isEditMode = true; public interface View extends ImageListEditorView { void setDropDown(boolean isDropDown); } @Inject public DropDownImageListEditor(DropDownImageListEditorView dropDownImageListEditorView, Event> valueChangeEvent) { super(dropDownImageListEditorView, valueChangeEvent); } protected DropDownImageListEditor(ImageListEditorView imageListEditorView, Event> valueChangeEvent) { super(imageListEditorView, valueChangeEvent); } @Override public void isEditMode(final boolean isEdit) { this.isEditMode = isEdit; showElements(); } @Override protected void showElements() { super.showElements(); ((DropDownImageListEditor.View)view).setDropDown(isEditMode && entries != null && entries.size() > 1); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/DropDownImageListEditorView.java ================================================ package org.dashbuilder.common.client.editor.list; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.editor.client.Editor; import com.google.gwt.resources.client.CssResource; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Anchor; import org.gwtbootstrap3.client.ui.DropDown; import org.gwtbootstrap3.client.ui.DropDownMenu; import org.gwtbootstrap3.client.ui.Image; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.mvp.Command; /** *

The ImageListEditor view that uses a drop down as selector.

* * @since 0.4.0 */ @Dependent public class DropDownImageListEditorView extends Composite implements DropDownImageListEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } interface DropDownImageListEditorViewStyle extends CssResource { String errorPanel(); String errorPanelWithError(); String image(); } @UiField DropDownImageListEditorViewStyle style; @UiField @Editor.Ignore HTMLPanel errorPanel; @UiField @Editor.Ignore FlowPanel helpPanel; @UiField @Editor.Ignore DropDown dropDown; @UiField @Editor.Ignore Anchor dropDownAnchor; @UiField @Editor.Ignore DropDownMenu dropDownMenu; @UiField @Editor.Ignore Tooltip errorTooltip; @Editor.Ignore Image currentTypeImage; @Editor.Ignore InlineLabel caret; Tooltip currentTypeImageTooltip; ImageListEditor presenter; @Override public void init(final ImageListEditor presenter) { this.presenter = presenter; } @UiConstructor public DropDownImageListEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); currentTypeImage = new Image(); caret = new InlineLabel(); caret.addStyleName( "caret" ); caret.setVisible( true); dropDownAnchor.add( currentTypeImage ); dropDownAnchor.add( caret ); dropDownAnchor.setEnabled( true ); currentTypeImageTooltip = new Tooltip(dropDown); currentTypeImageTooltip.setContainer("body"); currentTypeImageTooltip.setShowDelayMs(100); currentTypeImage.addClickHandler(e -> currentTypeImageTooltip.hide()); caret.addClickHandler(e -> currentTypeImageTooltip.hide()); helpPanel.add(currentTypeImageTooltip); } @Override public ImageListEditorView add(final SafeUri uri, final String width, final String height, final SafeHtml heading, final SafeHtml text, final boolean selected, final Command clickCommand) { if (selected) { currentTypeImage.setUrl( uri ); currentTypeImage.setSize( width, height ); } else { final Tooltip tooltip = new Tooltip(); tooltip.setTitle(text.asString()); tooltip.setContainer("body"); tooltip.setPlacement(Placement.RIGHT); tooltip.setShowDelayMs(100); final Image image = new Image(uri); image.setWidth(width); image.setHeight(height); image.addStyleName(style.image()); image.addClickHandler(e -> { tooltip.hide(); clickCommand.execute(); }); tooltip.setWidget(image); dropDownMenu.add(image); } return this; } @Override public ImageListEditorView setHelpContent(String title, String content, Placement placement) { currentTypeImageTooltip.setPlacement(placement); currentTypeImageTooltip.setTitle(content); currentTypeImageTooltip.hide(); return this; } @Override public ImageListEditorView showError(SafeHtml message) { errorTooltip.setTitle(message.asString()); errorPanel.removeStyleName(style.errorPanel()); errorPanel.addStyleName(style.errorPanelWithError()); return this; } @Override public ImageListEditorView clearError() { errorTooltip.setTitle(""); errorPanel.removeStyleName(style.errorPanelWithError()); errorPanel.addStyleName(style.errorPanel()); return this; } @Override public ImageListEditorView clear() { clearError(); dropDownMenu.clear(); return this; } @Override public void setDropDown(boolean isDropDown) { dropDownAnchor.setEnabled( isDropDown ); caret.setVisible( isDropDown ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/DropDownImageListEditorView.ui.xml ================================================ .errorPanel { border: none; } .errorPanelWithError { border-style: solid; border-color: red; border-width: 1px; } .image { cursor: pointer; margin: 5px; } .dropDown { min-width: 32px; } .dropDown ul { min-width: 0; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/HorizImageListEditor.java ================================================ package org.dashbuilder.common.client.editor.list; import org.dashbuilder.common.client.event.ValueChangeEvent; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; /** *

Images are shown in an single row container.

* * @param The edited type. * * @since 0.4.0 */ @Dependent public class HorizImageListEditor extends ImageListEditor { @Inject public HorizImageListEditor(HorizImageListEditorView horizImageListEditorView, Event> valueChangeEvent) { super(horizImageListEditorView, valueChangeEvent); } protected HorizImageListEditor(ImageListEditorView imageListEditorView, Event> valueChangeEvent) { super(imageListEditorView, valueChangeEvent); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/HorizImageListEditorView.java ================================================ package org.dashbuilder.common.client.editor.list; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.editor.client.Editor; import com.google.gwt.resources.client.CssResource; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.HasAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Image; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.mvp.Command; /** *

The ImageListEditor default view. It places images in an horizontal way.

* * @since 0.4.0 */ @Dependent public class HorizImageListEditorView extends Composite implements ImageListEditorView { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } interface HorizImageListEditorViewStyle extends CssResource { String errorPanel(); String errorPanelWithError(); String image(); } @UiField HorizImageListEditorViewStyle style; @UiField @Editor.Ignore HTMLPanel errorPanel; @UiField @Editor.Ignore FlowPanel helpPanel; @UiField @Editor.Ignore HorizontalPanel mainPanel; @UiField @Editor.Ignore Tooltip errorTooltip; ImageListEditor presenter; @Override public void init(final ImageListEditor presenter) { this.presenter = presenter; } @UiConstructor public HorizImageListEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public ImageListEditorView add(final SafeUri uri, final String width, final String height, final SafeHtml heading, final SafeHtml text, final boolean selected, final Command clickCommand) { final VerticalPanel panel = new VerticalPanel(); panel.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE); panel.setHeight("100%"); final Image image = new Image(uri); image.setWidth(width); image.setHeight(height); image.addStyleName(style.image()); final double alpha = selected ? 1 : 0.2; image.getElement().setAttribute("style", "filter: alpha(opacity=5);opacity: " + alpha); final Tooltip tooltip = new Tooltip(); tooltip.setTitle( text.asString() ); tooltip.setWidget(image); tooltip.setContainer("body"); tooltip.setPlacement(Placement.BOTTOM); tooltip.setIsAnimated(false); tooltip.setShowDelayMs(100); final HTML label = new HTML(heading.asString()); final HorizontalPanel labelPanel = new HorizontalPanel(); labelPanel.setWidth("100%"); labelPanel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER); labelPanel.add(label); panel.add(tooltip); panel.add(labelPanel); mainPanel.add(panel); image.addClickHandler(e -> { tooltip.hide(); tooltip.destroy(); clickCommand.execute(); }); return this; } @Override public ImageListEditorView setHelpContent(final String title, final String content, final Placement placement) { final Tooltip tooltip = new Tooltip(mainPanel); tooltip.setContainer("body"); tooltip.setShowDelayMs(1000); tooltip.setPlacement(placement); tooltip.setTitle(content); helpPanel.add(tooltip); return this; } @Override public ImageListEditorView showError(SafeHtml message) { errorTooltip.setTitle(message.asString()); errorPanel.removeStyleName(style.errorPanel()); errorPanel.addStyleName(style.errorPanelWithError()); return null; } @Override public ImageListEditorView clearError() { errorTooltip.setTitle(""); errorPanel.removeStyleName(style.errorPanelWithError()); errorPanel.addStyleName(style.errorPanel()); return this; } @Override public ImageListEditorView clear() { clearError(); mainPanel.clear(); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/HorizImageListEditorView.ui.xml ================================================ .errorPanel { border: none; } .errorPanelWithError { border-style: solid; border-color: red; border-width: 1px; } .image { cursor: pointer; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/ImageListEditor.java ================================================ package org.dashbuilder.common.client.editor.list; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.gwtbootstrap3.client.ui.constants.Placement; import javax.annotation.PostConstruct; import javax.enterprise.event.Event; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** *

Presenter for a gwt editor component that accepts multiple values and display each one using a given image.

*

The validation error messages are displayed by changing border color to RED and showing the message using a tooltip.

*

This component is typically used for handling enums.

* * @param The edited type. * * @since 0.4.0 */ public abstract class ImageListEditor implements IsWidget, LeafAttributeEditor { private static final String IMAGE_SIZE = "160px"; public class Entry { private T value; private SafeUri uri; private SafeHtml heading; private SafeHtml text; private Entry(final T value, final SafeUri uri, final SafeHtml heading, final SafeHtml text) { this.value = value; this.uri = uri; this.heading = heading; this.text = text; } public T getValue() { return value; } public SafeUri getUri() { return uri; } public SafeHtml getHeading() { return heading; } public SafeHtml getText() { return text; } } Event> valueChangeEvent; public ImageListEditorView view; final List entries = new ArrayList(); String imageWidth = IMAGE_SIZE; String imageHeight = IMAGE_SIZE; T value; public ImageListEditor(final ImageListEditorView view, final Event> valueChangeEvent) { this.view = view; this.valueChangeEvent = valueChangeEvent; } @PostConstruct public void init() { view.init(this); } public Entry newEntry(final T value, final SafeUri uri, final SafeHtml heading, final SafeHtml text) { return new Entry(value, uri, heading, text); } public void setEntries(final Collection entries) { this.entries.clear(); if (entries != null) { this.entries.addAll(entries); } showElements(); } public void setImageSize(final String w, final String h) { this.imageWidth = w; this.imageHeight = h; } public void setHelpContent(final String title, final String content, final Placement placement) { view.setHelpContent(title, content, placement); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public void showErrors(final List errors) { StringBuilder sb = new StringBuilder(); for (EditorError error : errors) { if (error.getEditor().equals(this)) { sb.append("\n").append(error.getMessage()); } } boolean hasErrors = sb.length() > 0; if (!hasErrors) { view.clearError(); return; } // Show the errors. view.showError(new SafeHtmlBuilder().appendEscaped(sb.substring(1)).toSafeHtml()); } @Override public T getValue() { return value; } @Override public void setValue(final T value) { setValue(value, false); } public void setValue(final T value, final boolean fireEvents) { if (this.value != null && this.value.equals(value)) return; T before = this.value; this.value = value; showElements(); if (fireEvents) { valueChangeEvent.fire(new org.dashbuilder.common.client.event.ValueChangeEvent(this, before, this.value)); } } @Override public Widget asWidget() { return view.asWidget(); } public void clear() { this.entries.clear(); this.imageWidth = IMAGE_SIZE; this.imageHeight = IMAGE_SIZE; this.value = null; view.clear(); } /************************************************************* ** PRIVATE EDITOR METHODS ** *************************************************************/ protected void showElements() { view.clear(); for (final Entry entry : entries) { final boolean selected = this.value == null || entry.getValue().equals(this.value); view.add(entry.getUri(), this.imageWidth, this.imageHeight, entry.getHeading(), entry.getText(), selected, () -> { ImageListEditor.this.setValue(entry.getValue(), true); }); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/list/ImageListEditorView.java ================================================ package org.dashbuilder.common.client.editor.list; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeUri; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; /** *

An image list editor view contract.

* * @since 0.4.0 */ public interface ImageListEditorView extends UberView> { ImageListEditorView add(final SafeUri uri, final String width, final String height, final SafeHtml heading, final SafeHtml text, final boolean selected, final Command clickCommand); ImageListEditorView setHelpContent(final String title, final String content, final Placement placement); ImageListEditorView showError(final SafeHtml message); ImageListEditorView clearError(); ImageListEditorView clear(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/map/MapEditor.java ================================================ package org.dashbuilder.common.client.editor.map; import com.google.gwt.editor.client.EditorError; import com.google.gwt.editor.client.HasEditorErrors; import com.google.gwt.editor.client.LeafValueEditor; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.common.client.resources.i18n.DashbuilderCommonConstants; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import java.util.*; /** *

Provides an editor for a Map instance of String values.

* * @since 0.4.0 */ @Dependent public class MapEditor implements IsWidget, LeafAttributeEditor> { public interface View extends UberView { View setEmptyText(String text); View setAddText(String text); View addTextColumn(int columnIndex, String header, boolean isSortable, int width); View addButtonColumn(int columnIndex, String header, int width); View removeColumn(int index); View setRowCount(int count); View setData(List> data); View showError(SafeHtml message); View clearError(); } Event>> valueChangeEvent; public View view; Map value; @Inject public MapEditor(final View view, final Event>> valueChangeEvent) { this.view = view; this.valueChangeEvent = valueChangeEvent; } @PostConstruct public void init() { view.init(this); view.setAddText(DashbuilderCommonConstants.INSTANCE.add()); initDataGrid(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public void showErrors(final List errors) { StringBuilder sb = new StringBuilder(); for (EditorError error : errors) { if (error.getEditor() == this) { sb.append("\n").append(error.getMessage()); } } boolean hasErrors = sb.length() > 0; if (!hasErrors) { view.clearError(); return; } // Show the errors. view.showError(new SafeHtmlBuilder().appendEscaped(sb.substring(1)).toSafeHtml()); } @Override public Widget asWidget() { return view.asWidget(); } @Override public void setValue(final Map value) { setValue(value, false); } @Override public Map getValue() { return value; } /************************************************************* ** VIEW CALLBACK METHODS ** *************************************************************/ void addEntry() { onAddEntry(); } String getValue(final int columnIndex, final Map.Entry object) { // Key updated. if (columnIndex == 0) { return object.getKey(); } // Value updated. if (columnIndex == 1) { return object.getValue(); } return null; } void update(final int columnIndex, final int index, final Map.Entry object, final String value) { // Key updated. if (columnIndex == 0) { onKeyUpdated(index, object, value); // Value updated. } else if (columnIndex == 1) { onValueUpdated(index, object, value); // Remove action. } else if (columnIndex == 2) { onRemoveEntry(object); } } /************************************************************* ** PRIVATE EDITOR METHODS ** *************************************************************/ private void onKeyUpdated(final int index, final Map.Entry object, final String value) { final HashMap _m = new LinkedHashMap(getValue()); final String lastKeyValue = object.getKey(); String mapValue = ""; if (lastKeyValue != null) { mapValue = _m.remove(lastKeyValue); } _m.put(value, mapValue); setValue(_m, true); } private void onValueUpdated(final int index, final Map.Entry object, final String value) { // Look for the entry. final String key = getKeyParameter(index); final HashMap _m = new LinkedHashMap(getValue()); _m.put(key, value); setValue(_m, true); } private void onRemoveEntry(final Map.Entry object) { if (getValue() != null) { final HashMap _m = new LinkedHashMap(getValue()); _m.remove(object.getKey()); setValue(_m, true); } } private void onAddEntry() { final String key = DashbuilderCommonConstants.INSTANCE.newValue(); final String value = DashbuilderCommonConstants.INSTANCE.newValue(); final HashMap _m = new LinkedHashMap();; _m.put(key, value); if (getValue() != null) { _m.putAll(getValue()); } // New value. setValue(_m, true); } private void setValue(final Map value, final boolean fireEvents) { // Disable current error markers, if present. view.clearError(); final Map before = this.value; this.value = value; // Fill grid values. redraw(); // Fire events, if necessary. if (fireEvents) { valueChangeEvent.fire(new ValueChangeEvent>(this, before, value)); } } private void initDataGrid() { view.setEmptyText(DashbuilderCommonConstants.INSTANCE.noData()); addColumns(); } private void addColumns() { // Key column. view.addTextColumn(0, DashbuilderCommonConstants.INSTANCE.key(), false, 20); // Value column. view.addTextColumn(1, DashbuilderCommonConstants.INSTANCE.value(), false, 20); // Remove action column. view.addButtonColumn(2, DashbuilderCommonConstants.INSTANCE.actions(), 20); } private String getKeyParameter(final int index) { if (getValue() != null && !getValue().isEmpty() && index > -1) { int x = 0; for (Map.Entry entry : getValue().entrySet()) { if (index == x) return entry.getKey(); x++; } } return null; } private void redraw() { // NOTE: If not removing and re-adding columns, grid tow data refresh is not well done. view.removeColumn(0); view.removeColumn(0); view.removeColumn(0); // Rebuild grid columns. initDataGrid(); // Set new data. final int count = value != null ? value.size() : 0; final List> list = value != null ? new LinkedList>(value.entrySet()) : new LinkedList>(); view.setRowCount(count); view.setData(list); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/map/MapEditorView.java ================================================ package org.dashbuilder.common.client.editor.map; import com.google.gwt.cell.client.EditTextCell; import com.google.gwt.cell.client.FieldUpdater; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style; import com.google.gwt.editor.client.Editor; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.*; import org.gwtbootstrap3.client.ui.constants.ButtonSize; import org.gwtbootstrap3.client.ui.constants.IconType; import org.gwtbootstrap3.client.ui.gwt.ButtonCell; import org.gwtbootstrap3.client.ui.gwt.DataGrid; import javax.enterprise.context.Dependent; import java.util.List; import java.util.Map; /** *

The MapEditor view that uses a DataGrid widget.

* * @since 0.4.0 */ @Dependent public class MapEditorView extends Composite implements MapEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } @UiField @Editor.Ignore HTMLPanel mainPanel; @UiField @Editor.Ignore ScrollPanel gridPanel; @UiField DataGrid> grid; @UiField @Editor.Ignore org.gwtbootstrap3.client.ui.Button addButton; @UiField @Editor.Ignore org.gwtbootstrap3.client.ui.Label errorLabel; private MapEditor presenter; @UiConstructor public MapEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); addButton.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { presenter.addEntry(); } }); } @Override public void init(final MapEditor presenter) { this.presenter = presenter; } @Override public MapEditor.View setEmptyText(final String text) { grid.setEmptyTableWidget(new org.gwtbootstrap3.client.ui.Label(text)); return this; } @Override public MapEditor.View setAddText(final String text) { addButton.setText(text); addButton.setTitle(text); return this; } @Override public MapEditor.View addTextColumn(final int columnIndex, final String heading, boolean isSortable, int width) { final com.google.gwt.user.cellview.client.Column, String> keyColumn = new com.google.gwt.user.cellview.client.Column, String>(new EditTextCell()) { @Override public String getValue(final Map.Entry object) { return presenter.getValue(columnIndex, object); } }; addColumn(keyColumn, columnIndex, heading, isSortable, width); return this; } @Override public MapEditor.View addButtonColumn(final int columnIndex, final String header, final int width) { final com.google.gwt.user.cellview.client.Column, String> removeColumn = new com.google.gwt.user.cellview.client.Column, String>(new ButtonCell( IconType.MINUS, ButtonSize.EXTRA_SMALL)) { @Override public String getValue(Map.Entry object) { return presenter.getValue(columnIndex, object); } }; addColumn(removeColumn, columnIndex, header, false, width); return this; } private void addColumn(final com.google.gwt.user.cellview.client.Column, String> column, final int columnIndex, final String header, final boolean isSortable, final int width) { column.setSortable(isSortable); column.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); grid.addColumn(column, header); grid.setColumnWidth(column, width, Style.Unit.PCT); column.setFieldUpdater(new FieldUpdater, String>() { @Override public void update(final int index, final Map.Entry object, final String value) { presenter.update(columnIndex, index, object, value); } }); } @Override public MapEditor.View removeColumn(final int index) { grid.removeColumn(index); return this; } @Override public MapEditor.View setRowCount(final int count) { grid.setRowCount(count); return this; } @Override public MapEditor.View setData(final List> data) { grid.setRowData(0, data); return this; } @Override public MapEditor.View showError(final SafeHtml message) { final Element element = errorLabel.getElement(); element.setInnerText(message.asString()); element.getStyle().setDisplay(Style.Display.INLINE); element.getStyle().setBorderColor("red"); element.getStyle().setBorderStyle(Style.BorderStyle.SOLID); element.getStyle().setBorderWidth(1, Style.Unit.PX); errorLabel.setVisible(true); return this; } @Override public MapEditor.View clearError() { final Element element = errorLabel.getElement(); element.setInnerText(""); element.getStyle().setDisplay(Style.Display.NONE); element.getStyle().setBorderWidth(0, Style.Unit.PX); errorLabel.setVisible(false); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/editor/map/MapEditorView.ui.xml ================================================ .mainPanel { } .errorPanelError { border: 1px solid red; } .gridPanel { width: 100%; } .grid { width: 100%; height: 200px; font-size: small; overflow: auto; } .addButtonPanel { width: 100%; text-align: right; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/error/ClientRuntimeError.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.error; import org.dashbuilder.common.client.StringUtils; /** * Class that wraps errors either captured or generated on client runtime. */ public class ClientRuntimeError { private String message; private Throwable throwable; public ClientRuntimeError(String message) { this(message, null); } public ClientRuntimeError(Throwable e) { this(null, e); } public ClientRuntimeError(String message, Throwable e) { this.message = message; this.throwable = e; } public Throwable getThrowable() { return throwable; } public String getMessage() { if (!StringUtils.isBlank(message)) { return message; } Throwable root = getRootCause(); return root.toString(); } public String getCause() { Throwable root = getRootCause(); if (root == null || getMessage().equals(root.toString())) { return null; } else { return root.getMessage(); } } public Throwable getRootCause() { Throwable target = throwable; while (true) { if (target == null || target.getCause() == null) { return target; } else { target = target.getCause(); } } } public String toString() { String cause = getCause(); return getMessage() + (cause != null ? " (cause: " + cause + ")" : ""); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/event/ContextualEvent.java ================================================ package org.dashbuilder.common.client.event; import org.uberfire.workbench.events.UberFireEvent; /** *

Base class for any event that is fired for a given context.

* * @since 0.4.0 */ public abstract class ContextualEvent implements UberFireEvent { private final Object context; public ContextualEvent(Object context) { this.context = context; } public Object getContext() { return context; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/event/ValueChangeEvent.java ================================================ package org.dashbuilder.common.client.event; /** *

CDI event for components that have a value and it can be changed.

* * @since 0.4.0 */ public class ValueChangeEvent extends ContextualEvent { private final T oldValue; private final T value; public ValueChangeEvent(final Object context, final T oldValue, final T value) { super(context); this.oldValue = oldValue; this.value = value; } public T getValue() { return value; } public T getOldValue() { return oldValue; } @Override public String toString() { return "ValueChangeEvent [value=" + value.toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/resources/bundles/DashbuilderCommonImages.java ================================================ /* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.resources.bundles; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.DataResource; import com.google.gwt.resources.client.ImageResource; /** * GWT managed images for common client components. */ public interface DashbuilderCommonImages extends ClientBundle { /* DEFAULT SLIDER */ @Source("images/slider/default/lessh.png") ImageResource lessh(); @Source("images/slider/default/lessv.png") ImageResource lessv(); @Source("images/slider/default/moreh.png") ImageResource moreh(); @Source("images/slider/default/morev.png") ImageResource morev(); @Source("images/slider/default/scaleh.png") DataResource scaleh(); @Source("images/slider/default/scalev.png") DataResource scalev(); @Source("images/slider/default/dragh.png") ImageResource dragh(); @Source("images/slider/default/dragv.png") ImageResource dragv(); /* TRIANGLE SLIDER */ @Source("images/slider/triangle/drag.png") ImageResource dragt(); @Source("images/slider/triangle/line.png") DataResource linet(); @Source("images/slider/triangle/more_less.png") ImageResource moreLesst(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/resources/bundles/DashbuilderCommonResources.java ================================================ package org.dashbuilder.common.client.resources.bundles; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; public interface DashbuilderCommonResources extends ClientBundle { DashbuilderCommonResources INSTANCE = GWT.create(DashbuilderCommonResources.class); DashbuilderCommonImages IMAGES = GWT.create(DashbuilderCommonImages.class); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface DashbuilderCommonConstants extends ConstantsWithLookup { DashbuilderCommonConstants INSTANCE = GWT.create( DashbuilderCommonConstants.class ); String add(); String remove(); String noData(); String key(); String value(); String actions(); String newValue(); String currentFilePath(); String uploadSuccessful(); String uploadFailed(); String uploadFailedAlreadyExists(); String clearAll(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonMessages.java ================================================ package org.dashbuilder.common.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; /** *

Common messages.

* * @since 0.3.0 */ public interface DashbuilderCommonMessages extends Messages { public static final DashbuilderCommonMessages INSTANCE = GWT.create(DashbuilderCommonMessages.class); String timeout(String seconds); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/AlertBox.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import javax.inject.Inject; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.client.mvp.UberElement; import org.uberfire.mvp.Command; public class AlertBox implements IsElement { public enum Level { DANGER, WARNING, SUCCESS, INFO } public interface View extends UberElement { void setMessage(String text); void setLevel(Level level); void setCloseEnabled(boolean enabled); } private View view; private Command onCloseCommand; @Inject public AlertBox(View view) { this.view = view; this.view.init(this); } @Override public HTMLElement getElement() { return view.getElement(); } public void setLevel(Level level) { view.setLevel(level); } public void setCloseEnabled(boolean enabled) { view.setCloseEnabled(enabled); } public void setMessage(String text) { view.setMessage(text); } public void setOnCloseCommand(Command onCloseCommand) { this.onCloseCommand = onCloseCommand; } public void close() { if (onCloseCommand != null) { onCloseCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/AlertBoxView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/AlertBoxView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import org.jboss.errai.common.client.dom.Button; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class AlertBoxView implements AlertBox.View, IsElement { @Inject @DataField Div alertDiv; @Inject @DataField Button closeButton; @Inject @DataField Span alertIcon; @Inject @DataField Span alertMessage; AlertBox presenter; private static final String[] ALERT_CLASS = {"alert-danger", "alert-warning", "alert-success", "alert-info"}; private static final String[] ALERT_ICON = {"pficon-error-circle-o", "pficon-warning-triangle-o", "pficon-ok", "pficon-info"}; @Override public void init(AlertBox presenter) { this.presenter = presenter; } @Override public void setMessage(String text) { alertMessage.setTextContent(text); } @Override public void setLevel(AlertBox.Level level) { String _alertClass = ALERT_CLASS[level.ordinal()]; String _alertIcon = ALERT_ICON[level.ordinal()]; alertDiv.setClassName("alert " + _alertClass); alertIcon.setClassName("pficon " + _alertIcon); } @Override public void setCloseEnabled(boolean enabled) { closeButton.setHidden(!enabled); } @EventHandler("closeButton") private void onClose(ClickEvent event) { presenter.close(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/AlertPanel.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.constants.AlertType; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class AlertPanel implements IsWidget { public interface View extends UberView { void show(AlertType severity, String message, Integer width, Command onOk, Command onCancel); } View view = null; public AlertPanel() { this(new AlertPanelView()); } @Inject public AlertPanel(View view) { this.view = view; view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void show(AlertType severity, String message, Integer width, Command onOk, Command onCancel) { view.show(severity, message, width, onOk, onCancel); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/AlertPanelView.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Alert; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.constants.AlertType; import org.uberfire.mvp.Command; @Dependent public class AlertPanelView extends Composite implements AlertPanel.View { interface ViewBinder extends UiBinder {} private static ViewBinder uiBinder = GWT.create(ViewBinder.class); @UiField Alert alert; @UiField Button okButton; @UiField Button cancelButton; AlertPanel presenter; Map pflyIconMap = new HashMap(); @Override public void init(AlertPanel presenter) { this.presenter = presenter; initWidget(uiBinder.createAndBindUi(this)); pflyIconMap.put(AlertType.SUCCESS, "pficon-ok"); pflyIconMap.put(AlertType.INFO, "pficon-info"); pflyIconMap.put(AlertType.WARNING, "pficon-warning-triangle-o"); pflyIconMap.put(AlertType.DANGER, "pficon-error-circle-o"); pflyIconMap.put(AlertType.DEFAULT, "pficon-info"); } @Override public void show(AlertType severity, String message, Integer width, final Command onOk, final Command onCancel) { alert.setType(severity); alert.addStyleName("pficon"); alert.addStyleName(pflyIconMap.get(severity)); alert.setText(" " + message + " "); if (width != null) { alert.setWidth(width + "px"); } if (onOk != null) { okButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent clickEvent) { onOk.execute(); } }); } if (onCancel != null) { cancelButton.setVisible(true); cancelButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent clickEvent) { onCancel.execute(); } }); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/AlertPanelView.ui.xml ================================================ .buttonsPanel { float: right; position: relative; margin: 10px; } .button { margin: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/CharacterBox.java ================================================ package org.dashbuilder.common.client.widgets; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.InputElement; import com.google.gwt.user.client.ui.RootPanel; /** *

Box class for character entry widgets (Support boostrap style).

*

This class implementation is same as com.github.gwtbootstrap.client.ui.TextBox but this one inherits from CharacterBoxBase.

* * @since 0.3.0 */ public class CharacterBox extends CharacterBoxBase { /** * Creates a TextBox widget that wraps an existing <input type='text'> * element. * * This element must already be attached to the document. If the element is * removed from the document, you must call * {@link RootPanel#detachNow(com.google.gwt.user.client.ui.Widget)}. * * @param element * the element to be wrapped */ public static CharacterBox wrap(Element element) { // Assert that the element is attached. assert Document.get().getBody().isOrHasChild(element); CharacterBox textBox = new CharacterBox(element); // Mark it attached and remember it for cleanup. textBox.onAttach(); RootPanel.detachOnWindowClose(textBox); return textBox; } /** * Creates an empty text box. */ public CharacterBox() { this(Document.get().createTextInputElement(), "gwt-TextBox"); } /** * This constructor may be used by subclasses to explicitly use an existing * element. This element must be an <input> element whose type is * 'text'. * * @param element * the element to be used */ protected CharacterBox(Element element) { super(element); assert InputElement.as(element).getType().equalsIgnoreCase("text"); } CharacterBox(Element element, String styleName) { super(element); if (styleName != null) { setStyleName(styleName); } } /** * Gets the maximum allowable length of the text box. * * @return the maximum length, in characters */ public int getMaxLength() { return getInputElement().getMaxLength(); } /** * Gets the number of visible characters in the text box. * * @return the number of visible characters */ public int getVisibleLength() { return getInputElement().getSize(); } /** * Sets the maximum allowable length of the text box. * * @param length * the maximum length, in characters */ public void setMaxLength(int length) { getInputElement().setMaxLength(length); } /** * Sets the number of visible characters in the text box. * * @param length * the number of visible characters */ public void setVisibleLength(int length) { getInputElement().setSize(length); } private InputElement getInputElement() { return getElement().cast(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/CharacterBoxBase.java ================================================ package org.dashbuilder.common.client.widgets; import com.google.gwt.dom.client.Element; import com.google.gwt.text.shared.AbstractRenderer; import com.google.gwt.text.shared.Parser; import org.gwtbootstrap3.client.ui.base.ValueBoxBase; /** *

Abstract base class for most character entry widgets. and Support boostrap style.

*

This class implementation is same as com.github.gwtbootstrap.client.ui.base.TextBoxBase but using Character types instead of String.

* * @since 0.3.0 */ public class CharacterBoxBase extends ValueBoxBase { private static final PassthroughRenderer RENDERER_INSTANCE = new PassthroughRenderer(); private static final PassthroughParser PARSER_INSTANCE = new PassthroughParser(); /** * Creates a text box that wraps the given browser element handle. This is * only used by subclasses. * * @param elem * the browser element to wrap */ protected CharacterBoxBase(Element elem) { super(elem, RENDERER_INSTANCE, PARSER_INSTANCE); } /** * Overridden to return "" from an empty text box. */ @Override public Character getValue() { Character raw = super.getValue(); return raw == null ? ' ' : raw; } private static class PassthroughRenderer extends AbstractRenderer { public PassthroughRenderer() { } public String render(Character object) { return object.toString(); } } private static class PassthroughParser implements Parser { public PassthroughParser() { } public Character parse(CharSequence object) { if (object.length() > 0) return object.charAt(0); return null; } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/FilterLabel.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import javax.inject.Inject; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.client.mvp.UberElement; import org.uberfire.mvp.Command; public class FilterLabel implements IsElement { public interface View extends UberElement { void setLabel(String label); } private View view; private String label; private Command onRemoveCommand; @Inject public FilterLabel(View view) { this.view = view; this.view.init(this); } @Override public HTMLElement getElement() { return view.getElement(); } public void setLabel(String label) { this.label = label; view.setLabel(label); } public String getLabel() { return label; } public void setOnRemoveCommand(Command onRemoveCommand) { this.onRemoveCommand = onRemoveCommand; } void onRemove() { if (onRemoveCommand != null) { onRemoveCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/FilterLabelSet.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import javax.inject.Inject; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberElement; import org.uberfire.mvp.Command; public class FilterLabelSet implements IsElement { public interface View extends UberElement { void clearAll(); void setClearAllEnabled(boolean enabled); void addLabel(FilterLabel label); } private View view; private SyncBeanManager beanManager; private Command onClearAllCommand; private int numberOfLabels = 0; @Inject public FilterLabelSet(View view, SyncBeanManager beanManager) { this.view = view; this.beanManager = beanManager; this.view.init(this); this.view.setClearAllEnabled(false); } @Override public HTMLElement getElement() { return view.getElement(); } public void clear() { view.clearAll(); view.setClearAllEnabled(false); numberOfLabels = 0; } public FilterLabel addLabel(String label) { FilterLabel filterLabel = beanManager.lookupBean(FilterLabel.class).newInstance(); filterLabel.setLabel(label); view.addLabel(filterLabel); numberOfLabels++; view.setClearAllEnabled(numberOfLabels>1); return filterLabel; } public void setOnClearAllCommand(Command onClearAllCommand) { this.onClearAllCommand = onClearAllCommand; } void onClearAll() { this.clear(); if (onClearAllCommand != null) { onClearAllCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/FilterLabelSetView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/FilterLabelSetView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import org.dashbuilder.common.client.resources.i18n.DashbuilderCommonConstants; import org.jboss.errai.common.client.dom.Anchor; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class FilterLabelSetView implements FilterLabelSet.View, IsElement { @Inject @DataField Div mainDiv; @Inject @DataField Anchor clearAll; FilterLabelSet presenter; @Override public void init(FilterLabelSet presenter) { this.presenter = presenter; clearAll.setTextContent(DashbuilderCommonConstants.INSTANCE.clearAll()); } @Override public void clearAll() { DOMUtil.removeAllChildren(mainDiv); mainDiv.appendChild(clearAll); } @Override public void setClearAllEnabled(boolean enabled) { clearAll.setHidden(!enabled); } @Override public void addLabel(FilterLabel label) { mainDiv.insertBefore(label.getElement(), clearAll); } @EventHandler("clearAll") private void onClearAll(ClickEvent event) { presenter.onClearAll(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/FilterLabelView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/java/org/dashbuilder/common/client/widgets/FilterLabelView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import org.jboss.errai.common.client.dom.Anchor; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class FilterLabelView implements FilterLabel.View, IsElement { @Inject @DataField Span labelText; @Inject @DataField Anchor labelRemove; FilterLabel presenter; @Override public void init(FilterLabel presenter) { this.presenter = presenter; } @Override public void setLabel(String label) { labelText.setTextContent(label); } @EventHandler("labelRemove") private void onRemove(ClickEvent event) { presenter.onRemove(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/CommonClient.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants.properties ================================================ add=Add remove=Remove noData=No data key=Key value=Value actions=Actions newValue=--New Value-- currentFilePath=Current file path uploadSuccessful=File uploaded successfully uploadFailed=File upload failed uploadFailedAlreadyExists=File upload failed. File already exists clearAll=Clear All ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants_de.properties ================================================ add=Hinzufügen remove=Entfernen noData=Keine Daten key=Schlüssel value=Wert actions=Aktionen newValue=--Neuer Wert-- currentFilePath=Aktueller Dateipfad uploadSuccessful=Datei erfolgreich hochgeladen uploadFailed=Hochladen der Datei fehlgeschlagen uploadFailedAlreadyExists=Hochladen der Datei fehlgeschlagen. Datei existiert bereits clearAll=Alle löschen ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants_es.properties ================================================ add=Agregar remove=Quitar noData=No hay datos key=Clave value=Valor actions=Acciones newValue=--Nuevo valor-- currentFilePath=Ruta de archivo actual uploadSuccessful=El archivo se cargó correctamente uploadFailed=Error al cargar el archivo uploadFailedAlreadyExists=Error al cargar el archivo. El archivo ya existe clearAll=Borrar todo ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants_fr.properties ================================================ add=Ajouter remove=Supprimer noData=Aucune donnée key=Clé value=Valeur actions=Actions newValue=--Nouvelle valeur-- currentFilePath=Chemin d''accès du fichier actuel uploadSuccessful=Fichier envoyé avec succès uploadFailed=Échec d''envoi du fichier uploadFailedAlreadyExists=L''envoi du fichier a échoué. Le fichier existe déjà clearAll=Effacer tout ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants_it.properties ================================================ add=Aggiungi remove=Rimuovi noData=Nessun dato key=Chiave value=Valore actions=Azioni newValue=--Nuovo Valore-- currentFilePath=Percorso file corrente uploadSuccessful=Caricamento file riuscito uploadFailed=Caricamento file fallito uploadFailedAlreadyExists=Caricamento file fallito. Il file esiste già clearAll=Cancella tutto ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants_ja.properties ================================================ add=追加 remove=削除 noData=データなし key=キー value=値 actions=アクション newValue=--新しい値-- currentFilePath=現在のファイルパス uploadSuccessful=ファイルが正しくアップロードされました uploadFailed=ファイルのアップロードが失敗しました uploadFailedAlreadyExists=ファイルのアップロードに失敗しました。ファイルはすでに存在します clearAll=すべて消去 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants_pt_BR.properties ================================================ add=Adicionar remove=Remover noData=Nenhum dado key=Key value=Valor actions=Ações newValue=--Novo Valor-- currentFilePath=Caminho do Arquivo Atual uploadSuccessful=Arquivo carregado com êxito uploadFailed=Falha no carregamento do arquivo uploadFailedAlreadyExists=Falha no carregamento do arquivo. O arquivo já existe. clearAll=Limpar tudo ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonConstants_zh_CN.properties ================================================ add=添加 remove=删除 noData=没有数据 key=键 value=值 actions=动作 newValue=--新的值-- currentFilePath=当前文件路径 uploadSuccessful=成功上传文件 uploadFailed=文件上传失败 uploadFailedAlreadyExists=文件上传失败。文件已存在。 clearAll=清除所有 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonMessages.properties ================================================ timeout=Timeout for current action fired after {0} seconds ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonMessages_es.properties ================================================ timeout=Tiempo de espera para la acción actual disparada después de {0} segundos ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonMessages_fr.properties ================================================ timeout=Délai d'exécution de l'action en cours après {0} secondes ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonMessages_it.properties ================================================ timeout=Timeout per l''azione corrente scaduto dopo {0} secondi ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/main/resources/org/dashbuilder/common/client/resources/i18n/DashbuilderCommonMessages_ja.properties ================================================ timeout=現在のアクションのタイムアウトを {0} 秒後に実行する ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/StringTemplateBuilderTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client; import java.util.Set; import org.junit.Test; import static org.junit.Assert.*; public class StringTemplateBuilderTest { @Test public void testNoReplacement() { StringTemplateBuilder templateBuilder = new StringTemplateBuilder(); templateBuilder.setTemplate("Hello ${user} from ${place}."); Set keys = templateBuilder.keys(); String code = templateBuilder.build(); assertEquals(keys.size(), 2); assertTrue(keys.contains("user")); assertTrue(keys.contains("place")); assertEquals(code, "Hello ${user} from ${place}."); } @Test public void testReplacement() { StringTemplateBuilder templateBuilder = new StringTemplateBuilder(); templateBuilder.setTemplate("Hello ${user} from ${place}."); templateBuilder.replace("user", "Mark"); templateBuilder.replace("place", "London"); String code = templateBuilder.build(); assertEquals(code, "Hello Mark from London."); } @Test public void testCustomKeys() { StringTemplateBuilder templateBuilder = new StringTemplateBuilder(); templateBuilder.setKeyPrefix("["); templateBuilder.setKeySufix("]"); templateBuilder.setTemplate("Hello [user] from [place]."); templateBuilder.replace("user", "Mark"); templateBuilder.replace("place", "London"); String code = templateBuilder.build(); assertEquals(code, "Hello Mark from London."); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/AbstractEditorTest.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.EditorError; import org.mockito.MockitoAnnotations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; public abstract class AbstractEditorTest { protected EditorError mockEditorError(final Editor editor, final String message) { EditorError error = mock(EditorError.class); doReturn(editor).when(error).getEditor(); doReturn(message).when(error).getMessage(); return error; } protected void setup() { MockitoAnnotations.initMocks(this); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/ToggleSwitchEditorTest.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtml; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mocks.EventSourceMock; import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class ToggleSwitchEditorTest extends AbstractEditorTest { @Mock ToggleSwitchEditor.View view; @Mock EventSourceMock> valueChangeEvent; private ToggleSwitchEditor presenter; @Before public void setup() { // The presenter instance to test. presenter = new ToggleSwitchEditor(view, valueChangeEvent); assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testInit() throws Exception { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).setValue(anyBoolean()); } @Test public void testClearErrors() throws Exception { List errors = new ArrayList(); presenter.showErrors(errors); verify(view, times(1)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setValue(anyBoolean()); } @Test public void testShowErrors() throws Exception { EditorError e1 = mockEditorError(presenter, "m1"); EditorError e2 = mockEditorError(presenter, "m2"); List errors = new ArrayList(2); errors.add(e1); errors.add(e2); presenter.showErrors(errors); final ArgumentCaptor errorSafeHtmlCaptor = ArgumentCaptor.forClass(SafeHtml.class); verify(view, times(1)).showError(errorSafeHtmlCaptor.capture()); verify(view, times(0)).init(presenter); verify(view, times(0)).clearError(); verify(view, times(0)).setValue(anyBoolean()); final SafeHtml value = errorSafeHtmlCaptor.getValue(); Assert.assertEquals("m1\nm2", value.asString()); } @Test public void testEnabled() throws Exception { presenter.setEnabled(true); verify(view, times(1)).setEnabled(true); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setValue(anyBoolean()); } @Test public void testValue() throws Exception { final Boolean newValue = true; presenter.setValue(newValue); assertEquals(newValue, presenter.getValue()); verify(view, times(1)).setValue(newValue); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); } @Test public void testOnValueChanged() throws Exception { final Boolean newValue = true; presenter.onValueChanged(newValue); assertEquals(newValue, presenter.getValue()); verify(view, times(1)).clearError(); verify(view, times(0)).setValue(newValue); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/ValueBoxEditorTest.java ================================================ package org.dashbuilder.common.client.editor; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtml; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mocks.EventSourceMock; import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class ValueBoxEditorTest extends AbstractEditorTest { @Mock ValueBoxEditor.View view; @Mock EventSourceMock> valueChangeEvent; private ValueBoxEditor presenter; @Before public void setup() { // The presenter instance to test. presenter = new ValueBoxEditor(view, valueChangeEvent); assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testInit() throws Exception { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).setValue(anyString()); } @Test public void testClearErrors() throws Exception { List errors = new ArrayList(); presenter.showErrors(errors); verify(view, times(1)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setValue(anyString()); } @Test public void testShowErrors() throws Exception { EditorError e1 = mockEditorError(presenter, "m1"); EditorError e2 = mockEditorError(presenter, "m2"); List errors = new ArrayList(2); errors.add(e1); errors.add(e2); presenter.showErrors(errors); final ArgumentCaptor errorSafeHtmlCaptor = ArgumentCaptor.forClass(SafeHtml.class); verify(view, times(1)).showError(errorSafeHtmlCaptor.capture()); verify(view, times(0)).init(presenter); verify(view, times(0)).clearError(); verify(view, times(0)).setValue(anyString()); final SafeHtml value = errorSafeHtmlCaptor.getValue(); Assert.assertEquals("m1\nm2", value.asString()); } @Test public void testAddHelpContent() throws Exception { final String title = "title"; final String content = "content"; final Placement p = Placement.BOTTOM; presenter.addHelpContent(title, content, p); verify(view, times(1)).addHelpContent(title, content, p); verify(view, times(0)).setValue(anyString()); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); } @Test public void testValue() throws Exception { final String newValue = "newValue"; presenter.setValue(newValue); assertEquals(newValue, presenter.getValue()); verify(view, times(1)).setValue(newValue); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); } @Test public void testOnValueChanged() throws Exception { final String newValue = "newValue"; presenter.onValueChanged(newValue); assertEquals(newValue, presenter.getValue()); verify(view, times(1)).clearError(); verify(view, times(0)).setValue(newValue); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/file/FileUploadEditorTest.java ================================================ package org.dashbuilder.common.client.editor.file; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.AbstractEditorTest; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mocks.EventSourceMock; import org.uberfire.workbench.events.NotificationEvent; import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class FileUploadEditorTest extends AbstractEditorTest { @Mock FileUploadEditor.View view; @Mock EventSourceMock> valueChangeEvent; @Mock EventSourceMock workbenchNotificationEvent; private FileUploadEditor presenter; @Before public void setup() { // The presenter instance to test. presenter = new FileUploadEditor(valueChangeEvent, workbenchNotificationEvent, view); assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testInit() throws Exception { presenter.init(); assertEquals(view.asWidget(), presenter.asWidget()); verify(view, times(1)).init(presenter); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(1)).setFileUploadName(anyString()); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(1)).setLoadingImageVisible(false); verify(view, times(0)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).clearError(); } @Test public void testConfigure() throws Exception { FileUploadEditor.FileUploadEditorCallback callback = mock(FileUploadEditor.FileUploadEditorCallback.class); presenter.configure("f1", callback); assertEquals(view.asWidget(), presenter.asWidget()); assertEquals(callback, presenter.callback); verify(view, times(0)).init(presenter); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(1)).setFileUploadName("f1"); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(0)).setLoadingImageVisible(false); verify(view, times(0)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).clearError(); } @Test public void testClearErrors() throws Exception { List errors = new ArrayList(); presenter.showErrors(errors); verify(view, times(1)).clearError(); verify(view, times(0)).init(presenter); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(0)).setLoadingImageVisible(anyBoolean()); verify(view, times(0)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); } @Test public void testShowErrors() throws Exception { EditorError e1 = mockEditorError(presenter, "m1"); EditorError e2 = mockEditorError(presenter, "m2"); List errors = new ArrayList(2); errors.add(e1); errors.add(e2); presenter.showErrors(errors); final ArgumentCaptor errorSafeHtmlCaptor = ArgumentCaptor.forClass(SafeHtml.class); verify(view, times(1)).showError(errorSafeHtmlCaptor.capture()); verify(view, times(0)).init(presenter); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(0)).setLoadingImageVisible(anyBoolean()); verify(view, times(0)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).clearError(); } @Test public void testAddHelpContent() throws Exception { final String title = "title"; final String content = "content"; final Placement p = Placement.BOTTOM; presenter.addHelpContent(title, content, p); verify(view, times(1)).addHelpContent(title, content, p); verify(view, times(0)).init(presenter); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(0)).setLoadingImageVisible(anyBoolean()); verify(view, times(0)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).clearError(); } @Test public void testValueSet() throws Exception { final String newValue = "newValue"; when(view.getFileName()).thenReturn("fff"); presenter.setValue(newValue); assertEquals(newValue, presenter.getValue()); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(1)).setFileLabelVisible(false); verify(view, times(0)).setLoadingImageVisible(anyBoolean()); verify(view, times(1)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).clearError(); } @Test public void testValueUnset() throws Exception { final String newValue = "newValue"; when(view.getFileName()).thenReturn(null); presenter.setValue(newValue); assertEquals(newValue, presenter.getValue()); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(1)).setFileLabelText(newValue); verify(view, times(1)).setFileLabelVisible(true); verify(view, times(0)).setLoadingImageVisible(anyBoolean()); verify(view, times(1)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).clearError(); } @Test public void testGetUploadFileName() throws Exception { FileUploadEditor.FileUploadEditorCallback callback = mock(FileUploadEditor.FileUploadEditorCallback.class); presenter.callback = callback; presenter.getUploadFileName(); verify(callback, times(1)).getUploadFileName(); verify(callback, times(0)).getUploadFileUrl(); } @Test public void testGetUploadFileUrl() throws Exception { FileUploadEditor.FileUploadEditorCallback callback = mock(FileUploadEditor.FileUploadEditorCallback.class); presenter.callback = callback; presenter.getUploadFileUrl(); verify(callback, times(1)).getUploadFileUrl(); verify(callback, times(0)).getUploadFileName(); } @Test public void testOnSubmitNull() throws Exception { when(view.getFileName()).thenReturn(null); final boolean result = presenter.onSubmit(); assertEquals(false, result); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(0)).setFileUploadVisible(anyBoolean()); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(0)).setLoadingImageVisible(anyBoolean()); verify(view, times(1)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).clearError(); } @Test public void testOnSubmit() throws Exception { when(view.getFileName()).thenReturn("ff"); final boolean result = presenter.onSubmit(); assertEquals(true, result); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(1)).setFileUploadVisible(false); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(1)).setLoadingImageVisible(true); verify(view, times(1)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).clearError(); } @Test public void testOnSubmitComplete() throws Exception { when(view.getFileName()).thenReturn("ff"); presenter.onSubmitComplete("OK"); assertEquals("ff", presenter.value); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).setFileUploadName(anyString()); verify(view, times(1)).setFileUploadVisible(true); verify(view, times(0)).setFileLabelText(anyString()); verify(view, times(0)).setFileLabelVisible(anyBoolean()); verify(view, times(1)).setLoadingImageVisible(false); verify(view, times(1)).getFileName(); verify(view, times(0)).setFormAction(anyString()); verify(view, times(0)).submit(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(2)).clearError(); verify( workbenchNotificationEvent, times( 1 ) ).fire(any(NotificationEvent.class)); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/list/DropDownEditorTest.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.editor.list; import java.util.ArrayList; import java.util.Collection; import javax.enterprise.event.Event; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.ext.widgets.common.client.dropdown.LiveSearchDropDown; import org.uberfire.ext.widgets.common.client.dropdown.SingleLiveSearchSelectionHandler; import static junit.framework.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DropDownEditorTest { @Mock DropDownEditor.View view; @Mock LiveSearchDropDown liveSearchDropDown; @Spy SingleLiveSearchSelectionHandler selectionHandler = new SingleLiveSearchSelectionHandler<>(); @Mock Event> valueChangeEvent; DropDownEditor presenter; Collection entries = new ArrayList<>(); @Before public void setup() { presenter = new DropDownEditor(view, liveSearchDropDown, valueChangeEvent); presenter.selectionHandler = selectionHandler; entries.add(presenter.newEntry("entry1", "Entry 1")); entries.add(presenter.newEntry("entry2", "Entry 2")); presenter.setEntries(entries); presenter.init(); } @Test public void testInit() { verify(liveSearchDropDown).setSearchEnabled(false); verify(liveSearchDropDown).init(any(), any()); assertNull(presenter.getValue()); } @Test public void testEntries() { presenter.getDropDownEntries("", -1, itemList -> { assertEquals(itemList.size(), 2); assertEquals(itemList.get(0).getKey(), "entry1"); assertEquals(itemList.get(1).getKey(), "entry2"); }); } @Test public void testSelect() { when(selectionHandler.getSelectedValue()).thenReturn("Entry 1"); presenter.setValue("entry2"); presenter.onEntrySelected(); ArgumentCaptor ac = ArgumentCaptor.forClass(ValueChangeEvent.class); verify(valueChangeEvent).fire(ac.capture()); assertEquals(presenter.getValue(), "entry1"); ValueChangeEvent event = ac.getValue(); assertEquals(event.getValue(), "entry1"); assertEquals(event.getOldValue(), "entry2"); } @Test public void testSetValue() { presenter.setValue("entry2"); verify(liveSearchDropDown).setSelectedItem("entry2"); assertEquals(presenter.getValue(), "entry2"); presenter.setSelectHint("- select - "); presenter.setValue(null); verify(liveSearchDropDown).setSelectedItem("- select - "); assertNull(presenter.getValue()); reset(liveSearchDropDown); presenter.clear(); presenter.setValue("entry2"); presenter.setEntries(entries); verify(liveSearchDropDown).setSelectedItem("entry2"); reset(liveSearchDropDown); presenter.clear(); presenter.setEntries(entries); verify(liveSearchDropDown, never()).setSelectedItem(anyString()); } @Test public void testClear() { presenter.setValue("entry2"); presenter.clear(); verify(liveSearchDropDown).clear();; assertNull(presenter.getValue()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/list/DropDownImageListEditorTest.java ================================================ package org.dashbuilder.common.client.editor.list; import org.dashbuilder.dataprovider.DataSetProviderType; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class DropDownImageListEditorTest extends ImageListEditorTest { @Before public void setup() { super.initExpectedValues(); // The presenter instance to test. view = mock(DropDownImageListEditor.View.class); presenter = new DropDownImageListEditor(view, valueChangeEvent); assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testClear() throws Exception { super.testClear(); } @Test public void testInit() throws Exception { super.testInit(); } @Test public void testNewEntry() throws Exception { super.testNewEntry(); } @Test public void testSetEntries() throws Exception { super.testSetEntries(); } @Test public void testClearErrors() throws Exception { super.testClearErrors(); } @Test public void testShowErrors() throws Exception { super.testShowErrors(); } @Test public void testAddHelpContent() throws Exception { super.testAddHelpContent(); } @Test public void testSetValueWithoutEvents() throws Exception { super.testSetValueWithoutEvents(); } @Test public void testSetValueWithEvents() throws Exception { super.testSetValueWithEvents(); } @Test public void testEditModeEnabled() throws Exception { presenter.setEntries(expectedEntries); ((DropDownImageListEditor)presenter).isEditMode(true); assertEquals(true, ((DropDownImageListEditor) presenter).isEditMode); verify( ((DropDownImageListEditor.View)view) , times(2)).setDropDown(true); } @Test public void testEditModeDisabled() throws Exception { presenter.setEntries(expectedEntries); ((DropDownImageListEditor)presenter).isEditMode(false); assertEquals(false, ((DropDownImageListEditor) presenter).isEditMode); verify( ((DropDownImageListEditor.View)view) , times(1)).setDropDown(false); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/list/HorizImageListEditorTest.java ================================================ package org.dashbuilder.common.client.editor.list; import org.dashbuilder.dataprovider.DataSetProviderType; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.mock; @RunWith(MockitoJUnitRunner.class) public class HorizImageListEditorTest extends ImageListEditorTest { @Before public void setup() { super.initExpectedValues(); // The presenter instance to test. view = mock( ImageListEditorView.class ); presenter = new HorizImageListEditor(view, valueChangeEvent); assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testClear() throws Exception { super.testClear(); } @Test public void testInit() throws Exception { super.testInit(); } @Test public void testNewEntry() throws Exception { super.testNewEntry(); } @Test public void testSetEntries() throws Exception { super.testSetEntries(); } @Test public void testClearErrors() throws Exception { super.testClearErrors(); } @Test public void testShowErrors() throws Exception { super.testShowErrors(); } @Test public void testAddHelpContent() throws Exception { super.testAddHelpContent(); } @Test public void testSetValueWithoutEvents() throws Exception { super.testSetValueWithoutEvents(); } @Test public void testSetValueWithEvents() throws Exception { super.testSetValueWithEvents(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/list/ImageListEditorTest.java ================================================ package org.dashbuilder.common.client.editor.list; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeUri; import org.dashbuilder.common.client.editor.AbstractEditorTest; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Assert; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; public abstract class ImageListEditorTest extends AbstractEditorTest { @Mock EventSourceMock> valueChangeEvent; protected final Collection expectedTypes = new ArrayList(3); protected final List.Entry> expectedEntries = new ArrayList.Entry>(4); protected ImageListEditor presenter; protected ImageListEditorView view; public void initExpectedValues() { // Currently expected provider types supported. expectedTypes.add(DataSetProviderType.BEAN); expectedTypes.add(DataSetProviderType.CSV); expectedTypes.add(DataSetProviderType.SQL); expectedEntries.addAll(mockEntries()); } public void testClear() throws Exception { presenter.entries.addAll(expectedEntries); presenter.value = DataSetProviderType.BEAN; presenter.clear(); assertTrue(presenter.entries.isEmpty()); assertNull(presenter.value); verify(view, times(1)).clear(); verify(view, times(0)).init(any(ImageListEditor.class)); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).add(any(SafeUri.class), anyString(), anyString(), any(SafeHtml.class), any(SafeHtml.class), anyBoolean(), any(Command.class)); } public void testInit() throws Exception { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(0)).clear(); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).add(any(SafeUri.class), anyString(), anyString(), any(SafeHtml.class), any(SafeHtml.class), anyBoolean(), any(Command.class)); } public void testNewEntry() throws Exception { ImageListEditor.Entry expectedEntry = mockEntry(DataSetProviderType.BEAN); ImageListEditor.Entry actualEntry = presenter.newEntry(expectedEntry.getValue(), expectedEntry.getUri(), expectedEntry.getHeading(), expectedEntry.getText()); Assert.assertEquals(expectedEntry.getHeading(), actualEntry.getHeading()); Assert.assertEquals(expectedEntry.getText(), actualEntry.getText()); Assert.assertEquals(expectedEntry.getUri(), actualEntry.getUri()); Assert.assertEquals(expectedEntry.getValue(), actualEntry.getValue()); } public void testSetEntries() throws Exception { presenter.setEntries(expectedEntries); assertShowElements(); } public void testClearErrors() throws Exception { List errors = new ArrayList(); presenter.showErrors(errors); verify(view, times(0)).clear(); verify(view, times(0)).init(any(ImageListEditor.class)); verify(view, times(1)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).add(any(SafeUri.class), anyString(), anyString(), any(SafeHtml.class), any(SafeHtml.class), anyBoolean(), any(Command.class)); } public void testShowErrors() throws Exception { EditorError e1 = mockEditorError(presenter, "m1"); EditorError e2 = mockEditorError(presenter, "m2"); List errors = new ArrayList(2); errors.add(e1); errors.add(e2); presenter.showErrors(errors); final ArgumentCaptor errorSafeHtmlCaptor = ArgumentCaptor.forClass(SafeHtml.class); verify(view, times(0)).clear(); verify(view, times(0)).init(any(ImageListEditor.class)); verify(view, times(0)).clearError(); verify(view, times(0)).add(any(SafeUri.class), anyString(), anyString(), any(SafeHtml.class), any(SafeHtml.class), anyBoolean(), any(Command.class)); verify(view, times(1)).showError(errorSafeHtmlCaptor.capture()); final SafeHtml value = errorSafeHtmlCaptor.getValue(); Assert.assertEquals("m1\nm2", value.asString()); } public void testAddHelpContent() throws Exception { final String title = "title"; final String content = "content"; final Placement p = Placement.BOTTOM; presenter.setHelpContent(title, content, p); verify(view, times(1)).setHelpContent(title, content, p); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).init(presenter); } public void testSetValueWithoutEvents() throws Exception { final DataSetProviderType value = DataSetProviderType.BEAN; presenter.entries.addAll(expectedEntries); presenter.setValue(value, false); Assert.assertEquals(value, presenter.value); assertShowElements(); } public void testSetValueWithEvents() throws Exception { final DataSetProviderType oldValue = DataSetProviderType.SQL; final DataSetProviderType newValue = DataSetProviderType.BEAN; presenter.value = oldValue; presenter.entries.addAll(expectedEntries); presenter.setValue(newValue, true); Assert.assertEquals(newValue, presenter.value); assertShowElements(); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); } protected void assertShowElements() { verify(view, times(0)).init(any(ImageListEditor.class)); verify(view, times(0)).clearError(); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(1)).clear(); verify(view, times(3)).add(any(SafeUri.class), anyString(), anyString(), any(SafeHtml.class), any(SafeHtml.class), anyBoolean(), any(Command.class)); Assert.assertEquals(expectedEntries, presenter.entries); } protected List.Entry> mockEntries() { List.Entry> result = new ArrayList.Entry>(4); result.add(mockEntry(DataSetProviderType.BEAN)); result.add(mockEntry(DataSetProviderType.CSV)); result.add(mockEntry(DataSetProviderType.SQL)); return result; } protected static ImageListEditor.Entry mockEntry(DataSetProviderType type) { final String name = type.getName(); final SafeUri uri = mock(SafeUri.class); final SafeHtml safeHtml = mock(SafeHtml.class); ImageListEditor.Entry entry = mock(ImageListEditor.Entry.class); doReturn(type).when(entry).getValue(); doReturn(safeHtml).when(entry).getHeading(); doReturn(safeHtml).when(entry).getText(); doReturn(uri).when(entry).getUri(); return entry; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/editor/map/MapEditorTest.java ================================================ package org.dashbuilder.common.client.editor.map; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.AbstractEditorTest; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class MapEditorTest extends AbstractEditorTest { @Mock MapEditor.View view; @Mock EventSourceMock>> valueChangeEvent; private MapEditor presenter; @Before public void setup() { // The presenter instance to test. presenter = new MapEditor(view, valueChangeEvent); assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testInit() throws Exception { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).setAddText(anyString()); verify(view, times(1)).setEmptyText(anyString()); verify(view, times(1)).addButtonColumn(anyInt(), anyString(), anyInt()); verify(view, times(2)).addTextColumn(anyInt(), anyString(), anyBoolean(), anyInt()); verify(view, times(0)).clearError(); verify(view, times(0)).removeColumn(anyInt()); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).setData(anyList()); verify(view, times(0)).setRowCount(anyInt()); } @Test public void testClearErrors() throws Exception { List errors = new ArrayList(); presenter.showErrors(errors); verify(view, times(1)).clearError(); verify(view, times(0)).init(presenter); verify(view, times(0)).setAddText(anyString()); verify(view, times(0)).setEmptyText(anyString()); verify(view, times(0)).addButtonColumn(anyInt(), anyString(), anyInt()); verify(view, times(0)).addTextColumn(anyInt(), anyString(), anyBoolean(), anyInt()); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).setData(anyList()); verify(view, times(0)).setRowCount(anyInt()); verify(view, times(0)).removeColumn(anyInt()); } @Test public void testShowErrors() throws Exception { EditorError e1 = mockEditorError(presenter, "m1"); EditorError e2 = mockEditorError(presenter, "m2"); List errors = new ArrayList(2); errors.add(e1); errors.add(e2); presenter.showErrors(errors); final ArgumentCaptor errorSafeHtmlCaptor = ArgumentCaptor.forClass(SafeHtml.class); verify(view, times(1)).showError(errorSafeHtmlCaptor.capture()); verify(view, times(0)).clearError(); verify(view, times(0)).init(presenter); verify(view, times(0)).setAddText(anyString()); verify(view, times(0)).setEmptyText(anyString()); verify(view, times(0)).addButtonColumn(anyInt(), anyString(), anyInt()); verify(view, times(0)).addTextColumn(anyInt(), anyString(), anyBoolean(), anyInt()); verify(view, times(0)).setData(anyList()); verify(view, times(0)).setRowCount(anyInt()); verify(view, times(0)).removeColumn(anyInt()); final SafeHtml value = errorSafeHtmlCaptor.getValue(); Assert.assertEquals("m1\nm2", value.asString()); } @Test public void testValue() throws Exception { final Map value = new HashMap(1); value.put("key1", "value1"); presenter.setValue(value); assertEquals(value, presenter.getValue()); assertSetViewValue(1); } @Test public void testUpdateKey() throws Exception { final Map value = new HashMap(1); value.put("key1", "value1"); presenter.value = value; Map.Entry entry = mock(Map.Entry.class); when(entry.getKey()).thenReturn("key1"); presenter.update(0, 0, entry, "key2"); assertEquals(1, presenter.getValue().size()); assertEquals("value1", presenter.getValue().get("key2")); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); assertSetViewValue(1); } @Test public void testUpdateValue() throws Exception { final Map value = new HashMap(1); value.put("key1", "value1"); presenter.value = value; Map.Entry entry = mock(Map.Entry.class); when(entry.getKey()).thenReturn("key1"); when(entry.getValue()).thenReturn("value1"); presenter.update(1, 0, entry, "value2"); assertEquals(1, presenter.getValue().size()); assertEquals("value2", presenter.getValue().get("key1")); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); assertSetViewValue(1); } @Test public void testRemoveEntry() throws Exception { final Map value = new HashMap(1); value.put("key1", "value1"); presenter.value = value; Map.Entry entry = mock(Map.Entry.class); when(entry.getKey()).thenReturn("key1"); presenter.update(2, 0, entry, null); assertEquals(0, presenter.getValue().size()); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); assertSetViewValue(0); } @Test public void testAddEntry() throws Exception { presenter.addEntry(); assertEquals(1, presenter.getValue().size()); verify( valueChangeEvent, times( 1 ) ).fire(any(ValueChangeEvent.class)); assertSetViewValue(1); } protected void assertSetViewValue(final int size) { verify(view, times(3)).removeColumn(0); verify(view, times(1)).clearError(); verify(view, times(1)).addButtonColumn(anyInt(), anyString(), anyInt()); verify(view, times(2)).addTextColumn(anyInt(), anyString(), anyBoolean(), anyInt()); verify(view, times(1)).setEmptyText(anyString()); verify(view, times(1)).setRowCount(size); final ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(List.class); verify(view, times(1)).setData(dataCaptor.capture()); final List dataValue = dataCaptor.getValue(); assertNotNull(dataValue); assertEquals(size, dataValue.size()); verify(view, times(0)).init(presenter); verify(view, times(0)).showError(any(SafeHtml.class)); verify(view, times(0)).setAddText(anyString()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-common-client/src/test/java/org/dashbuilder/common/client/widgets/FilterLabelSetTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.common.client.widgets; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class FilterLabelSetTest { @Mock FilterLabelSet.View view; @Mock FilterLabel filterLabel; @Mock SyncBeanDef filterLabelBean; @Mock SyncBeanManager beanManager; FilterLabelSet presenter; @Before public void setUp() { when(beanManager.lookupBean(FilterLabel.class)).thenReturn(filterLabelBean); when(filterLabelBean.newInstance()).thenReturn(filterLabel); presenter = new FilterLabelSet(view, beanManager); } @Test public void testClearAll() { presenter.clear(); verify(view, never()).setClearAllEnabled(true); verify(view, never()).addLabel(any()); presenter.addLabel("a"); verify(view, never()).setClearAllEnabled(true); verify(view, times(1)).addLabel(any()); presenter.addLabel("b"); verify(view).setClearAllEnabled(true); verify(view, times(2)).addLabel(any()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-dataset-client jar Dashbuilder Dataset Client org.jboss.errai errai-common org.jboss.errai errai-bus org.jboss.errai errai-ioc org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-api org.uberfire uberfire-client-all com.google.gwt gwt-user provided org.dashbuilder dashbuilder-services-api org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-dataset-shared org.dashbuilder dashbuilder-common-client javax.validation validation-api provided org.jboss.errai errai-validation com.google.gwt.gwtmockito gwtmockito test org.uberfire uberfire-testing-utils test org.kie.soup kie-soup-dataset-api test-jar test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/ClientDataSetCore.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import org.dashbuilder.dataset.DataSetManager; import org.dashbuilder.dataset.AbstractDataSetCore; import org.dashbuilder.dataset.client.engine.ClientChronometer; import org.dashbuilder.dataset.client.engine.ClientDateFormatter; import org.dashbuilder.dataset.client.engine.ClientDateFormatterImpl; import org.dashbuilder.dataset.client.engine.ClientIntervalBuilderDynamicDate; import org.dashbuilder.dataset.client.engine.ClientIntervalBuilderLocator; import org.dashbuilder.dataset.client.uuid.ClientUUIDGenerator; import org.dashbuilder.dataset.engine.Chronometer; import org.dashbuilder.dataset.engine.group.IntervalBuilderLocator; import org.dashbuilder.dataset.uuid.UUIDGenerator; public class ClientDataSetCore extends AbstractDataSetCore { private static ClientDataSetCore _instance = null; public static ClientDataSetCore get() { if (_instance == null) { _instance = new ClientDataSetCore(); } return _instance; } private ClientDataSetManager clientDataSetManager; private ClientIntervalBuilderLocator clientIntervalBuilderLocator; private ClientChronometer clientChronometer; private ClientUUIDGenerator clientUUIDGenerator; private ClientIntervalBuilderDynamicDate clientIntervalBuilderDynamicDate; private ClientDateFormatter clientDateFormatter; // Getters public ClientDataSetManager getClientDataSetManager() { if (clientDataSetManager == null) { clientDataSetManager = new ClientDataSetManager(); } return clientDataSetManager; } public ClientIntervalBuilderLocator getClientIntervalBuilderLocator() { if (clientIntervalBuilderLocator == null) { clientIntervalBuilderLocator = new ClientIntervalBuilderLocator( checkNotNull(getIntervalBuilderDynamicLabel(), "IntervalBuilderDynamicLabel"), checkNotNull(getClientIntervalBuilderDynamicDate(), "ClientIntervalBuilderDynamicDate"), checkNotNull(getIntervalBuilderFixedDate(), "IntervalBuilderFixedDate")); } return clientIntervalBuilderLocator; } public ClientIntervalBuilderDynamicDate getClientIntervalBuilderDynamicDate() { if (clientIntervalBuilderDynamicDate == null) { clientIntervalBuilderDynamicDate = new ClientIntervalBuilderDynamicDate( checkNotNull(getClientDateFormatter(), "ClientDateFormatter") ); } return clientIntervalBuilderDynamicDate; } public ClientDateFormatter getClientDateFormatter() { if (clientDateFormatter == null) { clientDateFormatter = new ClientDateFormatterImpl(); } return clientDateFormatter; } public ClientChronometer getClientChronometer() { if (clientChronometer == null) { clientChronometer = new ClientChronometer(); } return clientChronometer; } public ClientUUIDGenerator getClientUUIDGenerator() { if (clientUUIDGenerator == null) { clientUUIDGenerator = new ClientUUIDGenerator(); } return clientUUIDGenerator; } // Setters public void setClientDataSetManager(ClientDataSetManager clientDataSetManager) { this.clientDataSetManager = clientDataSetManager; } public void setClientIntervalBuilderLocator(ClientIntervalBuilderLocator clientIntervalBuilderLocator) { this.clientIntervalBuilderLocator = clientIntervalBuilderLocator; } public void setClientIntervalBuilderDynamicDate(ClientIntervalBuilderDynamicDate clientIntervalBuilderDynamicDate) { this.clientIntervalBuilderDynamicDate = clientIntervalBuilderDynamicDate; } public void setClientDateFormatter(ClientDateFormatter clientDateFormatter) { this.clientDateFormatter = clientDateFormatter; } public void setClientChronometer(ClientChronometer clientChronometer) { this.clientChronometer = clientChronometer; } public void setClientUUIDGenerator(ClientUUIDGenerator clientUUIDGenerator) { this.clientUUIDGenerator = clientUUIDGenerator; } // Factory methods @Override public DataSetManager newDataSetManager() { return getClientDataSetManager(); } @Override public IntervalBuilderLocator newIntervalBuilderLocator() { return getClientIntervalBuilderLocator(); } @Override public Chronometer newChronometer() { return getClientChronometer(); } @Override public UUIDGenerator newUuidGenerator() { return getClientUUIDGenerator(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/ClientDataSetManager.java ================================================ /** /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetManager; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.dataset.def.DataSetPreprocessor; import org.dashbuilder.dataset.engine.SharedDataSetOpEngine; import org.dashbuilder.dataset.engine.index.DataSetIndex; /** * Client implementation of a DataSetManager. It hold as map of data sets in memory. * It is designed to manipulate not quite big data sets. For big data sets the backend implementation is better, */ @ApplicationScoped public class ClientDataSetManager implements DataSetManager { SharedDataSetOpEngine dataSetOpEngine; Map> preprocessorMap = new HashMap>(); public ClientDataSetManager() { this.dataSetOpEngine = ClientDataSetCore.get().getSharedDataSetOpEngine(); } @Override public DataSet createDataSet(String uuid) { DataSet dataSet = DataSetFactory.newEmptyDataSet(); dataSet.setUUID(uuid); return dataSet; } @Override public DataSet getDataSet(String uuid) { DataSetIndex index = dataSetOpEngine.getIndexRegistry().get(uuid); if (index == null) { return null; } return index.getDataSet(); } @Override public void registerDataSet(DataSet dataSet) { if (dataSet != null) { dataSetOpEngine.getIndexRegistry().put(dataSet); } } @Override public void registerDataSet(DataSet dataSet, List preprocessors) { if (dataSet != null) { dataSetOpEngine.getIndexRegistry().put(dataSet); for (DataSetPreprocessor preprocessor : preprocessors) { registerDataSetPreprocessor(dataSet.getUUID(), preprocessor); } } } @Override public DataSet removeDataSet(String uuid) { DataSetIndex index = dataSetOpEngine.getIndexRegistry().remove(uuid); if (index == null) { return null; } return index.getDataSet(); } @Override public DataSet lookupDataSet(DataSetLookup lookup) { String uuid = lookup.getDataSetUUID(); if (StringUtils.isEmpty(uuid)) { return null; } // Get the target data set DataSetIndex dataSetIndex = dataSetOpEngine.getIndexRegistry().get(uuid); if (dataSetIndex == null) { return null; } List dataSetDefPreProcessors = getDataSetPreprocessors(uuid); if (dataSetDefPreProcessors != null) { for(DataSetPreprocessor p : dataSetDefPreProcessors){ p.preprocess(lookup); } } DataSet dataSet = dataSetIndex.getDataSet(); // Apply the list of operations specified (if any). if (!lookup.getOperationList().isEmpty()) { dataSet = dataSetOpEngine.execute(uuid, lookup.getOperationList()); } // Trim the data set as requested. dataSet = dataSet.trim(lookup.getRowOffset(), lookup.getNumberOfRows()); return dataSet; } @Override public DataSet[] lookupDataSets(DataSetLookup[] lookup) { DataSet[] result = new DataSet[lookup.length]; for (int i = 0; i < lookup.length; i++) { result[i] = lookupDataSet(lookup[i]); } return result; } @Override public DataSetMetadata getDataSetMetadata(String uuid) { DataSetLookup lookup = new DataSetLookup(uuid); DataSet dataSet = lookupDataSet(lookup); if (dataSet == null) { return null; } return dataSet.getMetadata(); } public void registerDataSetPreprocessor(String uuid, DataSetPreprocessor preprocessor) { List preprocessors = preprocessorMap.get(uuid); if (preprocessors == null) { preprocessorMap.put(uuid, preprocessors = new ArrayList()); } preprocessors.add(preprocessor); } public List getDataSetPreprocessors(String uuid) { return preprocessorMap.get(uuid); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/DataSetClientServices.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.common.client.backend.PathUrlFactory; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.client.resources.i18n.CommonConstants; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.engine.group.IntervalBuilderLocator; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.events.DataSetModifiedEvent; import org.dashbuilder.dataset.events.DataSetPushOkEvent; import org.dashbuilder.dataset.events.DataSetPushingEvent; import org.dashbuilder.dataset.events.DataSetStaleEvent; import org.dashbuilder.dataset.group.AggregateFunctionManager; import org.dashbuilder.dataset.service.DataSetDefServices; import org.dashbuilder.dataset.service.DataSetExportServices; import org.dashbuilder.dataset.service.DataSetLookupServices; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.ErrorCallback; import org.jboss.errai.common.client.api.RemoteCallback; import org.uberfire.backend.vfs.Path; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * Data set services for clients. *

It hides to client widgets where the data sets are stored and how they are fetched and processed.

*/ @ApplicationScoped public class DataSetClientServices { private ClientDataSetManager clientDataSetManager; private PathUrlFactory pathUrlFactory; private AggregateFunctionManager aggregateFunctionManager; private IntervalBuilderLocator intervalBuilderLocator; private Event dataSetPushingEvent; private Event dataSetPushOkEvent; private Event dataSetModifiedEvent; private Caller dataSetLookupServices; private Caller dataSetDefServices; private Caller dataSetExportServices; /** * A cache of DataSetMetadata instances */ private Map remoteMetadataMap = new HashMap(); /** * If enabled then remote data set can be pushed to clients. */ private boolean pushRemoteDataSetEnabled = true; /** * It holds a set of data set push requests in progress. */ private Map pushRequestMap = new HashMap(); public DataSetClientServices() { } @Inject public DataSetClientServices(ClientDataSetManager clientDataSetManager, PathUrlFactory pathUrlFactory, AggregateFunctionManager aggregateFunctionManager, IntervalBuilderLocator intervalBuilderLocator, Event dataSetPushingEvent, Event dataSetPushOkEvent, Event dataSetModifiedEvent, Caller dataSetLookupServices, Caller dataSetDefServices, Caller dataSetExportServices) { this.clientDataSetManager = clientDataSetManager; this.pathUrlFactory = pathUrlFactory; this.aggregateFunctionManager = aggregateFunctionManager; this.intervalBuilderLocator = intervalBuilderLocator; this.dataSetPushingEvent = dataSetPushingEvent; this.dataSetPushOkEvent = dataSetPushOkEvent; this.dataSetModifiedEvent = dataSetModifiedEvent; this.dataSetLookupServices = dataSetLookupServices; this.dataSetDefServices = dataSetDefServices; this.dataSetExportServices = dataSetExportServices; } public boolean isPushRemoteDataSetEnabled() { return pushRemoteDataSetEnabled; } /** * Enable/disable the ability to push remote data sets from server. */ public void setPushRemoteDataSetEnabled(boolean pushRemoteDataSetEnabled) { this.pushRemoteDataSetEnabled = pushRemoteDataSetEnabled; } /** * Fetch the metadata instance for the specified data set. * * @param uuid The UUID of the data set * @throws Exception It there is an unexpected error trying to execute the lookup request. */ public void fetchMetadata(final String uuid, final DataSetMetadataCallback listener) throws Exception { final DataSetMetadata metadata = clientDataSetManager.getDataSetMetadata(uuid); if (metadata != null) { listener.callback(metadata); } else if (dataSetLookupServices != null) { if (remoteMetadataMap.containsKey(uuid)) { listener.callback(remoteMetadataMap.get(uuid)); } else { dataSetLookupServices.call((DataSetMetadata result) -> { if (result == null) { listener.notFound(); } else { remoteMetadataMap.put(uuid, result); listener.callback(result); } }, (message, throwable) -> { return listener.onError(new ClientRuntimeError(throwable)); }).lookupDataSetMetadata(uuid); } } else { listener.notFound(); } } Map getRemoteMetadataMap() { return remoteMetadataMap; } /** * Get the cached metadata instance for the specified data set. * * @param uuid The UUID of the data set. Null if the metadata is not stored on client yet. */ public DataSetMetadata getMetadata(String uuid) { DataSetMetadata metadata = clientDataSetManager.getDataSetMetadata(uuid); if (metadata != null) { return metadata; } return remoteMetadataMap.get(uuid); } /** * Export a data set, specified by a data set lookup request, to CSV format. * * @param request The data set lookup request * @throws Exception It there is an unexpected error during the export. */ public void exportDataSetCSV(final DataSetLookup request, final DataSetExportReadyCallback listener) throws Exception { if (dataSetLookupServices != null) { // Look always into the client data set manager. if (clientDataSetManager.getDataSet(request.getDataSetUUID()) != null) { DataSet dataSet = clientDataSetManager.lookupDataSet(request); dataSetExportServices.call( new RemoteCallback() { public void callback(Path csvFilePath) { listener.exportReady(csvFilePath); } } , new ErrorCallback() { public boolean error(Message message, Throwable throwable) { listener.onError(new ClientRuntimeError(throwable)); return true; } }).exportDataSetCSV(dataSet); } // Data set not found on client. else { // If the data set is not in client, then look up remotely (only if the remote access is available). try { dataSetExportServices.call( new RemoteCallback() { public void callback(Path csvFilePath) { listener.exportReady(csvFilePath); } } , new ErrorCallback() { public boolean error(Message message, Throwable throwable) { listener.onError(new ClientRuntimeError(throwable)); return true; } }).exportDataSetCSV(request); } catch (Exception e) { listener.onError(new ClientRuntimeError(e)); } } } else { listener.onError(new ClientRuntimeError(CommonConstants.INSTANCE.exc_no_client_side_data_export())); } } /** * Export a data set, specified by a data set lookup request, to Excel format. * * @param request The data set lookup request * @throws Exception It there is an unexpected error during the export. */ public void exportDataSetExcel(final DataSetLookup request, final DataSetExportReadyCallback listener) throws Exception { if (dataSetLookupServices != null) { // Look always into the client data set manager. if (clientDataSetManager.getDataSet(request.getDataSetUUID()) != null) { DataSet dataSet = clientDataSetManager.lookupDataSet(request); try { dataSetExportServices.call( new RemoteCallback() { public void callback(Path excelFilePath) { listener.exportReady(excelFilePath); } }).exportDataSetExcel(dataSet); } catch (Exception e) { throw new RuntimeException(e); } } // Data set not found on client. else { // If the data set is not in client, then look up remotely (only if the remote access is available). try { dataSetExportServices.call( new RemoteCallback() { public void callback(Path excelFilePath) { listener.exportReady(excelFilePath); } } , new ErrorCallback() { public boolean error(Message message, Throwable throwable) { listener.onError(new ClientRuntimeError(throwable)); return true; } }).exportDataSetExcel(request); } catch (Exception e) { listener.onError(new ClientRuntimeError(e)); } } } else { listener.onError(new ClientRuntimeError(CommonConstants.INSTANCE.exc_no_client_side_data_export())); } } /** * Creates a brand new data set definition for the provider type specified * * @param type The provider type * @return A data set definition instance */ public void newDataSet(DataSetProviderType type, RemoteCallback callback) throws Exception { dataSetDefServices.call(callback).createDataSetDef(type); } /** * Process the specified data set lookup request for a given definition. * * @param def The data set definition * @param request The data set lookup request * @throws Exception It there is an unexpected error trying to execute the lookup request. */ public void lookupDataSet(final DataSetDef def, final DataSetLookup request, final DataSetReadyCallback listener) throws Exception { if (dataSetLookupServices != null) { try { dataSetLookupServices.call( new RemoteCallback() { public void callback(DataSet result) { if (result == null) { listener.notFound(); } else { listener.callback(result); } } }, new ErrorCallback() { @Override public boolean error(Message message, Throwable throwable) { return listener.onError(new ClientRuntimeError(throwable)); } }) .lookupDataSet(def, request); } catch (Exception e) { listener.onError(new ClientRuntimeError(e)); } } // Data set not found on client. else { listener.notFound(); } } /** * Process the specified data set lookup request. * * @param request The data set lookup request * @throws Exception It there is an unexpected error trying to execute the lookup request. */ public void lookupDataSet(final DataSetLookup request, final DataSetReadyCallback listener) throws Exception { // Look always into the client data set manager. if (clientDataSetManager.getDataSet(request.getDataSetUUID()) != null) { DataSet dataSet = clientDataSetManager.lookupDataSet(request); listener.callback(dataSet); } // If the data set is not in client, then look up remotely (only if the remote access is available). else if (dataSetLookupServices != null) { // First of all, get the target data set estimated size. fetchMetadata(request.getDataSetUUID(), new DataSetMetadataCallback() { public void callback(DataSetMetadata metatada) { // Push the data set to client if and only if the push feature is enabled, the data set is // pushable & the data set is smaller than the max push size defined. DataSetDef dsetDef = metatada.getDefinition(); int estimatedSize = metatada.getEstimatedSize() / 1000; boolean isPushable = dsetDef != null && dsetDef.isPushEnabled() && estimatedSize < dsetDef.getPushMaxSize(); if (pushRemoteDataSetEnabled && isPushable) { // Check if a push is already in progress. // (This is necessary in order to avoid repeating multiple push requests over the same data set). DataSetPushHandler pushHandler = pushRequestMap.get(request.getDataSetUUID()); if (pushHandler == null) { // Create a push handler. pushHandler = new DataSetPushHandler(metatada); // Send the lookup request to the server... DataSetLookup lookupSourceDataSet = new DataSetLookup(request.getDataSetUUID()); _lookupDataSet(lookupSourceDataSet, pushHandler); } // Register the lookup request into the current handler. pushHandler.registerLookup(request, listener); } // Lookup the remote data set otherwise. else { _lookupDataSet(request, listener); } } // Data set metadata not found public void notFound() { listener.notFound(); } @Override public boolean onError(final ClientRuntimeError error) { return listener.onError(error); } }); } // Data set not found on client. else { listener.notFound(); } } private void _lookupDataSet(DataSetLookup request, final DataSetReadyCallback listener) { try { dataSetLookupServices.call( new RemoteCallback() { public void callback(DataSet result) { if (result == null) { listener.notFound(); } else { listener.callback(result); } } }, new ErrorCallback() { @Override public boolean error(Message message, Throwable throwable) { return listener.onError(new ClientRuntimeError(throwable)); } }) .lookupDataSet(request); } catch (Exception e) { listener.onError(new ClientRuntimeError(e)); } } /** * @since 0.3.0.Final * @deprecated Use getPublicDataSetDefs instead */ public void getRemoteSharedDataSetDefs(RemoteCallback> callback) { getPublicDataSetDefs(callback); } public void getPublicDataSetDefs(RemoteCallback> callback) { try { dataSetDefServices.call(callback).getPublicDataSetDefs(); } catch (Exception e) { throw new RuntimeException(e); } } public AggregateFunctionManager getAggregateFunctionManager() { return aggregateFunctionManager; } public IntervalBuilderLocator getIntervalBuilderLocator() { return intervalBuilderLocator; } // Classes for the handling of concurrent lookup requests over any push-able data set private void onDataSetStaleEvent(@Observes DataSetStaleEvent event) { checkNotNull("event", event); String uuid = event.getDataSetDef().getUUID(); // Remove any stale data existing on the client. // This will force next lookup requests to push a refreshed data set. clientDataSetManager.removeDataSet(uuid); remoteMetadataMap.remove(uuid); // If a data set has been updated on the sever then fire an event. // In this case the notification is always send, no matter whether the data set is pushed to the client or not. dataSetModifiedEvent.fire(new DataSetModifiedEvent(event.getDataSetDef())); } private void onDataSetRemovedEvent(@Observes DataSetDefRemovedEvent event) { checkNotNull("event", event); String uuid = event.getDataSetDef().getUUID(); clientDataSetManager.removeDataSet(uuid); remoteMetadataMap.remove(uuid); // If a data set has been updated on the sever then fire an event. // In this case the notification is always send, no matter whether the data set is pushed to the client or not. dataSetModifiedEvent.fire(new DataSetModifiedEvent(event.getDataSetDef())); } // Catch backend events /** *

Returns the download URL for a given file provided by a servlet method.

* * @param path The path of the file. */ public String getDownloadFileUrl(final Path path) { return pathUrlFactory.getDownloadFileUrl(path); } /** *

Returns the upload URL for a given file provided by a servlet method.

* * @param path The path of the file. */ public String getUploadFileUrl(String path) { return pathUrlFactory.getUploadFileUrl(path); } private class DataSetPushHandler implements DataSetReadyCallback { private DataSetMetadata dataSetMetadata = null; private List listenerList = new ArrayList(); private DataSetPushHandler(DataSetMetadata metadata) { this.dataSetMetadata = metadata; pushRequestMap.put(dataSetMetadata.getUUID(), this); dataSetPushingEvent.fire(new DataSetPushingEvent(dataSetMetadata)); } public void registerLookup(DataSetLookup lookup, DataSetReadyCallback listener) { listenerList.add(new DataSetLookupListenerPair(lookup, listener)); } public void callback(DataSet dataSet) { pushRequestMap.remove(dataSetMetadata.getUUID()); clientDataSetManager.registerDataSet(dataSet); dataSetPushOkEvent.fire(new DataSetPushOkEvent(dataSetMetadata)); for (DataSetLookupListenerPair pair : listenerList) { DataSet result = clientDataSetManager.lookupDataSet(pair.lookup); pair.listener.callback(result); } } public void notFound() { pushRequestMap.remove(dataSetMetadata.getUUID()); for (DataSetLookupListenerPair pair : listenerList) { pair.listener.notFound(); } } @Override public boolean onError(final ClientRuntimeError error) { boolean t = false; for (DataSetLookupListenerPair pair : listenerList) { if (pair.listener.onError(error)) { t = true; } } return t; } } private class DataSetLookupListenerPair { DataSetLookup lookup; DataSetReadyCallback listener; private DataSetLookupListenerPair(DataSetLookup lookup, DataSetReadyCallback listener) { this.lookup = lookup; this.listener = listener; } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/DataSetExportReadyCallback.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.uberfire.backend.vfs.Path; /** * Interface for capturing the results of a data set export request */ public interface DataSetExportReadyCallback { /** * The path returned after a successful export * @param exportFilePath The path of the exported file in the server */ void exportReady(Path exportFilePath); /** * An error occurred during the export process * @param error The error details */ void onError(ClientRuntimeError error); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/DataSetMetadataCallback.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSetMetadata; /** * DataSetMetadata retrieval callback */ public interface DataSetMetadataCallback { void callback(DataSetMetadata metatada); void notFound(); boolean onError(ClientRuntimeError error); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/DataSetReadyCallback.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSet; /** * DataSet retrieval callback */ public interface DataSetReadyCallback { void callback(DataSet dataSet); void notFound(); boolean onError(ClientRuntimeError error); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/BeanDataSetDefAttributesEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.Editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.BeanDataSetDef; import java.util.Map; /** *

The GWT editor contract for the specific attributes of type org.dashbuilder.dataset.def.BeanDataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • generatorClass
  • *
  • paramaterMap
  • *
* * @since 0.4.0 */ public interface BeanDataSetDefAttributesEditor extends Editor { LeafAttributeEditor generatorClass(); LeafAttributeEditor> paramaterMap(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/BeanDataSetDefEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.BeanDataSetDef; import java.util.Map; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.BeanDataSetDef.

* * TODO * The attributes generatorClass and paramaterMap should be not directly referenced here, here should be referenced just the org.dashbuilder.dataset.client.editor.BeanDataSetDefAttributesEditor. * But gwt editor inheritance is not working in this situation, due to https://github.com/gwtproject/gwt/issues/6340 * Please refactor it when bug from gwt is fixed. * * @since 0.4.0 */ public interface BeanDataSetDefEditor extends DataSetDefEditor { LeafAttributeEditor generatorClass(); LeafAttributeEditor> paramaterMap(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/CSVDataSetDefAttributesEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.CSVDataSetDef; /** *

The GWT editor contract for the specific attributes of type org.dashbuilder.dataset.def.CSVDataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • fileURL
  • *
  • filePath
  • *
  • separatorChar
  • *
  • quoteChar
  • *
  • escapeChar
  • *
  • datePattern
  • *
  • numberPattern
  • *
*

It is a ValueAwareEditor as must nullify filePath or fileURL editors at runtime depending on the instance value.

* * @since 0.4.0 */ public interface CSVDataSetDefAttributesEditor extends ValueAwareEditor { LeafAttributeEditor fileURL(); LeafAttributeEditor filePath(); LeafAttributeEditor separatorChar(); LeafAttributeEditor quoteChar(); LeafAttributeEditor escapeChar(); LeafAttributeEditor datePattern(); LeafAttributeEditor numberPattern(); @Ignore boolean isUsingFilePath(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/CSVDataSetDefEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.CSVDataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.CSVDataSetDef.

* * TODO * All csv specific attributes should be not directly referenced here, here should be referenced just the org.dashbuilder.dataset.client.editor.BeanDataSetDefAttributesEditor. * But gwt editor inheritance is not working in this situation, due to https://github.com/gwtproject/gwt/issues/6340 * Please refactor it when bug from gwt is fixed. * * @since 0.4.0 */ public interface CSVDataSetDefEditor extends DataSetDefEditor { LeafAttributeEditor fileURL(); LeafAttributeEditor filePath(); LeafAttributeEditor separatorChar(); LeafAttributeEditor quoteChar(); LeafAttributeEditor escapeChar(); LeafAttributeEditor datePattern(); LeafAttributeEditor numberPattern(); @Ignore boolean isUsingFilePath(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/ColumnListEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.CompositeEditor; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.HasEditorErrors; import org.dashbuilder.common.client.editor.HasConstrainedValue; import org.dashbuilder.common.client.editor.HasEditMode; import org.dashbuilder.common.client.editor.HasRestrictedValue; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataColumnDef; import java.util.List; /** *

The GWT editor contract for a collection of the data set definition columns, which type is org.dashbuilder.dataset.def.DataColumnDef.

* * @since 0.4.0 */ public interface ColumnListEditor extends CompositeEditor, DataColumnDef, DataColumnDefEditor>, HasEditorErrors>, HasConstrainedValue>, HasRestrictedValue { /** * Columns edition constrains are different depending on the data set's provider type. * * @param type The data set's provider type. */ @Editor.Ignore void setProviderType(DataSetProviderType type); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/ColumnTypeEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.HasEditMode; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.def.DataColumnDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.ColumnType of a given data column definition.

* *

It's a value aware editor as the available column types to change depend on the current column type value.

* @since 0.4.0 */ public interface ColumnTypeEditor extends ValueAwareEditor, HasEditMode { /** * Column editor requires the original column type in oder to allow changing column types to the types given by the original data set column type. * @param columnType The original data set column type */ @Editor.Ignore void setOriginalColumnType(ColumnType columnType); LeafAttributeEditor columnType(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataColumnDefEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.Editor; import org.dashbuilder.common.client.editor.HasEditMode; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.def.DataColumnDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataColumnDef.

* * @since 0.4.0 */ public interface DataColumnDefEditor extends Editor, HasEditMode { /** * Columns edition constrains are different depending on the data set's provider type. * * @param type The data set's provider type. */ @Editor.Ignore void setProviderType(DataSetProviderType type); /** * Column editor requires the original column type in oder to allow changing column types to the types given by the original data set column type. * @param columnType The original data set column type */ @Editor.Ignore void setOriginalColumnType(ColumnType columnType); /** *

Called when editor is detached from the editors chain. Remove view from parent element here.

*/ @Editor.Ignore void removeFromParent(); LeafAttributeEditor id(); @Editor.Path(".") ColumnTypeEditor columnType(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefBackendCacheAttributesEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.DataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • cacheEnabled
  • *
  • cacheMaxRows
  • *
* * @since 0.4.0 */ public interface DataSetDefBackendCacheAttributesEditor extends ValueAwareEditor { LeafAttributeEditor cacheEnabled(); LeafAttributeEditor cacheMaxRows(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefBasicAttributesEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.Editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.DataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • uuid
  • *
  • name
  • *
* * @since 0.4.0 */ public interface DataSetDefBasicAttributesEditor extends Editor { LeafAttributeEditor UUID(); LeafAttributeEditor name(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefClientCacheAttributesEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.DataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • pushEnabled
  • *
  • pushMaxSize
  • *
* * @since 0.4.0 */ public interface DataSetDefClientCacheAttributesEditor extends ValueAwareEditor { LeafAttributeEditor pushEnabled(); LeafAttributeEditor pushMaxSize(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefColumnsEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.HasConstrainedValue; import org.dashbuilder.common.client.editor.HasRestrictedValue; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import java.util.List; /** *

The GWT editor contract for the data set definition columns.

*

It takes care about the allColumnsEnabled flag.

* * @since 0.4.0 */ public interface DataSetDefColumnsEditor extends ValueAwareEditor, HasConstrainedValue>, HasRestrictedValue { ColumnListEditor columns(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefColumnsFilterEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.HasConstrainedValue; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import java.util.List; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • data set columns
  • *
  • data set filter
  • *
* * @since 0.4.0 */ public interface DataSetDefColumnsFilterEditor extends ValueAwareEditor, HasConstrainedValue> { @Editor.Path(".") DataSetDefColumnsEditor columnListEditor(); DataSetDefFilterEditor dataSetFilter(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.HasConstrainedValue; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import java.util.List; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataSetDef.

*

It delegates to sub-editors the different attributes edition:

* * @since 0.4.0 */ public interface DataSetDefEditor extends ValueAwareEditor, HasConstrainedValue> { @Editor.Path(".") DataSetDefBasicAttributesEditor basicAttributesEditor(); @Editor.Path(".") DataSetDefColumnsFilterEditor columnsAndFilterEditor(); @Editor.Path(".") DataSetDefBackendCacheAttributesEditor backendCacheEditor(); @Editor.Path(".") DataSetDefClientCacheAttributesEditor clientCacheEditor(); @Editor.Path(".") DataSetDefRefreshAttributesEditor refreshEditor(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefFilterEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.filter.DataSetFilter; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.filter.DataSetFilter.

* * @since 0.4.0 */ public interface DataSetDefFilterEditor extends ValueAwareEditor { void init(DataSetMetadata metadata); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefProviderTypeEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.HasEditorErrors; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • provider type
  • *
* * @since 0.4.0 */ public interface DataSetDefProviderTypeEditor extends HasEditorErrors { LeafAttributeEditor provider(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefRefreshAttributesEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.DataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.DataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • refreshTime
  • *
  • refreshAlways
  • *
* * @since 0.4.0 */ public interface DataSetDefRefreshAttributesEditor extends ValueAwareEditor { LeafAttributeEditor refreshAlways(); DataSetDefRefreshIntervalEditor refreshTime(); @Editor.Ignore boolean isRefreshEnabled(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/DataSetDefRefreshIntervalEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.LeafValueEditor; /** *

The GWT editor contract for the refreshInterval attribute for a data set definition.

* * @since 0.4.0 */ public interface DataSetDefRefreshIntervalEditor extends LeafValueEditor { void setEnabled(boolean isEnabled); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/KafkaDataSetDefAttributesEditor.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.KafkaDataSetDef; /** *

The GWT editor contract for the specific attributes of type org.dashbuilder.dataset.def.KafkaDataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • host
  • *
  • port
  • *
  • target
  • *
  • clientId
  • *
  • nodeId
  • *
  • topic
  • *
  • partition
  • *
* */ public interface KafkaDataSetDefAttributesEditor extends ValueAwareEditor { LeafAttributeEditor host(); LeafAttributeEditor port(); LeafAttributeEditor target(); LeafAttributeEditor filter(); LeafAttributeEditor clientId(); LeafAttributeEditor nodeId(); LeafAttributeEditor topic(); LeafAttributeEditor partition(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/KafkaDataSetDefEditor.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.KafkaDataSetDef; import org.dashbuilder.dataset.def.KafkaDataSetDef.MetricsTarget; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.KafkaDataSetDef.

* */ public interface KafkaDataSetDefEditor extends DataSetDefEditor { LeafAttributeEditor host(); LeafAttributeEditor port(); LeafAttributeEditor target(); LeafAttributeEditor filter(); LeafAttributeEditor clientId(); LeafAttributeEditor nodeId(); LeafAttributeEditor topic(); LeafAttributeEditor partition(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/PrometheusDataSetDefAttributesEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.PrometheusDataSetDef; /** *

The GWT editor contract for the specific attributes of type org.dashbuilder.dataset.def.PrometheusDataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • serverUrl
  • *
  • query
  • *
* */ public interface PrometheusDataSetDefAttributesEditor extends ValueAwareEditor { LeafAttributeEditor serverUrl(); LeafAttributeEditor query(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/PrometheusDataSetDefEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.PrometheusDataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.PrometheusDataSetDef.

* */ public interface PrometheusDataSetDefEditor extends DataSetDefEditor { LeafAttributeEditor serverUrl(); LeafAttributeEditor query(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/SQLDataSetDefAttributesEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; /** *

The GWT editor contract for the specific attributes of type org.dashbuilder.dataset.def.SQLDataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • dataSource
  • *
  • dbSchema
  • *
  • dbTable
  • *
  • dbSQL
  • *
*

It is a ValueAwareEditor as must nullify dbTable or dbSQL editors at runtime depending on instance value.

* @since 0.4.0 */ public interface SQLDataSetDefAttributesEditor extends ValueAwareEditor { LeafAttributeEditor dataSource(); LeafAttributeEditor dbSchema(); LeafAttributeEditor dbTable(); LeafAttributeEditor dbSQL(); @Ignore boolean isUsingQuery(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/editor/SQLDataSetDefEditor.java ================================================ package org.dashbuilder.dataset.client.editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; /** *

The GWT editor contract for beans of type org.dashbuilder.dataset.def.SQLDataSetDef.

* * TODO * The attributes dataSource, dbSchema, dbTable and dbSQL should be not directly referenced here, here should be referenced just the org.dashbuilder.dataset.client.editor.SQLDataSetDefAttributesEditor. * But gwt editor inheritance is not working in this situation, due to https://github.com/gwtproject/gwt/issues/6340 * Please refactor it when bug from gwt is fixed. * * @since 0.4.0 */ public interface SQLDataSetDefEditor extends DataSetDefEditor { LeafAttributeEditor dataSource(); LeafAttributeEditor dbSchema(); LeafAttributeEditor dbTable(); LeafAttributeEditor dbSQL(); @Ignore boolean isUsingQuery(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/engine/ClientChronometer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.engine; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.Duration; import org.dashbuilder.dataset.client.resources.i18n.CommonConstants; import org.dashbuilder.dataset.engine.Chronometer; @Dependent public final class ClientChronometer implements Chronometer { protected Double startTime; protected Double stopTime; public long start() { stopTime = null; startTime = Duration.currentTimeMillis(); return startTime.longValue() * 1000000; } public long stop() { stopTime = Duration.currentTimeMillis(); return stopTime.longValue() * 1000000; } public long elapsedTime() { long stop = stopTime != null ? stopTime.longValue() : System.currentTimeMillis(); return (stop - startTime.longValue()) * 1000000; } public String formatElapsedTime(long millis) { long milliseconds = millis; long seconds = milliseconds / 1000; milliseconds %= 1000; long minutes = seconds / 60; seconds %= 60; long hours = minutes / 60; minutes %= 60; long days = hours / 24; hours %= 24; long weeks = days / 7; days %= 7; double secondsd = (double) (seconds * 1000 + milliseconds) / 1000; StringBuilder buf = new StringBuilder(); if (weeks > 0) buf.append(weeks).append(" ").append( CommonConstants.INSTANCE.weeks()).append(" "); if (days > 0) buf.append(days).append("d "); if (hours > 0) buf.append(hours).append("h "); if (minutes > 0) buf.append(minutes).append("m "); if (secondsd > 0) buf.append(secondsd).append("s"); if (buf.length() == 0) return "0s"; return buf.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/engine/ClientDateFormatter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.engine; import java.util.Date; public interface ClientDateFormatter { String format(Date d, String pattern); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/engine/ClientDateFormatterImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.engine; import java.util.Date; import com.google.gwt.i18n.client.DateTimeFormat; public class ClientDateFormatterImpl implements ClientDateFormatter { @Override public String format(Date d, String pattern) { DateTimeFormat format = DateTimeFormat.getFormat(pattern); return format.format(d); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/engine/ClientIntervalBuilderDynamicDate.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.engine; import java.util.Collections; import java.util.Date; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.date.Quarter; import org.dashbuilder.dataset.engine.DataSetHandler; import org.dashbuilder.dataset.engine.group.IntervalBuilder; import org.dashbuilder.dataset.engine.group.IntervalList; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.sort.ColumnSort; import org.dashbuilder.dataset.sort.DataSetSort; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.dataset.sort.SortedList; import static org.dashbuilder.dataset.group.DateIntervalType.*; /** * Interval builder for date columns which generates intervals depending on the underlying data available. */ @ApplicationScoped public class ClientIntervalBuilderDynamicDate implements IntervalBuilder { private ClientDateFormatter dateFormatter; public ClientIntervalBuilderDynamicDate() { } @Inject public ClientIntervalBuilderDynamicDate(ClientDateFormatter dateFormatter) { this.dateFormatter = dateFormatter; } public IntervalList build(DataSetHandler handler, ColumnGroup columnGroup) { IntervalDateRangeList results = new IntervalDateRangeList(columnGroup); DataSet dataSet = handler.getDataSet(); List values = dataSet.getColumnById(columnGroup.getSourceId()).getValues(); if (values.isEmpty()) { return results; } // Sort the column dates. DataSetSort sortOp = new DataSetSort(); sortOp.addSortColumn(new ColumnSort(columnGroup.getSourceId(), SortOrder.ASCENDING)); DataSetHandler sortResults = handler.sort(sortOp); List sortedRows = sortResults.getRows(); if (sortedRows == null || sortedRows.isEmpty()) { return results; } // Get the lower & upper limits. SortedList sortedValues = new SortedList(values, sortedRows); Date minDate = null; Date maxDate = null; for (int i = 0; minDate == null && i < sortedValues.size(); i++) { minDate = (Date) sortedValues.get(i); } for (int i = sortedValues.size()-1; maxDate == null && i >= 0; i--) { maxDate = (Date) sortedValues.get(i); } // If min/max are equals then create a single interval. DateIntervalType intervalType = calculateIntervalSize(minDate, maxDate, columnGroup); if (minDate == null || minDate.compareTo(maxDate) == 0) { IntervalDateRange interval = new IntervalDateRange(0, intervalType, minDate, maxDate); for (int row = 0; row < sortedValues.size(); row++) interval.getRows().add(row); results.add(interval); results.setIntervalType(columnGroup.getIntervalSize()); results.setMinValue(minDate); results.setMaxValue(maxDate); return results; } // Create the intervals according to the min/max dates. Date intervalMinDate = firstIntervalDate(intervalType, minDate, columnGroup); int index = 0; int counter = 0; while (intervalMinDate.compareTo(maxDate) <= 0) { // Go to the next interval Date intervalMaxDate = nextIntervalDate(intervalMinDate, intervalType, 1); // Create the interval. IntervalDateRange interval = new IntervalDateRange(counter++, intervalType, intervalMinDate, intervalMaxDate); results.add(interval); // Add the target rows to the interval. boolean stop = false; while (!stop) { if (index >= sortedValues.size()) { stop = true; } else { Date dateValue = (Date) sortedValues.get(index); Integer row = sortedRows.get(index); if (dateValue == null) { index++; } else if (dateValue.before(intervalMaxDate)) { interval.getRows().add(row); index++; } else { stop = true; } } } // Move to the next interval. intervalMinDate = intervalMaxDate; } // Reverse intervals if requested boolean asc = columnGroup.isAscendingOrder(); if (!asc) Collections.reverse( results ); results.setIntervalType(intervalType.toString()); results.setMinValue(minDate); results.setMaxValue(maxDate); return results; } public IntervalList build(DataColumn dataColumn) { ColumnGroup columnGroup = dataColumn.getColumnGroup(); Date minDate = (Date) dataColumn.getMinValue(); Date maxDate = (Date) dataColumn.getMaxValue(); IntervalDateRangeList results = new IntervalDateRangeList(columnGroup); if (minDate == null || maxDate == null) { return results; } DateIntervalType intervalType = DateIntervalType.getByName(dataColumn.getIntervalType()); if (intervalType == null) { intervalType = DateIntervalType.YEAR; } Date intervalMinDate = firstIntervalDate(intervalType, minDate, columnGroup); int counter = 0; while (intervalMinDate.compareTo(maxDate) <= 0) { // Go to the next interval Date intervalMaxDate = nextIntervalDate(intervalMinDate, intervalType, 1); // Create the interval. IntervalDateRange interval = new IntervalDateRange(counter++, intervalType, intervalMinDate, intervalMaxDate); results.add(interval); // Move to the next interval. intervalMinDate = intervalMaxDate; } // Reverse intervals if requested boolean asc = columnGroup.isAscendingOrder(); if (!asc) Collections.reverse( results ); results.setIntervalType(intervalType.toString()); results.setMinValue(minDate); results.setMaxValue(maxDate); return results; } public DateIntervalType calculateIntervalSize(Date minDate, Date maxDate, ColumnGroup columnGroup) { DateIntervalType intervalType = DateIntervalType.getByName(columnGroup.getIntervalSize()); if (intervalType == null) { intervalType = YEAR; } if (minDate == null || maxDate == null) { return intervalType; } long millis = (maxDate.getTime() - minDate.getTime()); if (millis <= 0) { return intervalType; } // Calculate the interval type used according to the constraints set. int maxIntervals = columnGroup.getMaxIntervals(); if (maxIntervals < 1) maxIntervals = 15; for (DateIntervalType type : values()) { long nintervals = millis / getDurationInMillis(type); if (nintervals < maxIntervals) { intervalType = type; break; } } // Ensure the interval mode obtained is always greater or equals than the preferred interval size. DateIntervalType intervalSize = null; String preferredSize = columnGroup.getIntervalSize(); if (preferredSize != null && preferredSize.trim().length() > 0) { intervalSize = getByName(columnGroup.getIntervalSize()); } if (intervalSize != null && compare(intervalType, intervalSize) == -1) { intervalType = intervalSize; } return intervalType; } protected Date firstIntervalDate(DateIntervalType intervalType, Date minDate, ColumnGroup columnGroup) { Date intervalMinDate = new Date(minDate.getTime()); if (YEAR.equals(intervalType)) { intervalMinDate.setMonth(0); intervalMinDate.setDate(1); intervalMinDate.setHours(0); intervalMinDate.setMinutes(0); intervalMinDate.setSeconds(0); } if (QUARTER.equals(intervalType)) { int currentMonth = intervalMinDate.getMonth(); int firstMonthYear = columnGroup.getFirstMonthOfYear().getIndex(); int rest = Quarter.getPositionInQuarter(firstMonthYear, currentMonth + 1); intervalMinDate.setMonth(currentMonth - rest); intervalMinDate.setDate(1); intervalMinDate.setHours(0); intervalMinDate.setMinutes(0); intervalMinDate.setSeconds(0); } if (MONTH.equals(intervalType)) { intervalMinDate.setDate(1); intervalMinDate.setHours(0); intervalMinDate.setMinutes(0); intervalMinDate.setSeconds(0); } if (DAY.equals(intervalType) || DAY_OF_WEEK.equals(intervalType) || WEEK.equals(intervalType)) { intervalMinDate.setHours(0); intervalMinDate.setMinutes(0); intervalMinDate.setSeconds(0); } if (HOUR.equals(intervalType)) { intervalMinDate.setMinutes(0); intervalMinDate.setSeconds(0); } if (MINUTE.equals(intervalType)) { intervalMinDate.setSeconds(0); } return intervalMinDate; } protected Date nextIntervalDate(Date intervalMinDate, DateIntervalType intervalType, int intervals) { Date intervalMaxDate = new Date(intervalMinDate.getTime()); if (MILLENIUM.equals(intervalType)) { intervalMaxDate.setYear(intervalMinDate.getYear() + 1000 * intervals); } else if (CENTURY.equals(intervalType)) { intervalMaxDate.setYear(intervalMinDate.getYear() + 100 * intervals); } else if (DECADE.equals(intervalType)) { intervalMaxDate.setYear(intervalMinDate.getYear() + 10 * intervals); } else if (YEAR.equals(intervalType)) { intervalMaxDate.setYear(intervalMinDate.getYear() + intervals); } else if (QUARTER.equals(intervalType)) { intervalMaxDate.setMonth(intervalMinDate.getMonth() + 3 * intervals); } else if (MONTH.equals(intervalType)) { intervalMaxDate.setMonth(intervalMinDate.getMonth() + intervals); } else if (WEEK.equals(intervalType)) { intervalMaxDate.setDate(intervalMinDate.getDate() + 7 * intervals); } else if (DAY.equals(intervalType) || DAY_OF_WEEK.equals(intervalType)) { intervalMaxDate.setDate(intervalMinDate.getDate() + intervals); } else if (HOUR.equals(intervalType)) { intervalMaxDate.setHours(intervalMinDate.getHours() + intervals); } else if (MINUTE.equals(intervalType)) { intervalMaxDate.setMinutes(intervalMinDate.getMinutes() + intervals); } else if (SECOND.equals(intervalType)) { intervalMaxDate.setSeconds(intervalMinDate.getSeconds() + intervals); } else { // Default to year to avoid infinite loops intervalMaxDate.setYear(intervalMinDate.getYear() + intervals); } return intervalMaxDate; } /** * A list containing date range intervals. */ public class IntervalDateRangeList extends IntervalList { public IntervalDateRangeList(ColumnGroup columnGroup) { super(columnGroup); } public Interval locateInterval(Object value) { Date d = (Date) value; for (Interval interval : this) { IntervalDateRange dateRange = (IntervalDateRange) interval; if (d.equals(dateRange.getMinDate()) || (d.after(dateRange.getMinDate()) && d.before(dateRange.getMaxDate()))) { return interval; } } return null; } } /** * A date interval holding dates belonging to a given range. */ public class IntervalDateRange extends Interval { public IntervalDateRange(int index, DateIntervalType intervalType, Date minDate, Date maxDate) { super(calculateName(intervalType, minDate)); super.setMinValue(minDate); super.setMaxValue(maxDate); super.setIndex(index); super.setType(intervalType != null ? intervalType.toString() : null); } public Date getMinDate() { return (Date) minValue; } public Date getMaxDate() { return (Date) maxValue; } } public String calculateName(DateIntervalType intervalType, Date d) { if (MILLENIUM.equals(intervalType) || CENTURY.equals(intervalType) || DECADE.equals(intervalType) || YEAR.equals(intervalType)) { return dateFormatter.format(d, "yyyy"); } if (QUARTER.equals(intervalType) || MONTH.equals(intervalType)) { return dateFormatter.format(d, "yyyy-MM"); } if (WEEK.equals(intervalType) || DAY.equals(intervalType) || DAY_OF_WEEK.equals(intervalType)) { return dateFormatter.format(d, "yyyy-MM-dd"); } if (HOUR.equals(intervalType)) { return dateFormatter.format(d, "yyyy-MM-dd HH"); } if (MINUTE.equals(intervalType)) { return dateFormatter.format(d, "yyyy-MM-dd HH:mm"); } if (SECOND.equals(intervalType)) { return dateFormatter.format(d, "yyyy-MM-dd HH:mm:ss"); } return null; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/engine/ClientIntervalBuilderLocator.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.engine; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.client.resources.i18n.CommonConstants; import org.dashbuilder.dataset.engine.group.IntervalBuilder; import org.dashbuilder.dataset.engine.group.IntervalBuilderDynamicLabel; import org.dashbuilder.dataset.engine.group.IntervalBuilderFixedDate; import org.dashbuilder.dataset.engine.group.IntervalBuilderLocator; import org.dashbuilder.dataset.group.GroupStrategy; @ApplicationScoped public class ClientIntervalBuilderLocator implements IntervalBuilderLocator { IntervalBuilderDynamicLabel intervalBuilderDynamicLabel; ClientIntervalBuilderDynamicDate intervalBuilderDynamicDate; IntervalBuilderFixedDate intervalBuilderFixedDate; public ClientIntervalBuilderLocator() { } @Inject public ClientIntervalBuilderLocator(IntervalBuilderDynamicLabel intervalBuilderDynamicLabel, ClientIntervalBuilderDynamicDate intervalBuilderDynamicDate, IntervalBuilderFixedDate intervalBuilderFixedDate) { this.intervalBuilderDynamicLabel = intervalBuilderDynamicLabel; this.intervalBuilderDynamicDate = intervalBuilderDynamicDate; this.intervalBuilderFixedDate = intervalBuilderFixedDate; } public IntervalBuilder lookup(ColumnType columnType, GroupStrategy strategy) { if (ColumnType.LABEL.equals(columnType)) { if (GroupStrategy.FIXED.equals(strategy)) return intervalBuilderDynamicLabel; if (GroupStrategy.DYNAMIC.equals(strategy)) return intervalBuilderDynamicLabel; } if (ColumnType.DATE.equals(columnType)) { if (GroupStrategy.FIXED.equals(strategy)) return intervalBuilderFixedDate; if (GroupStrategy.DYNAMIC.equals(strategy)) return intervalBuilderDynamicDate; return intervalBuilderDynamicDate; } if (ColumnType.NUMBER.equals(columnType)) { return intervalBuilderDynamicLabel; } if (ColumnType.TEXT.equals(columnType)) { throw new IllegalArgumentException( CommonConstants.INSTANCE.exc_text_columns_no_grouping()); } return null; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/bundles/DataSetClientImages.java ================================================ /* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.bundles; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.DataResource; import com.google.gwt.resources.client.ImageResource; /** * GWT managed images for Data Set client components. */ public interface DataSetClientImages extends ClientBundle { @Source("images/csv_icon_160.png") DataResource csvIcon160(); @Source("images/csv_icon_32.png") DataResource csvIcon32(); @Source("images/java_icon_160.png") DataResource javaIcon160(); @Source("images/java_icon_32.png") DataResource javaIcon32(); @Source("images/sql_icon_160.png") DataResource sqlIcon160(); @Source("images/sql_icon_32.png") DataResource sqlIcon32(); @Source("images/el_icon_160.png") DataResource elIcon160(); @Source("images/el_icon_32.png") DataResource elIcon32(); @Source("images/excel_icon.png") DataResource excelIcon(); @Source("images/label_icon_16.png") DataResource labelIcon16(); @Source("images/label_icon_32.png") DataResource labelIcon32(); @Source("images/number_icon_32_V1.png") DataResource numberIcon32V1(); @Source("images/number_icon_32_V2.png") DataResource numberIcon32V2(); @Source("images/number_icon_32_V3.png") DataResource numberIcon32V3(); @Source("images/text_icon_16.png") DataResource textIcon16(); @Source("images/text_icon_32.png") DataResource textIcon32(); @Source("images/date_icon_16.png") DataResource dateIcon16(); @Source("images/date_icon_16.png") DataResource dateIcon32(); @Source("images/ok_icon_small.gif") ImageResource okIconSmall(); @Source("images/cancel_icon_small.gif") ImageResource cancelIconSmall(); @Source("images/loading_icon.gif") DataResource loadingIcon(); @Source("images/prometheus_icon_160.png") DataResource prometheusIcon160(); @Source("images/prometheus_icon_32.png") DataResource prometheusIcon32(); @Source("images/kafka_icon_160.png") DataResource kafkaIcon160(); @Source("images/kafka_icon_32.png") DataResource kafkaIcon32(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/bundles/DataSetClientResources.java ================================================ package org.dashbuilder.dataset.client.resources.bundles; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; public interface DataSetClientResources extends ClientBundle { DataSetClientResources INSTANCE = GWT.create( DataSetClientResources.class ); DataSetClientImages images(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface AggregateFunctionTypeConstants extends ConstantsWithLookup { public static final AggregateFunctionTypeConstants INSTANCE = GWT.create( AggregateFunctionTypeConstants.class ); String COUNT(); String DISTINCT(); String AVERAGE(); String SUM(); String MIN(); String MAX(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/CommonConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface CommonConstants extends Messages { public static final CommonConstants INSTANCE = GWT.create( CommonConstants.class ); String weeks(); String exc_text_columns_no_grouping(); String exc_no_client_side_data_export(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface CoreFunctionTypeConstants extends ConstantsWithLookup { public static final CoreFunctionTypeConstants INSTANCE = GWT.create( CoreFunctionTypeConstants.class ); String IS_NULL(); String NOT_NULL(); String EQUALS_TO(); String NOT_EQUALS_TO(); String LIKE_TO(); String GREATER_THAN(); String GREATER_OR_EQUALS_TO(); String LOWER_THAN(); String LOWER_OR_EQUALS_TO(); String BETWEEN(); String TIME_FRAME(); String IN(); String NOT_IN(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface DateIntervalTypeConstants extends ConstantsWithLookup { public static final DateIntervalTypeConstants INSTANCE = GWT.create( DateIntervalTypeConstants.class ); String MILLISECOND(); String HUNDRETH(); String TENTH(); String SECOND(); String MINUTE(); String HOUR(); String DAY(); String DAY_OF_WEEK(); String WEEK(); String MONTH(); String QUARTER(); String YEAR(); String DECADE(); String CENTURY(); String MILLENIUM(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface DayOfWeekConstants extends ConstantsWithLookup { public static final DayOfWeekConstants INSTANCE = GWT.create( DayOfWeekConstants.class ); String SUNDAY(); String MONDAY(); String TUESDAY(); String WEDNESDAY(); String THURSDAY(); String FRIDAY(); String SATURDAY(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/MonthConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface MonthConstants extends ConstantsWithLookup { public static final MonthConstants INSTANCE = GWT.create( MonthConstants.class ); String JANUARY(); String FEBRUARY(); String MARCH(); String APRIL(); String MAY(); String JUNE(); String JULY(); String AUGUST(); String SEPTEMBER(); String OCTOBER(); String NOVEMBER(); String DECEMBER(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface QuarterConstants extends ConstantsWithLookup { public static final QuarterConstants INSTANCE = GWT.create( QuarterConstants.class ); String Q1(); String Q2(); String Q3(); String Q4(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface TimeModeConstants extends ConstantsWithLookup { public static final TimeModeConstants INSTANCE = GWT.create( TimeModeConstants.class ); String NOW(); String BEGIN(); String END(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/java/org/dashbuilder/dataset/client/uuid/ClientUUIDGenerator.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client.uuid; import javax.enterprise.context.ApplicationScoped; import com.google.gwt.dom.client.Document; import org.dashbuilder.dataset.uuid.UUIDGenerator; @ApplicationScoped public class ClientUUIDGenerator implements UUIDGenerator { public String newUuid() { return Document.get().createUniqueId(); } public String newUuidBase64() { return Document.get().createUniqueId(); } public String uuidToBase64(String str) { return str; } public String uuidFromBase64(String str) { return str; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/DatasetClient.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # COUNT=Count DISTINCT=Distinct AVERAGE=Average SUM=Sum MIN=Min MAX=Max ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants_de.properties ================================================ COUNT=Anzahl DISTINCT=Eindeutig AVERAGE=Durchschnitt SUM=Summe MIN=Min. MAX=Max. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # COUNT=Recuento DISTINCT=Distinto AVERAGE=Promedio SUM=Suma MIN=Mín. MAX=Máx. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # COUNT=Nombre DISTINCT=Distinct AVERAGE=Moyenne SUM=Somme MIN=Min MAX=Max ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # COUNT=Conteggio DISTINCT=Distinto AVERAGE=Media SUM=Somma MIN=Minimo MAX=Massimo ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # COUNT=回数 DISTINCT=一意 AVERAGE=平均 SUM=合計 MIN=最小 MAX=最大 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants_pt_BR.properties ================================================ COUNT=Contar DISTINCT=Distinguir AVERAGE=Média SUM=Soma MIN=Min MAX=Max ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/AggregateFunctionTypeConstants_zh_CN.properties ================================================ COUNT=计数 DISTINCT=区分 AVERAGE=平均值 SUM=总数 MIN=最小值 MAX=最大值 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # weeks=weeks exc_text_columns_no_grouping=TEXT columns do not support grouping. exc_no_client_side_data_export=Client-side export is not available. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants_de.properties ================================================ weeks=Wochen exc_text_columns_no_grouping=TEXT-Spalten unterstützen keine Gruppierung. exc_no_client_side_data_export=Export auf Client-Seite ist nicht verfügbar. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants_es.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # weeks=semanas exc_text_columns_no_grouping=Las columnas de TEXTO no soportan la agrupación. exc_no_client_side_data_export=La exportación del lado del cliente no está disponible. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants_fr.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # weeks=semaines exc_text_columns_no_grouping=Les colonnes TEXTE ne permettent pas le regroupement. exc_no_client_side_data_export=L''exportation côté client n''est pas disponible. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants_it.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # weeks=settimane exc_text_columns_no_grouping=Le colonne di testo non supportano il raggruppamento. exc_no_client_side_data_export=L''esportazione lato client non è disponibile. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants_ja.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # weeks=週 exc_text_columns_no_grouping=TEXT 列はグループ化をサポートしません。 exc_no_client_side_data_export=クライアントサイドエクスポートは利用不可です。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants_pt_BR.properties ================================================ weeks=semanas exc_text_columns_no_grouping=Colunas de TEXTO não suportam o agrupamento. exc_no_client_side_data_export=Exportação do lado do cliente não está disponível. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CommonConstants_zh_CN.properties ================================================ weeks=周 exc_text_columns_no_grouping=TEXT 字段不支持分组。 exc_no_client_side_data_export=客户端的导出不可用。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # IS_NULL=is null NOT_NULL=not null EQUALS_TO=equals to NOT_EQUALS_TO=different to LIKE_TO=like GREATER_THAN=greater than GREATER_OR_EQUALS_TO=greater or equals LOWER_THAN=lower than LOWER_OR_EQUALS_TO=lower or equals BETWEEN=between TIME_FRAME=time frame IN=in NOT_IN=not in ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants_de.properties ================================================ IS_NULL=ist Null NOT_NULL=nicht Null EQUALS_TO=gleich NOT_EQUALS_TO=ungleich LIKE_TO=wie GREATER_THAN=größer als GREATER_OR_EQUALS_TO=größer oder gleich LOWER_THAN=kleiner als LOWER_OR_EQUALS_TO=kleiner oder gleich BETWEEN=zwischen TIME_FRAME=Zeitrahmen IN=in NOT_IN=nicht in ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # IS_NULL=es nulo NOT_NULL=no es nulo EQUALS_TO=es igual a NOT_EQUALS_TO=diferente de LIKE_TO=como GREATER_THAN=mayor a GREATER_OR_EQUALS_TO=mayor o igual LOWER_THAN=inferior a LOWER_OR_EQUALS_TO=inferior o igual BETWEEN=entre TIME_FRAME=marco de tiempo IN=en NOT_IN=no en ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # IS_NULL=est nul NOT_NULL=non nul EQUALS_TO=est égal à NOT_EQUALS_TO=différent de LIKE_TO=correspond à GREATER_THAN=supérieur à GREATER_OR_EQUALS_TO=supérieur ou égal LOWER_THAN=inférieur à LOWER_OR_EQUALS_TO=inférieur ou égal BETWEEN=entre TIME_FRAME=période IN=dans NOT_IN=hors de ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # IS_NULL=è nullo NOT_NULL=non è nullo EQUALS_TO=uguale a NOT_EQUALS_TO=diverso da LIKE_TO=come GREATER_THAN=maggiore di GREATER_OR_EQUALS_TO=maggiore o uguale a LOWER_THAN=minore di LOWER_OR_EQUALS_TO=minore o uguale a BETWEEN=tra TIME_FRAME=intervallo di tempo IN=in NOT_IN=non in ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # IS_NULL=は null NOT_NULL=null ではない EQUALS_TO=等しい NOT_EQUALS_TO=異なる LIKE_TO=似ている GREATER_THAN=は次の値よりも大きい: GREATER_OR_EQUALS_TO=以上 LOWER_THAN=未満 LOWER_OR_EQUALS_TO=以下 BETWEEN=は次の値の間にある TIME_FRAME=タイムフレーム IN=in NOT_IN=not in ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants_pt_BR.properties ================================================ IS_NULL=é nulo NOT_NULL=não é nulo EQUALS_TO=igual a NOT_EQUALS_TO=diferente de LIKE_TO=como GREATER_THAN=maior do que GREATER_OR_EQUALS_TO=maior ou igual a LOWER_THAN=menor do que LOWER_OR_EQUALS_TO=menor ou igual a BETWEEN=entre TIME_FRAME=tempo IN=em NOT_IN=não em ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/CoreFunctionTypeConstants_zh_CN.properties ================================================ IS_NULL=为 null NOT_NULL=非 null EQUALS_TO=等于 NOT_EQUALS_TO=不同于 LIKE_TO=类似 GREATER_THAN=大于 GREATER_OR_EQUALS_TO=大于或等于 LOWER_THAN=低于 LOWER_OR_EQUALS_TO=低于或等于 BETWEEN=介于之间 TIME_FRAME=时间范围 IN=包括 NOT_IN=不包括 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # MILLISECOND=Millisecond HUNDRETH=Hundreth TENTH=Tenth SECOND=Second MINUTE=Minute HOUR=Hour DAY=Day DAY_OF_WEEK=Day of week WEEK=Week MONTH=Month QUARTER=Quarter YEAR=Year DECADE=Decade CENTURY=Century MILLENIUM=Millenium ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants_de.properties ================================================ MILLISECOND=Millisekunde HUNDRETH=Hunderstel TENTH=Zehntel SECOND=Sekunde MINUTE=Minute HOUR=Stunde DAY=Tag DAY_OF_WEEK=Wochentag WEEK=Woche MONTH=Monat QUARTER=Quartal YEAR=Jahr DECADE=Jahrzehnt CENTURY=Jahrhundert MILLENIUM=Jahrtausend ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # MILLISECOND=Milisegundo HUNDRETH=Centésimo TENTH=Décimo SECOND=Segundo MINUTE=Minuto HOUR=Hora DAY=Día DAY_OF_WEEK=Día de la semana WEEK=Semana MONTH=Mes QUARTER=Trimestre YEAR=Año DECADE=Década CENTURY=Siglo MILLENIUM=Milenio ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # MILLISECOND=Milliseconde HUNDRETH=Centième TENTH=Dixième SECOND=Deuxième MINUTE=Minute HOUR=Heure DAY=Jour DAY_OF_WEEK=Jour de la semaine WEEK=Semaine MONTH=Mois QUARTER=Trimestre YEAR=Année DECADE=Décennie CENTURY=Siècle MILLENIUM=Millénaire ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # MILLISECOND=Millisecondo HUNDRETH=Centesimo TENTH=Decimo SECOND=Secondo MINUTE=Minuto HOUR=Ora DAY=Giorno DAY_OF_WEEK=Giorno della settimana WEEK=Settimana MONTH=Mese QUARTER=Trimestre YEAR=Anno DECADE=Decennio CENTURY=Secolo MILLENIUM=Millennio ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # MILLISECOND=ミリ秒 HUNDRETH=1/100 TENTH=1/10 SECOND=2 番目 MINUTE=分 HOUR=時間 DAY=日 DAY_OF_WEEK=曜日 WEEK=週 MONTH=月 QUARTER=四半期 YEAR=年 DECADE=10 年 CENTURY=100 年 MILLENIUM=1000 年 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants_pt_BR.properties ================================================ MILLISECOND=Milésimos de segundos HUNDRETH=Centézimo TENTH=Décimo SECOND=Segundo MINUTE=Minuto HOUR=Hora DAY=Dia DAY_OF_WEEK=Dia da semana WEEK=Semana MONTH=Mês QUARTER=Trimestre YEAR=Ano DECADE=Década CENTURY=Século MILLENIUM=Milênio ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DateIntervalTypeConstants_zh_CN.properties ================================================ MILLISECOND=毫秒 HUNDRETH=第一百 TENTH=第十 SECOND=秒 MINUTE=分钟 HOUR=小时 DAY=天 DAY_OF_WEEK=星期几 WEEK=周 MONTH=月 QUARTER=季度 YEAR=年 DECADE=十年 CENTURY=世纪 MILLENIUM=一千年 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # SUNDAY=Sunday MONDAY=Monday TUESDAY=Tuesday WEDNESDAY=Wednesday THURSDAY=Thursday FRIDAY=Friday SATURDAY=Saturday ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants_de.properties ================================================ SUNDAY=Sonntag MONDAY=Montag TUESDAY=Dienstag WEDNESDAY=Mittwoch THURSDAY=Donnerstag FRIDAY=Freitag SATURDAY=Samstag ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # SUNDAY=Domingo MONDAY=Lunes TUESDAY=Martes WEDNESDAY=Miércoles THURSDAY=Jueves FRIDAY=Viernes SATURDAY=Sábado ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # SUNDAY=Dimanche MONDAY=Lundi TUESDAY=Mardi WEDNESDAY=Mercredi THURSDAY=Jeudi FRIDAY=Vendredi SATURDAY=Samedi ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # SUNDAY=Domenica MONDAY=Lunedì TUESDAY=Martedì WEDNESDAY=Mercoledì THURSDAY=Giovedì FRIDAY=Venerdì SATURDAY=Sabato ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # SUNDAY=日曜日 MONDAY=月曜日 TUESDAY=火曜日 WEDNESDAY=水曜日 THURSDAY=木曜日 FRIDAY=金曜日 SATURDAY=土曜日 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants_pt_BR.properties ================================================ SUNDAY=Domingo MONDAY=segunda-feira TUESDAY=terça-feira WEDNESDAY=quarta-feira THURSDAY=quinta-feira FRIDAY=sexta-feira SATURDAY=Sábado ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/DayOfWeekConstants_zh_CN.properties ================================================ SUNDAY=星期天 MONDAY=星期一 TUESDAY=星期二 WEDNESDAY=星期三 THURSDAY=星期四 FRIDAY=星期五 SATURDAY=星期六 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # JANUARY=January FEBRUARY=February MARCH=March APRIL=April MAY=May JUNE=June JULY=July AUGUST=August SEPTEMBER=September OCTOBER=October NOVEMBER=November DECEMBER=December ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants_de.properties ================================================ JANUARY=Januar FEBRUARY=Februar MARCH=März APRIL=April MAY=Mai JUNE=Juni JULY=Juli AUGUST=August SEPTEMBER=September OCTOBER=Oktober NOVEMBER=November DECEMBER=Dezember ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # JANUARY=Enero FEBRUARY=Febrero MARCH=Marzo APRIL=Abril MAY=Mayo JUNE=Junio JULY=Julio AUGUST=Agosto SEPTEMBER=Septiembre OCTOBER=Octubre NOVEMBER=Noviembre DECEMBER=Diciembre ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # JANUARY=Janvier FEBRUARY=Février MARCH=Mars APRIL=Avril MAY=Mai JUNE=Juin JULY=Juillet AUGUST=Août SEPTEMBER=Septembre OCTOBER=Octobre NOVEMBER=Novembre DECEMBER=Décembre ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # JANUARY=Gennaio FEBRUARY=Febbraio MARCH=Marzo APRIL=Aprile MAY=Maggio JUNE=Giugno JULY=Luglio AUGUST=Agosto SEPTEMBER=Settembre OCTOBER=Ottobre NOVEMBER=Novembre DECEMBER=Dicembre ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # JANUARY=1月 FEBRUARY=2月 MARCH=3月 APRIL=4月 MAY=5月 JUNE=6月 JULY=7月 AUGUST=8月 SEPTEMBER=9月 OCTOBER=10月 NOVEMBER=11月 DECEMBER=12月 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants_pt_BR.properties ================================================ JANUARY=Janeiro FEBRUARY=Fevereiro MARCH=Março APRIL=Abril MAY=Maio JUNE=Junho JULY=Julho AUGUST=Agosto SEPTEMBER=Setembro OCTOBER=Outubro NOVEMBER=Novembro DECEMBER=Dezembro ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/MonthConstants_zh_CN.properties ================================================ JANUARY=1月 FEBRUARY=2月 MARCH=3月 APRIL=4月 MAY=5月 JUNE=6月 JULY=7月 AUGUST=8月 SEPTEMBER=9月 OCTOBER=10月 NOVEMBER=11月 DECEMBER=12月 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Q1=Q1 Q2=Q2 Q3=Q3 Q4=Q4 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants_de.properties ================================================ Q1=Q1 Q2=Q2 Q3=Q3 Q4=Q4 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Q1=Primer trimestre Q2=Segundo trimestre Q3=Tercer trimestre Q4=Cuarto trimestre ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Q1=T1 Q2=T2 Q3=T3 Q4=T4 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Q1=Q1 Q2=Q2 Q3=Q3 Q4=Q4 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Q1=Q1 Q2=Q2 Q3=Q3 Q4=Q4 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants_pt_BR.properties ================================================ Q1=Q1 Q2=Q2 Q3=Q3 Q4=Q4 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/QuarterConstants_zh_CN.properties ================================================ Q1=Q1 Q2=Q2 Q3=Q3 Q4=Q4 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # NOW=Now BEGIN=Begin of END=End of ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants_de.properties ================================================ NOW=Jetzt BEGIN=Beginn von END=Ende von ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # NOW=Ahora BEGIN=Comienzo de END=Fin de ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # NOW=Maintenant BEGIN=Début de END=Fin de ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # NOW=Ora BEGIN=Inizio di END=Fine di ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # NOW=現在 BEGIN=開始 END=終了 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants_pt_BR.properties ================================================ NOW=Agora BEGIN=Começo de END=Final de ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/main/resources/org/dashbuilder/dataset/client/resources/i18n/TimeModeConstants_zh_CN.properties ================================================ NOW=现在 BEGIN=开始于 END=结束于 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/test/java/org/dashbuilder/dataset/client/AbstractDataSetTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import javax.enterprise.event.Event; import org.dashbuilder.common.client.backend.PathUrlFactory; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetFormatter; import org.dashbuilder.dataset.ExpenseReportsData; import org.dashbuilder.dataset.events.DataSetModifiedEvent; import org.dashbuilder.dataset.events.DataSetPushOkEvent; import org.dashbuilder.dataset.events.DataSetPushingEvent; import org.dashbuilder.dataset.service.DataSetDefServices; import org.dashbuilder.dataset.service.DataSetExportServices; import org.dashbuilder.dataset.service.DataSetLookupServices; import org.jboss.errai.common.client.api.Caller; import org.junit.Before; import org.mockito.Mock; import org.uberfire.mocks.CallerMock; public abstract class AbstractDataSetTest { @Mock protected Event dataSetPushingEvent; @Mock protected Event dataSetPushOkEvent; @Mock protected Event dataSetModifiedEvent; @Mock protected DataSetLookupServices dataSetLookupServices; @Mock protected DataSetExportServices dataSetExportServices; @Mock protected PathUrlFactory pathUrlFactory; @Mock protected Caller dataSetDefServicesCaller; protected Caller dataSetExportServicesCaller; protected Caller dataSetLookupServicesCaller; protected ClientDataSetCore clientDataSetCore; protected DataSetClientServices clientServices; protected ClientDataSetManager clientDataSetManager; protected DataSet expensesDataSet; protected DataSetFormatter dataSetFormatter = new DataSetFormatter(); public static final String EXPENSES = "expenses"; public void initClientFactory() { clientDataSetCore = ClientDataSetCore.get(); clientDataSetCore.setClientDateFormatter(new ClientDateFormatterMock()); clientDataSetCore.setChronometer(new ChronometerMock()); } public void initClientDataSetManager() { clientDataSetManager = clientDataSetCore.getClientDataSetManager(); } public void initDataSetClientServices() { dataSetExportServicesCaller = new CallerMock<>(dataSetExportServices); dataSetLookupServicesCaller = new CallerMock<>(dataSetLookupServices); clientServices = new DataSetClientServices( clientDataSetManager, pathUrlFactory, clientDataSetCore.getAggregateFunctionManager(), clientDataSetCore.getIntervalBuilderLocator(), dataSetPushingEvent, dataSetPushOkEvent, dataSetModifiedEvent, dataSetLookupServicesCaller, dataSetDefServicesCaller, dataSetExportServicesCaller); } public void registerExpensesDataSet() throws Exception { expensesDataSet = ExpenseReportsData.INSTANCE.toDataSet(); expensesDataSet.setUUID(EXPENSES); clientDataSetManager.registerDataSet(expensesDataSet); } @Before public void init() throws Exception { initClientFactory(); initClientDataSetManager(); initDataSetClientServices(); registerExpensesDataSet(); } public void printDataSet(DataSet dataSet) { System.out.print(dataSetFormatter.formatDataSet(dataSet, "{", "}", ",\n", "\"", "\"", ", ") + "\n\n"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/test/java/org/dashbuilder/dataset/client/ChronometerMock.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import org.dashbuilder.dataset.engine.Chronometer; public class ChronometerMock implements Chronometer { @Override public long start() { return 0; } @Override public long stop() { return 0; } @Override public long elapsedTime() { return 0; } @Override public String formatElapsedTime(long millis) { return String.valueOf(millis); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/test/java/org/dashbuilder/dataset/client/ClientDataSetManagerTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookupFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.SUM; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class ClientDataSetManagerTest extends AbstractDataSetTest { @Test public void testGroupWithNullDates() { // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DATE)); expensesDataSet.setValueAt(0, column, null); // Group by date. No NPE must occur. DataSet result = clientDataSetManager.lookupDataSet( DataSetLookupFactory.newDataSetLookupBuilder() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .buildLookup()); assertEquals(result.getRowCount(), 4); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/test/java/org/dashbuilder/dataset/client/ClientDateFormatterMock.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import java.text.SimpleDateFormat; import java.util.Date; import org.dashbuilder.dataset.client.engine.ClientDateFormatter; public class ClientDateFormatterMock implements ClientDateFormatter { @Override public String format(Date d, String pattern) { SimpleDateFormat sdf = new SimpleDateFormat(pattern); return sdf.format(d); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-client/src/test/java/org/dashbuilder/dataset/client/DataSetClientServicesTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.client; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.service.DataSetLookupServices; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mocks.CallerMock; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DataSetClientServicesTest { @Mock private ClientDataSetManager clientDataSetManager; @Mock private DataSetMetadata dataSetMetadata; @Mock private DataSetLookupServices dataSetLookupServices; private CallerMock dataSetLookupServicesCallerMock; private boolean isCallbackCalled = false; private boolean isNotFoundCalled = false; private boolean isOnErrorCalled = false; @Before public void setup() { dataSetLookupServicesCallerMock = new CallerMock<>(dataSetLookupServices); } @Test public void testFetchMetadataWhenMetadataIsNotNull() throws Exception { final String uuid = "uuid"; final DataSetClientServices services = makeDataSetClientServices(clientDataSetManager, dataSetLookupServicesCallerMock); when(clientDataSetManager.getDataSetMetadata(uuid)).thenReturn(dataSetMetadata); services.fetchMetadata(uuid, makeDataSetMetadataCallback()); assertTrue(isDataSetMetadataCallbackCalled()); assertFalse(isDataSetMetadataNotFoundCallbackCalled()); assertFalse(isDataSetMetadataOnErrorCallbackCalled()); assertNull(services.getRemoteMetadataMap().get(uuid)); } @Test public void testFetchMetadataWhenSetLookupServicesIsNull() throws Exception { final String uuid = "uuid"; final DataSetClientServices services = makeDataSetClientServices(clientDataSetManager, null); when(clientDataSetManager.getDataSetMetadata(uuid)).thenReturn(null); services.fetchMetadata(uuid, makeDataSetMetadataCallback()); assertFalse(isDataSetMetadataCallbackCalled()); assertTrue(isDataSetMetadataNotFoundCallbackCalled()); assertFalse(isDataSetMetadataOnErrorCallbackCalled()); assertNull(services.getRemoteMetadataMap().get(uuid)); } @Test public void testFetchMetadataWhenRemoteMetadataMapContainsTheUUID() throws Exception { final String uuid = "uuid"; final DataSetClientServices services = makeDataSetClientServices(clientDataSetManager, dataSetLookupServicesCallerMock); services.getRemoteMetadataMap().put(uuid, null); when(clientDataSetManager.getDataSetMetadata(uuid)).thenReturn(null); services.fetchMetadata(uuid, makeDataSetMetadataCallback()); assertTrue(isDataSetMetadataCallbackCalled()); assertFalse(isDataSetMetadataNotFoundCallbackCalled()); assertFalse(isDataSetMetadataOnErrorCallbackCalled()); assertNull(services.getRemoteMetadataMap().get(uuid)); } @Test public void testFetchMetadataWhenResultIsNull() throws Exception { final String uuid = "uuid"; final DataSetClientServices services = makeDataSetClientServices(clientDataSetManager, dataSetLookupServicesCallerMock); when(clientDataSetManager.getDataSetMetadata(uuid)).thenReturn(null); when(dataSetLookupServices.lookupDataSetMetadata(eq(uuid))).thenReturn(null); services.fetchMetadata(uuid, makeDataSetMetadataCallback()); assertFalse(isDataSetMetadataCallbackCalled()); assertTrue(isDataSetMetadataNotFoundCallbackCalled()); assertFalse(isDataSetMetadataOnErrorCallbackCalled()); assertNull(services.getRemoteMetadataMap().get(uuid)); } @Test public void testFetchMetadataWhenResultIsNotNull() throws Exception { final String uuid = "uuid"; final DataSetClientServices services = makeDataSetClientServices(clientDataSetManager, dataSetLookupServicesCallerMock); when(clientDataSetManager.getDataSetMetadata(uuid)).thenReturn(null); when(dataSetLookupServices.lookupDataSetMetadata(eq(uuid))).thenReturn(dataSetMetadata); services.fetchMetadata(uuid, makeDataSetMetadataCallback()); assertTrue(isDataSetMetadataCallbackCalled()); assertFalse(isDataSetMetadataNotFoundCallbackCalled()); assertFalse(isDataSetMetadataOnErrorCallbackCalled()); assertEquals(services.getRemoteMetadataMap().get(uuid), dataSetMetadata); } @Test public void testFetchMetadataWhenDataSetLookupServicesReturnsAnError() throws Exception { final String uuid = "uuid"; final DataSetClientServices services = makeDataSetClientServices(clientDataSetManager, dataSetLookupServicesCallerMock); when(clientDataSetManager.getDataSetMetadata(uuid)).thenReturn(null); doThrow(Exception.class).when(dataSetLookupServices).lookupDataSetMetadata(any()); services.fetchMetadata(uuid, makeDataSetMetadataCallback()); assertFalse(isDataSetMetadataCallbackCalled()); assertFalse(isDataSetMetadataNotFoundCallbackCalled()); assertTrue(isDataSetMetadataOnErrorCallbackCalled()); assertNull(services.getRemoteMetadataMap().get(uuid)); } private DataSetMetadataCallback makeDataSetMetadataCallback() { return new DataSetMetadataCallback() { @Override public void callback(final DataSetMetadata metadata) { callbackCalled(); } @Override public void notFound() { notFoundCalled(); } @Override public boolean onError(final ClientRuntimeError error) { onErrorCalled(); return false; } }; } private void onErrorCalled() { isOnErrorCalled = true; } private void notFoundCalled() { isNotFoundCalled = true; } private void callbackCalled() { isCallbackCalled = true; } public boolean isDataSetMetadataCallbackCalled() { return isCallbackCalled; } public boolean isDataSetMetadataNotFoundCallbackCalled() { return isNotFoundCalled; } public boolean isDataSetMetadataOnErrorCallbackCalled() { return isOnErrorCalled; } private DataSetClientServices makeDataSetClientServices(final ClientDataSetManager clientDataSetManager, final CallerMock dataSetLookupServicesCallerMock) { return new DataSetClientServices(clientDataSetManager, null, null, null, null, null, null, dataSetLookupServicesCallerMock, null, null); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-dataset-editor jar Dashbuilder Data Set Editor com.google.gwt gwt-user provided org.jboss.errai errai-common org.jboss.errai errai-ioc org.jboss.errai errai-bus org.uberfire uberfire-api org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-client-api org.uberfire uberfire-workbench-client org.uberfire uberfire-commons-editor-api org.uberfire uberfire-commons-editor-client org.uberfire uberfire-widgets-commons org.dashbuilder dashbuilder-services-api org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-common-client org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-displayer-client org.dashbuilder dashbuilder-widgets com.google.gwt.gwtmockito gwtmockito test org.uberfire uberfire-testing-utils test src/main/java src/main/resources ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/perspectives/DataSetAuthoringPerspective.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.perspectives; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.MultiListWorkbenchPanelPresenter; import org.uberfire.client.workbench.panels.impl.MultiTabWorkbenchPanelPresenter; import org.uberfire.client.workbench.panels.impl.SimpleWorkbenchPanelPresenter; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.CompassPosition; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PanelDefinitionImpl; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import javax.enterprise.context.ApplicationScoped; /** *

The authoring perspective for the management of data sets using the UI.

*

Provides:

*
    *
  • The Data Set Explorer widget on the left area.
  • *
  • The Data Set Authoring Home widget on the center area.
  • *
* * @since 0.3.0 */ @ApplicationScoped @WorkbenchPerspective(identifier = "DataSetAuthoringPerspective") public class DataSetAuthoringPerspective { @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(MultiListWorkbenchPanelPresenter.class.getName()); perspective.setName("Data Set Authoring"); perspective.getRoot().addPart(new PartDefinitionImpl(new DefaultPlaceRequest("DataSetAuthoringHome"))); final PanelDefinition west = new PanelDefinitionImpl(MultiListWorkbenchPanelPresenter.class.getName()); west.setWidth(350); west.setMinWidth(300); west.addPart(new PartDefinitionImpl(new DefaultPlaceRequest("DataSetDefExplorer"))); perspective.getRoot().insertChild( CompassPosition.WEST, west ); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants.java ================================================ package org.dashbuilder.dataset.editor.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; import com.google.gwt.i18n.client.Messages; public interface DataSetAuthoringConstants extends Messages { public static final DataSetAuthoringConstants INSTANCE = GWT.create(DataSetAuthoringConstants.class); String homeTitle(); String creationWizardTitle(); String dataSetCount(int count); String nextSteps(); String defineA(); String newDataSet(); String toFetchYourDataFromExtSystem(); String createDataDisplayers(); String createDashboards(); String editorTitleGeneric(); String editorTitle(String name, String type); String validationOk(); String validationFailed(); String dataSetNotFound(); String saving(); String savedOk(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetAuthoringHomePresenter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.screens; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.editor.client.resources.i18n.DataSetAuthoringConstants; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.kie.soup.commons.validation.PortablePreconditions; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberView; import org.uberfire.lifecycle.OnStartup; @WorkbenchScreen(identifier = "DataSetAuthoringHome") @Dependent public class DataSetAuthoringHomePresenter { public interface View extends UberView { void setDataSetCount(int n); } View view; PlaceManager placeManager; DataSetClientServices clientServices; int dataSetCount = 0; @Inject public DataSetAuthoringHomePresenter(final View view, final PlaceManager placeManager, final DataSetClientServices clientServices) { this.view = view; this.placeManager = placeManager; this.clientServices = clientServices; } @OnStartup public void init() { clientServices.getPublicDataSetDefs(dataSetDefs -> { dataSetCount = dataSetDefs.size(); view.setDataSetCount(dataSetCount); }); } @WorkbenchPartTitle public String getTitle() { return DataSetAuthoringConstants.INSTANCE.homeTitle(); } @WorkbenchPartView public UberView getView() { return view; } public void newDataSet() { placeManager.goTo("DataSetDefWizard"); } public int getDataSetCount() { return dataSetCount; } // Be aware of data set lifecycle events void onDataSetDefRegisteredEvent(@Observes DataSetDefRegisteredEvent event) { PortablePreconditions.checkNotNull("DataSetDefRegisteredEvent", event); view.setDataSetCount(++dataSetCount); } void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { PortablePreconditions.checkNotNull("DataSetDefRemovedEvent", event); view.setDataSetCount(--dataSetCount); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetAuthoringHomeView.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.screens; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Hyperlink; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.editor.client.resources.i18n.DataSetAuthoringConstants; @Dependent public class DataSetAuthoringHomeView extends Composite implements DataSetAuthoringHomePresenter.View { interface DataSetEditorViewBinder extends UiBinder {} private static DataSetEditorViewBinder uiBinder = GWT.create(DataSetEditorViewBinder.class); @UiField HTMLPanel initialViewPanel; @UiField Hyperlink newDataSetLink; @UiField HTML dataSetCountText; DataSetAuthoringHomePresenter presenter; public DataSetAuthoringHomeView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(DataSetAuthoringHomePresenter presenter) { this.presenter = presenter; } public void setDataSetCount(int n) { dataSetCountText.setText(DataSetAuthoringConstants.INSTANCE.dataSetCount(n)); } @UiHandler("newDataSetLink") public void onNewDataSetClicked(ClickEvent event) { presenter.newDataSet(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetAuthoringHomeView.ui.xml ================================================ .initialViewPanel { margin: 50px; } .dataSetCountLabel { margin-bottom: 20px; } .defineA { float: left; margin-left: 25px; } .newDataSet { float: left; margin-right: 5px; margin-left: 5px; cursor: pointer; } .toFetchYourDataFromExtSystem { margin-left: 5px; } .nextSteps { margin: 5px; } .step { margin: 5px; margin-left: 25px; } .clear { clear: both; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefEditorPresenter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.screens; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflowFactory; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.DataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.backend.EditDataSetDef; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.editor.client.resources.i18n.DataSetAuthoringConstants; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.service.DataSetDefVfsServices; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.ErrorCallback; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.backend.vfs.Path; import org.uberfire.client.annotations.WorkbenchEditor; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartTitleDecoration; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.events.ChangeTitleWidgetEvent; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import org.uberfire.ext.editor.commons.client.BaseEditor; import org.uberfire.ext.editor.commons.client.file.popups.SavePopUpPresenter; import org.uberfire.ext.editor.commons.file.DefaultMetadata; import org.uberfire.ext.editor.commons.service.support.SupportsCopy; import org.uberfire.ext.editor.commons.service.support.SupportsDelete; import org.uberfire.lifecycle.OnClose; import org.uberfire.lifecycle.OnMayClose; import org.uberfire.lifecycle.OnStartup; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.events.NotificationEvent; import org.uberfire.workbench.model.menu.Menus; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.uberfire.ext.editor.commons.client.menu.MenuItems.COPY; import static org.uberfire.ext.editor.commons.client.menu.MenuItems.DELETE; import static org.uberfire.ext.editor.commons.client.menu.MenuItems.SAVE; import static org.uberfire.ext.editor.commons.client.menu.MenuItems.VALIDATE; import static org.uberfire.workbench.events.NotificationEvent.NotificationType.ERROR; import static org.uberfire.workbench.events.NotificationEvent.NotificationType.SUCCESS; @Dependent @WorkbenchEditor(identifier = "DataSetDefEditor", supportedTypes = {DataSetDefType.class}, priority = Integer.MAX_VALUE) public class DataSetDefEditorPresenter extends BaseEditor { @Inject SyncBeanManager beanManager; @Inject DataSetEditorWorkflowFactory workflowFactory; @Inject Caller services; @Inject PlaceManager placeManager; @Inject DataSetDefType resourceType; @Inject ErrorPopupPresenter errorPopupPresenter; @Inject SavePopUpPresenter savePopUpPresenter; @Inject public DataSetDefScreenView view; DataSetEditWorkflow workflow; @OnStartup public void onStartup(final ObservablePath path, final PlaceRequest place) { super.baseView = view; init(path, place, resourceType, true, false, VALIDATE, SAVE, COPY, DELETE); } @WorkbenchPartTitleDecoration public IsWidget getTitle() { return super.getTitle(); } @WorkbenchPartTitle public String getTitleText() { return buildTitle(); } protected String buildTitle() { if (getDataSetDef() == null) { return DataSetAuthoringConstants.INSTANCE.editorTitleGeneric(); } else { String type = getDataSetDef().getProvider().getName(); return DataSetAuthoringConstants.INSTANCE.editorTitle(getDataSetDef().getName(), type); } } @WorkbenchMenu public void getMenus(final Consumer menusConsumer) { super.getMenus(menusConsumer); } @WorkbenchPartView public Widget getWidget() { return view.asWidget(); } @OnMayClose public boolean onMayClose() { workflow.flush(); return super.mayClose(getCurrentModelHash()); } @OnClose public void onClose() { disposeWorkflow(); } @Override protected void loadContent() { try { services.call(loadCallback, errorCallback).load(versionRecordManager.getCurrentPath()); } catch (final Exception e) { // Edit only the definition, so user can fix the wrong attributes, if any. loadDefinition(); } } private void loadDefinition() { services.call(getDefinitionCallback, getDefinitionErrorCallback).get(versionRecordManager.getCurrentPath()); } public DataSetDef getDataSetDef() { return workflow != null ? workflow.getDataSetDef() : null; } private void testDataSet() { assert workflow != null; workflow.testDataSet(new DataSetEditorWorkflow.TestDataSetCallback() { @Override public void onSuccess(final DataSet dataSet) { edit(dataSet); } @Override public void onError(final ClientRuntimeError error) { showError(error); } }); } private void edit(final DataSetDef dataSetDef, final List columnDefs) { final DataSetProviderType type = dataSetDef.getProvider() != null ? dataSetDef.getProvider() : null; workflow = workflowFactory.edit(type); view.setWidget(workflow); workflow.edit(dataSetDef, columnDefs).showPreviewTab(); } private void edit(final DataSet dataset) { if (dataset != null) { final DataSetDef dataSetDef = workflow.getDataSetDef(); List columns = dataset.getColumns(); if (columns != null && !columns.isEmpty()) { // Obtain all data columns available from the resulting data set. List columnDefs = new ArrayList<>(columns.size()); for (final DataColumn column : columns) { columnDefs.add(new DataColumnDef(column.getId(), column.getColumnType())); } edit(dataSetDef, columnDefs); } else { showError("Data set has no columns"); } } else { showError("Data set is empty."); } } @Override protected void onValidate(final Command callFinished) { workflow.flush(); if (!workflow.hasErrors()) { notification.fire(new NotificationEvent(DataSetAuthoringConstants.INSTANCE.validationOk(), SUCCESS)); } else { notification.fire(new NotificationEvent(DataSetAuthoringConstants.INSTANCE.validationFailed(), ERROR)); } callFinished.execute(); } @Override protected void save() { workflow.flush(); if (!workflow.hasErrors()) { savePopUpPresenter.show(versionRecordManager.getCurrentPath(), commitMessage -> { final DataSetDef def = getDataSetDef(); services.call(new RemoteCallback() { @Override public void callback(final Path path) { DataSetDefEditorPresenter.this.getSaveSuccessCallback(getCurrentModelHash()).callback(path); placeManager.closePlace(DataSetDefEditorPresenter.this.place); } }, errorCallback) .save(def, commitMessage); } ); concurrentUpdateSessionInfo = null; } } public int getCurrentModelHash() { if (getDataSetDef() == null) { return 0; } return getDataSetDef().hashCode(); } public void disposeWorkflow() { if (workflow != null) { workflowFactory.dispose(workflow); } } RemoteCallback getDefinitionCallback = result -> { load(result, result != null ? result.getColumns() : null); }; RemoteCallback loadCallback = result -> { load(result != null ? result.getDefinition() : null, result != null ? result.getColumns() : null); }; ErrorCallback errorCallback = (message, throwable) -> { // Edit only the definition, so user can fix the wrong attributes, if any. loadDefinition(); return false; }; ErrorCallback getDefinitionErrorCallback = new ErrorCallback() { @Override public boolean error(Message message, Throwable throwable) { view.hideBusyIndicator(); showError(new ClientRuntimeError(throwable)); return false; } }; protected void load(final DataSetDef dataSetDef, List columns) { if (dataSetDef == null) { view.hideBusyIndicator(); showError(DataSetAuthoringConstants.INSTANCE.dataSetNotFound()); } else { changeTitleNotification.fire(new ChangeTitleWidgetEvent(place, buildTitle())); view.hideBusyIndicator(); edit(dataSetDef, columns); setOriginalHash(getCurrentModelHash()); } } protected Caller getDeleteServiceCaller() { return services; } protected Caller getCopyServiceCaller() { return services; } private void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { placeManager.closePlace(place); } void showError(final ClientRuntimeError error) { final String message = error.getCause() != null ? error.getCause() : error.getMessage(); showError(message); } void showError(final String message) { errorPopupPresenter.showMessage(message); } /************************************************************* ** CDI EVENT HANDLING METHODS ** *************************************************************/ void onTestEvent(@Observes TestDataSetRequestEvent testDataSetRequestEvent) { checkNotNull("testDataSetRequestEvent", testDataSetRequestEvent); if (testDataSetRequestEvent.getContext().equals(workflow)) { if (!workflow.hasErrors()) { testDataSet(); } } } void onCancelEvent(@Observes CancelRequestEvent cancelEvent) { checkNotNull("cancelEvent", cancelEvent); if (cancelEvent.getContext().equals(workflow)) { workflow.clear(); } } void onErrorEvent(@Observes ErrorEvent errorEvent) { checkNotNull("errorEvent", errorEvent); if (errorEvent.getClientRuntimeError() != null) { showError(errorEvent.getClientRuntimeError()); } else if (errorEvent.getMessage() != null) { showError(errorEvent.getMessage()); } } void onTabChangedEvent(@Observes TabChangedEvent tabChangedEvent) { checkNotNull("tabChangedEvent", tabChangedEvent); if (tabChangedEvent.getContext().equals(workflow.getEditor())) { workflow.clearButtons(); String tabId = tabChangedEvent.getTabId(); if (tabId != null && DataSetEditor.TAB_CONFIGURATION.equals(tabId)) { workflow.showTestButton(); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefExplorerScreen.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.screens; import java.util.function.Consumer; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.widgets.dataset.event.EditDataSetEvent; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.explorer.DataSetExplorer; import org.dashbuilder.client.widgets.resources.i18n.DataSetExplorerConstants; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.service.DataSetDefVfsServices; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.uberfire.backend.vfs.Path; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import org.uberfire.lifecycle.OnClose; import org.uberfire.lifecycle.OnStartup; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; import org.uberfire.workbench.events.NotificationEvent; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.Menus; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * @since 0.3.0 */ @WorkbenchScreen(identifier = "DataSetDefExplorer") @Dependent public class DataSetDefExplorerScreen { private Menus menu = null; @Inject PlaceManager placeManager; @Inject Caller services; @Inject Event notification; @Inject DataSetExplorer explorerWidget; @Inject ErrorPopupPresenter errorPopupPresenter; @OnStartup public void onStartup(PlaceRequest placeRequest) { this.menu = makeMenuBar(); explorerWidget.show(); } @OnClose public void onClose() { } @WorkbenchPartTitle public String getTitle() { return DataSetExplorerConstants.INSTANCE.title(); } @WorkbenchPartView public IsWidget getView() { return explorerWidget; } @WorkbenchMenu public void getMenus(final Consumer menusConsumer) { menusConsumer.accept(menu); } private Menus makeMenuBar() { return MenuFactory .newTopLevelMenu(DataSetExplorerConstants.INSTANCE.newDataSet()) .respondsWith(this::newDataSet) .endMenu() .build(); } void newDataSet() { placeManager.tryClosePlace(new DefaultPlaceRequest("DataSetDefWizard"), () -> { placeManager.goTo("DataSetDefWizard"); }); } private void showError(final ClientRuntimeError error) { final String message = error.getCause() != null ? error.getCause() : error.getMessage(); showError(message); } private void showError(final String message) { errorPopupPresenter.showMessage(message); } void onEditDataSetEvent(@Observes EditDataSetEvent event) { checkNotNull("event", event); services.call(new RemoteCallback() { public void callback(Path path) { placeManager.goTo(new PathPlaceRequest(path)); } }).resolve(event.getDef()); } void onErrorEvent(@Observes ErrorEvent errorEvent) { checkNotNull("errorEvent", errorEvent); if (errorEvent.getClientRuntimeError() != null) { showError(errorEvent.getClientRuntimeError()); } else if (errorEvent.getMessage() != null) { showError(errorEvent.getMessage()); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefScreenView.java ================================================ package org.dashbuilder.dataset.editor.client.screens; import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.ext.editor.commons.client.BaseEditorView; public interface DataSetDefScreenView extends BaseEditorView, IsWidget { void setWidget(IsWidget widget); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefScreenViewImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.screens; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.uberfire.ext.editor.commons.client.BaseEditorViewImpl; import javax.enterprise.context.Dependent; @Dependent public class DataSetDefScreenViewImpl extends BaseEditorViewImpl implements DataSetDefScreenView { final FlowPanel mainPanel = new FlowPanel(); public DataSetDefScreenViewImpl() { } @Override public Widget asWidget() { return mainPanel; } @Override public void setWidget(final IsWidget widget) { mainPanel.clear(); mainPanel.add(widget); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefType.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.screens; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.backend.vfs.Path; import org.uberfire.client.workbench.type.ClientResourceType; import org.uberfire.workbench.category.Category; import org.uberfire.workbench.category.Others; @ApplicationScoped public class DataSetDefType implements ClientResourceType { private Category category; public DataSetDefType() { } @Inject public DataSetDefType(final Others category) { this.category = category; } @Override public Category getCategory() { return this.category; } @Override public String getShortName() { return "dataset"; } @Override public String getDescription() { return "Data set"; } @Override public IsWidget getIcon() { return null; } @Override public String getPrefix() { return ""; } @Override public String getSuffix() { return "dset"; } @Override public int getPriority() { return 0; } @Override public String getSimpleWildcardPattern() { return "*.dset"; } @Override public boolean accept(final Path path) { return path.getFileName().endsWith(getSuffix()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefWizardScreen.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.editor.client.screens; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflowFactory; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.DataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.DataSetProviderTypeWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.DataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.event.*; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.editor.client.resources.i18n.DataSetAuthoringConstants; import org.dashbuilder.dataset.service.DataSetDefVfsServices; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.ErrorCallback; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.backend.vfs.Path; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import org.uberfire.ext.editor.commons.client.file.popups.SavePopUpPresenter; import org.uberfire.ext.widgets.common.client.common.BusyPopup; import org.uberfire.lifecycle.OnClose; import org.uberfire.lifecycle.OnMayClose; import org.uberfire.lifecycle.OnStartup; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.events.NotificationEvent; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import java.util.ArrayList; import java.util.List; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; @WorkbenchScreen(identifier = "DataSetDefWizard") @Dependent public class DataSetDefWizardScreen { SyncBeanManager beanManager; DataSetEditorWorkflowFactory workflowFactory; Caller services; DataSetClientServices clientServices; Event notification; PlaceManager placeManager; ErrorPopupPresenter errorPopupPresenter; public DataSetDefScreenView view; PlaceRequest placeRequest; Command nextCommand; Integer originalHash = 0; DataSetEditorWorkflow currentWorkflow; SavePopUpPresenter savePopUpPresenter; @Inject public DataSetDefWizardScreen(final SyncBeanManager beanManager, final DataSetEditorWorkflowFactory workflowFactory, final Caller services, final DataSetClientServices clientServices, final Event notification, final PlaceManager placeManager, final ErrorPopupPresenter errorPopupPresenter, final SavePopUpPresenter savePopUpPresenter, final DataSetDefScreenView view) { this.beanManager = beanManager; this.workflowFactory = workflowFactory; this.services = services; this.clientServices = clientServices; this.notification = notification; this.placeManager = placeManager; this.errorPopupPresenter = errorPopupPresenter; this.savePopUpPresenter = savePopUpPresenter; this.view = view; } @WorkbenchPartTitle public String getTitle() { return DataSetAuthoringConstants.INSTANCE.creationWizardTitle(); } @WorkbenchPartView public IsWidget getView() { return view; } @OnStartup public void init(PlaceRequest placeRequest) { this.placeRequest = placeRequest; providerTypeEdition(); } @OnMayClose public boolean onMayClose() { return mayClose(); } @OnClose public void onClose() { disposeCurrentWorkflow(); } public void setOriginalHash(Integer originalHash) { this.originalHash = originalHash; } public int getCurrentModelHash() { if (getDataSetDef() == null) { return 0; } return getDataSetDef().hashCode(); } public DataSetDef getDataSetDef() { return currentWorkflow != null ? currentWorkflow.getDataSetDef() : null; } public boolean mayClose() { try { // Flush the current workflow state if (currentWorkflow != null) { currentWorkflow.flush(); } } catch (Exception e) { // Ignore. The provider type selection workflow stage throws an error // due to the dataset def being in partial creation state. } Integer currentHash = getCurrentModelHash(); if (isDirty(currentHash)) { return view.confirmClose(); } else { return true; } } public boolean isDirty(Integer currentHash) { if (originalHash == null) { return currentHash != null; } else { return !originalHash.equals(currentHash); } } private void providerTypeEdition() { final DataSetDef dataSetDef = new DataSetDef(); final DataSetProviderTypeWorkflow providerTypeWorkflow = workflowFactory.providerType(); this.nextCommand = () -> onProviderTypeSelected(providerTypeWorkflow); // First step, provider type selection. providerTypeWorkflow.edit(dataSetDef).providerTypeEdition(); setCurrentWorkflow(providerTypeWorkflow); setOriginalHash(getCurrentModelHash()); } void onProviderTypeSelected(final DataSetProviderTypeWorkflow providerTypeWorkflow) { final DataSetProviderType selectedProviderType = providerTypeWorkflow.getProviderType(); try { clientServices.newDataSet(selectedProviderType, this::basicAttributesEdition); } catch (final Exception e) { showError(e.getCause() != null ? e.getCause().getMessage() : e.getMessage()); } } private void setCurrentWorkflow(final DataSetEditorWorkflow w) { this.currentWorkflow = w; view.setWidget(w); } private void disposeCurrentWorkflow() { if (this.currentWorkflow != null) { workflowFactory.dispose(this.currentWorkflow); this.currentWorkflow = null; } } private void basicAttributesEdition(final DataSetDef typedDataSetDef) { final DataSetProviderType type = typedDataSetDef.getProvider() != null ? typedDataSetDef.getProvider() : null; final DataSetBasicAttributesWorkflow basicAttributesWorkflow = workflowFactory.basicAttributes(type); basicAttributesWorkflow.edit(typedDataSetDef).basicAttributesEdition().showBackButton().showTestButton(); setCurrentWorkflow(basicAttributesWorkflow); setOriginalHash(getCurrentModelHash()); } private void testDataSet() { assert currentWorkflow != null; currentWorkflow.testDataSet(new DataSetEditorWorkflow.TestDataSetCallback() { @Override public void onSuccess(final DataSet dataSet) { completeEdition(currentWorkflow.getDataSetDef(), dataSet); } @Override public void onError(final ClientRuntimeError error) { showError(error); } }); } public void completeEdition(final DataSetDef dataSetDef, final DataSet dataset) { if (dataset != null) { this.nextCommand = this::save; List columns = dataset.getColumns(); if (columns != null && !columns.isEmpty()) { // Obtain all data columns available from the resulting data set. List columnDefs = new ArrayList<>(columns.size()); for (final DataColumn column : columns) { columnDefs.add(new DataColumnDef(column.getId(), column.getColumnType())); } // Delegate edition to the dataSetEditWorkflow. final DataSetProviderType type = dataSetDef.getProvider() != null ? dataSetDef.getProvider() : null; final DataSetEditWorkflow editWorkflow = workflowFactory.edit(type); editWorkflow.edit(dataSetDef, columnDefs) .showPreviewTab() .showBackButton() .showNextButton(); setCurrentWorkflow(editWorkflow); } else { showError("Data set has no columns"); } } else { showError("Data set is empty."); } } protected void save() { final DataSetDef dataSetDef = currentWorkflow.getDataSetDef(); savePopUpPresenter.show(message -> onSave(dataSetDef, message)); } void onSave(final DataSetDef dataSetDef, final String message) { BusyPopup.showMessage(DataSetAuthoringConstants.INSTANCE.saving()); services.call(saveSuccessCallback, errorCallback).save(dataSetDef, message); placeManager.goTo("DataSetAuthoringHome"); } RemoteCallback saveSuccessCallback = new RemoteCallback() { @Override public void callback(Path path) { disposeCurrentWorkflow(); BusyPopup.close(); setOriginalHash(0); notification.fire(new NotificationEvent(DataSetAuthoringConstants.INSTANCE.savedOk())); placeManager.closePlace(placeRequest); } }; ErrorCallback errorCallback = (message, throwable) -> { BusyPopup.close(); showError(new ClientRuntimeError(throwable)); return false; }; void showError(final ClientRuntimeError error) { final String message = error.getCause() != null ? error.getCause() : error.getMessage(); showError(message); } void showError(final String message) { errorPopupPresenter.showMessage(message); } /************************************************************* ** CDI EVENT HANDLING METHODS ** *************************************************************/ void onTestEvent(@Observes TestDataSetRequestEvent testDataSetRequestEvent) { checkNotNull("testDataSetRequestEvent", testDataSetRequestEvent); if (testDataSetRequestEvent.getContext().equals(currentWorkflow)) { if (!currentWorkflow.hasErrors()) { testDataSet(); } } } void onSaveEvent(@Observes SaveRequestEvent saveEvent) { checkNotNull("saveEvent", saveEvent); if (saveEvent.getContext().equals(currentWorkflow)) { if (this.nextCommand != null && !currentWorkflow.hasErrors()) { this.nextCommand.execute(); } } } void onCancelEvent(@Observes CancelRequestEvent cancelEvent) { checkNotNull("cancelEvent", cancelEvent); if (cancelEvent.getContext().equals(currentWorkflow) && mayClose()) { providerTypeEdition(); } } void onErrorEvent(@Observes ErrorEvent errorEvent) { checkNotNull("errorEvent", errorEvent); if (errorEvent.getClientRuntimeError() != null) { showError(errorEvent.getClientRuntimeError()); } else if (errorEvent.getMessage() != null) { showError(errorEvent.getMessage()); } } void onTabChangedEvent(@Observes TabChangedEvent tabChangedEvent) { checkNotNull("tabChangedEvent", tabChangedEvent); try { // This event should only be fired when worklow is an instance of the DataSetEditWorkflow, as it uses the main tabbed editor. if (tabChangedEvent.getContext().equals(((DataSetEditWorkflow) currentWorkflow).getEditor())) { currentWorkflow.clearButtons(); String tabId = tabChangedEvent.getTabId(); if (tabId != null && DataSetEditor.TAB_CONFIGURATION.equals(tabId)) { currentWorkflow.showTestButton(); } else { currentWorkflow.showBackButton().showNextButton(); } } } catch (final ClassCastException e) { // Skip event. } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/DataSetEditor.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants.properties ================================================ homeTitle=Data Set Authoring Home creationWizardTitle=Data Set Creation Wizard dataSetCount=There are {0} data sets available nextSteps=Next steps defineA=1. Define a newDataSet=new data set toFetchYourDataFromExtSystem=to fetch your data from an external storage system createDataDisplayers=2. Create displayers to visualize data from your newly created data sets createDashboards=3. Create new dashboards to organize and coordinate your displayers editorTitleGeneric=Data Set Editor editorTitle=Data Set Editor [{0} ({1})] validationOk=Data set definition is OK validationFailed=Data set definition has errors dataSetNotFound=Data set definition not found saving=Saving... savedOk=Data set definition saved successfully ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants_de.properties ================================================ homeTitle=Datensatz-Authoring Home creationWizardTitle=Assistent zum Anlegen von Datensätzen dataSetCount=Es sind {0} Datensätze verfügbar nextSteps=Die nächsten Schritte defineA=1. Definieren eines newDataSet=neuen Datensätze toFetchYourDataFromExtSystem=zum Abruf von Daten von einem externen Speichersystem createDataDisplayers=2. Erstellen von Displayern zur Visualisierung neu angelegter Datensätze createDashboards=3. Erstellen neuer Dashboards zur Organisation und Koordination Ihrer Displayer editorTitleGeneric=Datensatz-Editor editorTitle=Datensatz-Editor [{0} ({1})] validationOk=Datensatz-Definition ist OK validationFailed=Datensatz-Definition hat Fehler dataSetNotFound=Datensatz-Definition nicht gefunden saving=Speichern ... savedOk=Datensatz-Definition erfolgreich gespeichert ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants_es.properties ================================================ homeTitle=Inicio de la autoría de conjuntos de datos creationWizardTitle=Asistente de creación de conjuntos de datos dataSetCount=Hay {0} conjuntos de datos disponibles nextSteps=Próximos pasos defineA=1. Definir un newDataSet=nuevo conjunto de datos toFetchYourDataFromExtSystem=para obtener sus datos de un sistema de almacenamiento externo createDataDisplayers=2. Crear visualizadores para ver los datos de los conjuntos de datos creados recientemente createDashboards=3. Crear nuevos cuadros de mando para organizar y coordinar sus visualizadores editorTitleGeneric=Editor de conjuntos de datos editorTitle=Editor de conjuntos de datos [{0} ({1})] validationOk=La definición del conjunto de datos es correcta validationFailed=La definición del conjunto de datos tiene errores dataSetNotFound=No se encuentra la definición del conjunto de datos saving=Guardando… savedOk=La definición del conjunto de datos se guardó correctamente ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants_fr.properties ================================================ homeTitle=Page d''accueil de création d''ensembles de données creationWizardTitle=Assistant de création d''ensembles de données dataSetCount={0} ensembles de données sont disponibles nextSteps=Étapes suivantes defineA=1. Définir un newDataSet=nouvel ensemble de données toFetchYourDataFromExtSystem=pour extraire vos données d''un système de stockage externe createDataDisplayers=2. Créer des afficheurs pour visualiser les données de vos nouveaux ensembles de données createDashboards=3. Créer des tableaux de bord pour organiser et coordonner vos afficheurs editorTitleGeneric=Éditeur d''ensembles de données editorTitle=Éditeur d''ensembles de données [{0} ({1})] validationOk=La définition de l''ensemble de données est correcte validationFailed=La définition de l''ensemble de données comporte des erreurs dataSetNotFound=La définition de l''ensemble de données est introuvable saving=Enregistrement… savedOk=La définition de l''ensemble de données a été enregistrée ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants_it.properties ================================================ homeTitle=Pagina principale dell''autore del set di dati creationWizardTitle=Wizard di creazione del set di dati dataSetCount=Sono disponibili {0} set di dati nextSteps=Passaggi successivi defineA=1. Definisci un newDataSet=nuevo set di dati toFetchYourDataFromExtSystem=per recuperare i tuoi dati da un sistema di archiviazione esterno createDataDisplayers=2. Crea display per visualizzare i dati dei tuoi nuovi set di dati createDashboards=3. Crea nuovi dashboard per organizzare e coordinare i tuoi display editorTitleGeneric=Editor del set di dati editorTitle=Editor del set di dati [{0} ({1})] validationOk=La definizione del set di dati è corretta validationFailed=La definizione del set di dati contiene errori dataSetNotFound=Definizione del set di dati non trovata saving=Salvataggio... savedOk=Definizione del set di dati salvata con successo ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants_ja.properties ================================================ homeTitle=データセットオーサリングホーム creationWizardTitle=データセット作成ウィザード dataSetCount={0} データセットが利用可能です nextSteps=次のステップ defineA=1.外部ストレージシステムからデータを取得するため newDataSet=新しいデータセット toFetchYourDataFromExtSystem=を定義する createDataDisplayers=2.新しく作成したデータセットからデータを視覚化するためにディスプレイヤーを作成します createDashboards=3.ディスプレイヤーを整理および管理するために新しいダッシュボードを作成します editorTitleGeneric=データセットエディター editorTitle=データセットエディター [{0} ({1})] validationOk=データセット定義は OK です validationFailed=データセット定義にエラーがあります dataSetNotFound=データセット定義が見つかりません saving=保存中... savedOk=データセット定義が正常に保存されました ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants_pt_BR.properties ================================================ homeTitle=Página Principal da Autoría do Data Set creationWizardTitle=Assistente de Criação do Data Set dataSetCount=Existem {0} data sets disponíveis nextSteps=Próximos passos defineA=1. Define um(a) newDataSet=novo data set toFetchYourDataFromExtSystem=para buscar seus dados de um sistema de armazenamento externo createDataDisplayers=2. Cria exibidores para visualizar os dados de seus conjuntos de dados recentemente criados createDashboards=3. Cria novos painéis para organizar e coordenar seus exibidores editorTitleGeneric=Editor de Data Set editorTitle=Editor de Data Set [{0} ({1})] validationOk=Definição de Data Set é OK validationFailed=Definição de data set possui erros dataSetNotFound=Definição de Data set não foi encontrada saving=Salvando... savedOk=Definição de data set salva com sucesso ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/main/resources/org/dashbuilder/dataset/editor/client/resources/i18n/DataSetAuthoringConstants_zh_CN.properties ================================================ homeTitle=数据集编辑主页 creationWizardTitle=数据集创建向导 dataSetCount=有 {0} 个可用的数据集 nextSteps=后续的步骤 defineA=1. 定义 newDataSet=新的数据集 toFetchYourDataFromExtSystem=以从外部存储系统获取数据 createDataDisplayers=2. 创建显示屏显示新创建的数据集中的数据 createDashboards=3. 创建仪表板组织和协调您的数据显示屏 editorTitleGeneric=数据集编辑器 editorTitle=数据集编辑器 [{0} ({1})] validationOk=数据集定义正常 validationFailed=数据集定义有错误 dataSetNotFound=未找到数据集定义 saving=正在保存... savedOk=数据集定义已成功保存 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/test/java/org/dashbuilder/dataset/editor/client/screens/DataSetAuthoringHomePresenterTest.java ================================================ package org.dashbuilder.dataset.editor.client.screens; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.jboss.errai.common.client.api.RemoteCallback; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberView; import java.util.List; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DataSetAuthoringHomePresenterTest { @Mock DataSetAuthoringHomePresenter.View view; @Mock PlaceManager placeManager; @Mock DataSetClientServices dataSetClientServices; private DataSetAuthoringHomePresenter presenter; @Before public void setup() throws Exception { final List dataSetDefList = mock(List.class); when(dataSetDefList.size()).thenReturn(5); doAnswer(new Answer() { @Override public Void answer(InvocationOnMock invocationOnMock) throws Throwable { RemoteCallback> callback = (RemoteCallback>) invocationOnMock.getArguments()[0]; callback.callback(dataSetDefList); return null; } }).when(dataSetClientServices).getPublicDataSetDefs(any(RemoteCallback.class)); // The presenter instance to test. presenter = new DataSetAuthoringHomePresenter(view, placeManager, dataSetClientServices); } @Test public void testInit() { presenter.init(); verify(view, times(1)).setDataSetCount(5); } @Test public void testGetView() { final UberView view = presenter.getView(); assertEquals(this.view, view); } @Test public void testNewDataSet() { presenter.newDataSet(); verify(placeManager, times(1)).goTo("DataSetDefWizard"); } @Test public void testDataSetRegistered() { int count = presenter.getDataSetCount(); presenter.onDataSetDefRegisteredEvent(new DataSetDefRegisteredEvent(null)); assertEquals(presenter.getDataSetCount(), count+1); verify(view).setDataSetCount(count+1); } @Test public void testDataSetRemoved() { int count = presenter.getDataSetCount(); presenter.onDataSetDefRemovedEvent(new DataSetDefRemovedEvent(null)); assertEquals(presenter.getDataSetCount(), count-1); verify(view).setDataSetCount(count-1); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/test/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefEditorPresenterTest.java ================================================ package org.dashbuilder.dataset.editor.client.screens; import java.util.List; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflowFactory; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.DataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.backend.EditDataSetDef; import org.dashbuilder.dataset.client.editor.DataSetDefEditor; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.service.DataSetDefVfsServices; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.backend.vfs.Path; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.events.ChangeTitleWidgetEvent; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import org.uberfire.ext.editor.commons.client.history.VersionRecordManager; import org.uberfire.ext.editor.commons.client.menu.BasicFileMenuBuilder; import org.uberfire.ext.editor.commons.client.validation.DefaultFileNameValidator; import org.uberfire.mocks.CallerMock; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.events.NotificationEvent; 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.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * @since 0.4.0 */ @RunWith(GwtMockitoTestRunner.class) public class DataSetDefEditorPresenterTest { @Mock EventSourceMock changeTitleNotification; @Mock EventSourceMock notification; @Mock VersionRecordManager versionRecordManager; @Mock BasicFileMenuBuilder menuBuilder; @Mock DefaultFileNameValidator fileNameValidator; @Mock PlaceManager placeManager; @Mock PlaceRequest placeRequest; @Mock ObservablePath observablePath; @Mock SyncBeanManager beanManager; @Mock DataSetEditorWorkflowFactory workflowFactory; @Mock DataSetDefType resourceType; @Mock ErrorPopupPresenter errorPopupPresenter; @Mock DataSetDefVfsServices dataSetDefVfsServices; @Mock DataSetDef dataSetDef; @Mock DataSetDefEditor dataSetDefEditor; @Mock DataSetDefScreenView view; Caller services; @InjectMocks private DataSetDefEditorPresenter presenter; final List columns = mock(List.class); final DataSetEditWorkflow editWorkflow = mock(DataSetEditWorkflow.class); @Before public void setup() throws Exception { when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); when(dataSetDef.getColumns()).thenReturn(columns); services = new CallerMock<>(dataSetDefVfsServices); presenter.services = services; presenter.workflow = editWorkflow; final EditDataSetDef editDataSetDef = mock(EditDataSetDef.class); when(editDataSetDef.getDefinition()).thenReturn(dataSetDef); when(editDataSetDef.getColumns()).thenReturn(columns); when(dataSetDefVfsServices.load(any())).thenReturn(editDataSetDef); when(dataSetDefVfsServices.get(any())).thenReturn(dataSetDef); when(workflowFactory.edit(any())).thenReturn(editWorkflow); when(editWorkflow.getDataSetDef()).thenReturn(dataSetDef); when(editWorkflow.getEditor()).thenReturn(dataSetDefEditor); when(editWorkflow.edit(any(), any())).thenReturn(editWorkflow); assertEquals(view.asWidget(), presenter.getWidget()); } @Test public void testOnMayClose() { presenter.loadContent(); when(editWorkflow.getDataSetDef()).thenReturn(mock(DataSetDef.class)); presenter.onMayClose(); verify(view).confirmClose(); assertTrue(presenter.isDirty(presenter.getCurrentModelHash())); } @Test public void testOnClose() throws Exception { presenter.onClose(); verify(workflowFactory).dispose(editWorkflow); } @Test public void testLoadContent() throws Exception { presenter.loadContent(); assertFalse(presenter.isDirty(presenter.getCurrentModelHash())); verify(dataSetDefVfsServices, times(1)).load(any()); verify(changeTitleNotification, times(1)).fire(any(ChangeTitleWidgetEvent.class)); verify(view, times(1)).hideBusyIndicator(); verify(view, times(1)).setWidget(editWorkflow); verify(editWorkflow, times(1)).edit(dataSetDef, columns); verify(editWorkflow, times(1)).showPreviewTab(); } @Test public void testLoadContentNullified() throws Exception { when(dataSetDefVfsServices.load(any())).thenReturn(null); presenter.loadContent(); verify(dataSetDefVfsServices, times(1)).load(any()); verify(errorPopupPresenter, times(1)).showMessage(any()); verify(view, times(1)).hideBusyIndicator(); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testLoadDefinition() throws Exception { final Exception loadContentException = mock(Exception.class); doThrow(loadContentException).when(dataSetDefVfsServices).load(any()); presenter.loadContent(); assertFalse(presenter.isDirty(presenter.getCurrentModelHash())); verify(dataSetDefVfsServices, times(1)).get(any()); verify(view, times(1)).hideBusyIndicator(); verify(view, times(1)).setWidget(editWorkflow); verify(editWorkflow, times(1)).edit(dataSetDef, columns); verify(editWorkflow, times(1)).showPreviewTab(); } @Test public void testGetDataSetDef() { assertEquals(dataSetDef, presenter.getDataSetDef()); } @Test public void testGetDataSetDefNullified() { when(editWorkflow.getDataSetDef()).thenReturn(null); DataSetDef d = presenter.getDataSetDef(); assertNull(d); } @Test public void testOnTestEvent() { TestDataSetRequestEvent event = mock(TestDataSetRequestEvent.class); when(event.getContext()).thenReturn(editWorkflow); when(editWorkflow.hasErrors()).thenReturn(false); presenter.onTestEvent(event); verify(editWorkflow, times(1)).testDataSet(any(DataSetEditorWorkflow.TestDataSetCallback.class)); } @Test public void testOnTestEventWithErrors() { TestDataSetRequestEvent event = mock(TestDataSetRequestEvent.class); when(event.getContext()).thenReturn(editWorkflow); when(editWorkflow.hasErrors()).thenReturn(true); presenter.onTestEvent(event); verify(editWorkflow, times(0)).testDataSet(any(DataSetEditorWorkflow.TestDataSetCallback.class)); } @Test public void testOnValidateSuccess() { when(editWorkflow.hasErrors()).thenReturn(false); presenter.getValidateCommand().execute(); verify(editWorkflow, times(1)).flush(); final ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(NotificationEvent.class); verify(notification, times(1)).fire(dataCaptor.capture()); NotificationEvent ne = dataCaptor.getValue(); assertNotNull(ne); assertEquals(NotificationEvent.NotificationType.SUCCESS, ne.getType()); } @Test public void validateCallbackIsCalled() throws Exception { final Command command = mock(Command.class); presenter.onValidate(command); verify(command).execute(); } @Test public void testOnValidateFailed() { when(editWorkflow.hasErrors()).thenReturn(true); presenter.getValidateCommand().execute(); verify(editWorkflow, times(1)).flush(); final ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(NotificationEvent.class); verify(notification, times(1)).fire(dataCaptor.capture()); NotificationEvent ne = dataCaptor.getValue(); assertNotNull(ne); assertEquals(NotificationEvent.NotificationType.ERROR, ne.getType()); } // TODO: @Test - Do it when SaveOperationService refactored. public void testOnSave() { presenter.save(); } @Test public void testShowError() { final ClientRuntimeError error = mock(ClientRuntimeError.class); when(error.getCause()).thenReturn("errorCause"); presenter.showError(error); verify(errorPopupPresenter, times(1)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); verify(editWorkflow, times(0)).clear(); verify(editWorkflow, times(0)).clearButtons(); verify(editWorkflow, times(0)).showTestButton(); verify(editWorkflow, times(0)).showNextButton(); verify(editWorkflow, times(0)).showBackButton(); verify(editWorkflow, times(0)).edit(any(DataSetDef.class), any(List.class)); } @Test public void testOnCancelEvent() { CancelRequestEvent event = mock(CancelRequestEvent.class); when(event.getContext()).thenReturn(editWorkflow); presenter.onCancelEvent(event); verify(editWorkflow, times(1)).clear(); verify(editWorkflow, times(0)).clearButtons(); verify(editWorkflow, times(0)).showTestButton(); verify(editWorkflow, times(0)).showNextButton(); verify(editWorkflow, times(0)).showBackButton(); verify(editWorkflow, times(0)).edit(any(DataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(0)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testOnErrorEvent() { ErrorEvent event = mock(ErrorEvent.class); when(event.getClientRuntimeError()).thenReturn(null); when(event.getMessage()).thenReturn("errorMessage"); presenter.onErrorEvent(event); verify(editWorkflow, times(0)).clear(); verify(editWorkflow, times(0)).clearButtons(); verify(editWorkflow, times(0)).showTestButton(); verify(editWorkflow, times(0)).showNextButton(); verify(editWorkflow, times(0)).showBackButton(); verify(editWorkflow, times(0)).edit(any(DataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(1)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testOnTabChangedEvent_ConfigurationTab() { TabChangedEvent event = mock(TabChangedEvent.class); when(event.getContext()).thenReturn(dataSetDefEditor); when(event.getTabId()).thenReturn(DataSetEditor.TAB_CONFIGURATION); presenter.onTabChangedEvent(event); verify(editWorkflow, times(1)).clearButtons(); verify(editWorkflow, times(1)).showTestButton(); verify(editWorkflow, times(0)).showNextButton(); verify(editWorkflow, times(0)).showBackButton(); verify(editWorkflow, times(0)).edit(any(DataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(0)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testOnTabChangedEvent_PreviewTab() { TabChangedEvent event = mock(TabChangedEvent.class); when(event.getContext()).thenReturn(dataSetDefEditor); when(event.getTabId()).thenReturn(DataSetEditor.TAB_PREVIEW); presenter.onTabChangedEvent(event); verify(editWorkflow, times(1)).clearButtons(); verify(editWorkflow, times(0)).showTestButton(); verify(editWorkflow, times(0)).showNextButton(); verify(editWorkflow, times(0)).showBackButton(); verify(editWorkflow, times(0)).edit(any(DataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(0)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testOnTabChangedEvent_AdvancedTab() { TabChangedEvent event = mock(TabChangedEvent.class); when(event.getContext()).thenReturn(dataSetDefEditor); when(event.getTabId()).thenReturn(DataSetEditor.TAB_ADVANCED); presenter.onTabChangedEvent(event); verify(editWorkflow, times(1)).clearButtons(); verify(editWorkflow, times(0)).showTestButton(); verify(editWorkflow, times(0)).showNextButton(); verify(editWorkflow, times(0)).showBackButton(); verify(editWorkflow, times(0)).edit(any(DataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(0)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/test/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefExplorerScreenTest.java ================================================ package org.dashbuilder.dataset.editor.client.screens; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.event.EditDataSetEvent; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.explorer.DataSetExplorer; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.service.DataSetDefVfsServices; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.backend.vfs.Path; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import org.uberfire.mocks.CallerMock; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.mvp.impl.PathPlaceRequest; import org.uberfire.workbench.events.NotificationEvent; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefExplorerScreenTest { @Mock PlaceRequest placeRequest; @Mock PlaceManager placeManager; @Mock EventSourceMock notification; @Mock ErrorPopupPresenter errorPopupPresenter; @Mock DataSetExplorer explorerWidget; @Mock DataSetDefVfsServices dataSetDefVfsServices; @Mock Caller services; @InjectMocks DataSetDefExplorerScreen presenter; @Before public void setup() throws Exception { presenter.services = services; assertEquals(explorerWidget, presenter.getView()); doAnswer(invocationOnMock -> { Command callback = (Command ) invocationOnMock.getArguments()[1]; callback.execute(); return null; }).when(placeManager).tryClosePlace(any(), any()); doAnswer(invocationOnMock -> { RemoteCallback callback = (RemoteCallback) invocationOnMock.getArguments()[0]; callback.callback(mock(Path.class)); return null; }).when(services).call(any(RemoteCallback.class)); } @Test public void testNewDataSet() { presenter.newDataSet(); verify(placeManager).tryClosePlace(eq(new DefaultPlaceRequest("DataSetDefWizard")), any(Command.class)); verify(placeManager).goTo("DataSetDefWizard"); } // Cannot mock constructor for PathPlaceRequest, but having the classcast exception when mocking it implies that placeManager#goTo is called.... @Test(expected = ClassCastException.class) public void testOnEditDataSetEvent() { final DataSetDef def = mock(DataSetDef.class); final EditDataSetEvent editDataSetEvent = mock(EditDataSetEvent.class); when(editDataSetEvent.getDef()).thenReturn(def); presenter.onEditDataSetEvent(editDataSetEvent); verify(placeManager, times(1)).goTo(any(PathPlaceRequest.class)); } @Test public void testOnErrorEvent() { final ErrorEvent errorDataSetEvent = mock(ErrorEvent.class); when(errorDataSetEvent.getMessage()).thenReturn("errorMessage"); presenter.onErrorEvent(errorDataSetEvent); verify(errorPopupPresenter, times(1)).showMessage("errorMessage"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/test/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefTypeTest.java ================================================ package org.dashbuilder.dataset.editor.client.screens; import org.junit.Before; import org.junit.Test; import org.uberfire.backend.vfs.Path; import org.uberfire.workbench.category.Others; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class DataSetDefTypeTest { private DataSetDefType tested; @Before public void setup() { tested = new DataSetDefType(new Others()); } @Test public void testIt() { assertEquals("dataset", tested.getShortName()); assertEquals("Data set", tested.getDescription()); assertEquals(null, tested.getIcon()); assertEquals("", tested.getPrefix()); assertEquals("dset", tested.getSuffix()); assertEquals(0, tested.getPriority()); assertEquals("*.dset", tested.getSimpleWildcardPattern()); final Path path = mock(Path.class); when(path.getFileName()).thenReturn("fff.dset"); assertEquals(true, tested.accept(path)); final Path path2 = mock(Path.class); when(path2.getFileName()).thenReturn("fff.mock"); assertEquals(false, tested.accept(path2)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-dataset-editor/src/test/java/org/dashbuilder/dataset/editor/client/screens/DataSetDefWizardScreenTest.java ================================================ package org.dashbuilder.dataset.editor.client.screens; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflowFactory; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.DataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.DataSetProviderTypeWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.SQLDataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.SQLDataSetDefEditor; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.def.DataSetDefFactory; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.service.DataSetDefVfsServices; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.backend.vfs.Path; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import org.uberfire.ext.editor.commons.client.file.popups.SavePopUpPresenter; import org.uberfire.mocks.CallerMock; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.events.NotificationEvent; import java.util.ArrayList; import java.util.List; import static org.jgroups.util.Util.*; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefWizardScreenTest { @Mock EventSourceMock notification; @Mock PlaceManager placeManager; @Mock SyncBeanManager beanManager; @Mock DataSetEditorWorkflowFactory workflowFactory; @Mock DataSetClientServices clientServices; @Mock ErrorPopupPresenter errorPopupPresenter; @Mock DataSetDefScreenView view; @Mock DataSetProviderTypeWorkflow dataSetProviderTypeWorkflow; @Mock SQLDataSetDef dataSetDef; @Mock SQLDataSetDefEditor dataSetDefEditor; @Mock DataSetBasicAttributesWorkflow dataSetBasicAttributesWorkflow; @Mock SQLDataSetEditWorkflow editWorkflow; @Mock DataSetDefVfsServices dataSetDefVfsServices; @Mock SavePopUpPresenter savePopUpPresenter; Caller services; private DataSetDefWizardScreen presenter; @Before public void setup() throws Exception { services = new CallerMock<>( dataSetDefVfsServices ); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(workflowFactory.providerType()).thenReturn(dataSetProviderTypeWorkflow); when(workflowFactory.edit(any(DataSetProviderType.class))).thenReturn(editWorkflow); when(dataSetProviderTypeWorkflow.edit(any(DataSetDef.class))).thenReturn(dataSetProviderTypeWorkflow); when(dataSetProviderTypeWorkflow.providerTypeEdition()).thenReturn(dataSetProviderTypeWorkflow); doAnswer(invocationOnMock -> { RemoteCallback callback = (RemoteCallback) invocationOnMock.getArguments()[1]; callback.callback(dataSetDef); return null; }).when(clientServices).newDataSet(any(DataSetProviderType.class), any(RemoteCallback.class)); doAnswer(invocationOnMock -> { presenter.onClose(); return null; }).when(placeManager).closePlace(any(PlaceRequest.class)); when(dataSetBasicAttributesWorkflow.edit(any(DataSetDef.class))).thenReturn(dataSetBasicAttributesWorkflow); when(dataSetBasicAttributesWorkflow.basicAttributesEdition()).thenReturn(editWorkflow); when(editWorkflow.getDataSetDef()).thenReturn(dataSetDef); when(editWorkflow.edit(any(SQLDataSetDef.class), any(List.class))).thenReturn(editWorkflow); when(editWorkflow.showNextButton()).thenReturn(editWorkflow); when(editWorkflow.showBackButton()).thenReturn(editWorkflow); when(editWorkflow.showTestButton()).thenReturn(editWorkflow); when(editWorkflow.showPreviewTab()).thenReturn(editWorkflow); when(editWorkflow.showConfigurationTab()).thenReturn(editWorkflow); when(editWorkflow.showAdvancedTab()).thenReturn(editWorkflow); when(workflowFactory.basicAttributes(any(DataSetProviderType.class))).thenReturn(dataSetBasicAttributesWorkflow); presenter = new DataSetDefWizardScreen( beanManager, workflowFactory, services, clientServices, notification, placeManager, errorPopupPresenter, savePopUpPresenter, view ); presenter.services = services; } @Test public void testOnMayClose() { presenter.init(null); when(dataSetProviderTypeWorkflow.getDataSetDef()).thenReturn(mock(SQLDataSetDef.class)); presenter.onMayClose(); verify(view).confirmClose(); assertTrue(presenter.isDirty(presenter.getCurrentModelHash())); } @Test public void testOnClose() { presenter.init(PlaceRequest.NOWHERE); DataSetEditorWorkflow currentWorkflow = presenter.currentWorkflow; presenter.onClose(); verify(workflowFactory).dispose(currentWorkflow); assertNull("current workflow null", presenter.currentWorkflow); } @Test public void testShowError() { final ClientRuntimeError error = mock(ClientRuntimeError.class); when(error.getCause()).thenReturn("errorCause"); presenter.showError(error); verify(errorPopupPresenter, times(1)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testInitProviderTypeEdition() { PlaceRequest placeRequest = mock(PlaceRequest.class); presenter.init(placeRequest); assertEquals(dataSetProviderTypeWorkflow, presenter.currentWorkflow); assertFalse(presenter.isDirty(presenter.getCurrentModelHash())); verify(workflowFactory, times(1)).providerType(); verify(view, times(1)).setWidget(any(IsWidget.class)); verify(dataSetProviderTypeWorkflow, times(1)).edit(any(DataSetDef.class)); verify(dataSetProviderTypeWorkflow, times(0)).showNextButton(); verify(dataSetProviderTypeWorkflow, times(0)).showTestButton(); verify(dataSetProviderTypeWorkflow, times(0)).showBackButton(); } @Test public void testOnProviderTypeSelected() throws Exception { when(dataSetProviderTypeWorkflow.getProviderType()).thenReturn(DataSetProviderType.SQL); presenter.onProviderTypeSelected(dataSetProviderTypeWorkflow); assertEquals(dataSetBasicAttributesWorkflow, presenter.currentWorkflow); assertFalse(presenter.isDirty(presenter.getCurrentModelHash())); verify(view, times(1)).setWidget(any(IsWidget.class)); verify(dataSetBasicAttributesWorkflow, times(1)).edit(any(DataSetDef.class)); verify(editWorkflow, times(1)).showTestButton(); verify(editWorkflow, times(1)).showBackButton(); verify(editWorkflow, times(0)).showNextButton(); } @Test public void testOnTestEventWithErrors() { TestDataSetRequestEvent event = mock(TestDataSetRequestEvent.class); when(event.getContext()).thenReturn(dataSetBasicAttributesWorkflow); when(dataSetBasicAttributesWorkflow.hasErrors()).thenReturn(true); presenter.currentWorkflow = dataSetBasicAttributesWorkflow; presenter.onTestEvent(event); verify(dataSetBasicAttributesWorkflow, times(0)).testDataSet(any(DataSetEditorWorkflow.TestDataSetCallback.class)); } @Test public void testOnTestEventAndCompleteEdition() { final DataSet dataSet = mock(DataSet.class); DataColumn col1 = mock(DataColumn.class); when(col1.getId()).thenReturn("col1"); when(col1.getColumnType()).thenReturn(ColumnType.LABEL); DataColumn col2 = mock(DataColumn.class); when(col2.getId()).thenReturn("col2"); when(col2.getColumnType()).thenReturn(ColumnType.LABEL); List columns = new ArrayList(); columns.add(col1); columns.add(col2); when(dataSet.getColumns()).thenReturn(columns); TestDataSetRequestEvent event = mock(TestDataSetRequestEvent.class); when(event.getContext()).thenReturn(dataSetBasicAttributesWorkflow); when(dataSetBasicAttributesWorkflow.hasErrors()).thenReturn(false); when(dataSetBasicAttributesWorkflow.getDataSetDef()).thenReturn(dataSetDef); doAnswer(new Answer() { @Override public Void answer(InvocationOnMock invocationOnMock) throws Throwable { DataSetEditorWorkflow.TestDataSetCallback callback = (DataSetEditorWorkflow.TestDataSetCallback) invocationOnMock.getArguments()[0]; callback.onSuccess(dataSet); return null; } }).when(dataSetBasicAttributesWorkflow).testDataSet(any(DataSetEditorWorkflow.TestDataSetCallback.class)); presenter.currentWorkflow = dataSetBasicAttributesWorkflow; presenter.onTestEvent(event); verify(dataSetBasicAttributesWorkflow, times(1)).testDataSet(any(DataSetEditorWorkflow.TestDataSetCallback.class)); assertEquals(editWorkflow, presenter.currentWorkflow); assertTrue(presenter.isDirty(presenter.getCurrentModelHash())); verify(workflowFactory, times(1)).edit(any(DataSetProviderType.class)); verify(view, times(1)).setWidget(any(IsWidget.class)); final ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(List.class); verify(editWorkflow, times(1)).edit(any(SQLDataSetDef.class), dataCaptor.capture()); List columnsCaptured = dataCaptor.getValue(); assertNotNull(columnsCaptured); assertEquals(2, columnsCaptured.size()); assertEquals("col1", columnsCaptured.get(0).getId()); assertEquals("col2", columnsCaptured.get(1).getId()); verify(editWorkflow, times(1)).showPreviewTab(); verify(editWorkflow, times(1)).showNextButton(); verify(editWorkflow, times(1)).showBackButton(); verify(editWorkflow, times(0)).showTestButton(); } @Test public void testOnSave() { final Path path = mock(Path.class); DataSetDef dataSetDef = DataSetDefFactory.newBeanDataSetDef().buildDef(); PlaceRequest placeRequest = mock(PlaceRequest.class); when(dataSetDefVfsServices.save(any(DataSetDef.class), anyString())).thenReturn(path); when(dataSetProviderTypeWorkflow.getDataSetDef()).thenReturn(dataSetDef); presenter.init(placeRequest); presenter.onSave(dataSetDef, "saveMessage"); verify(placeManager, times(1)).goTo("DataSetAuthoringHome"); verify(notification, times(1)).fire(any(NotificationEvent.class)); verify(placeManager, times(1)).closePlace(any(PlaceRequest.class)); verify(workflowFactory).dispose(dataSetProviderTypeWorkflow); verify(workflowFactory, times(0)).edit(any(DataSetProviderType.class)); assertNull("current workflow null", presenter.currentWorkflow); assertFalse(presenter.isDirty(presenter.getCurrentModelHash())); assertTrue(presenter.mayClose()); } @Test public void testOnCancelEvent() { presenter.currentWorkflow = dataSetBasicAttributesWorkflow; CancelRequestEvent event = mock(CancelRequestEvent.class); when(event.getContext()).thenReturn(dataSetBasicAttributesWorkflow); presenter.onCancelEvent(event); verify(workflowFactory, times(1)).providerType(); verify(workflowFactory, times(0)).edit(any(DataSetProviderType.class)); verify(workflowFactory, times(0)).basicAttributes(any(DataSetProviderType.class)); } @Test public void testOnErrorEvent() { ErrorEvent event = mock(ErrorEvent.class); when(event.getClientRuntimeError()).thenReturn(null); when(event.getMessage()).thenReturn("errorMessage"); presenter.currentWorkflow = dataSetBasicAttributesWorkflow; presenter.onErrorEvent(event); verify(dataSetBasicAttributesWorkflow, times(0)).clear(); verify(dataSetBasicAttributesWorkflow, times(0)).clearButtons(); verify(dataSetBasicAttributesWorkflow, times(0)).showTestButton(); verify(dataSetBasicAttributesWorkflow, times(0)).showNextButton(); verify(dataSetBasicAttributesWorkflow, times(0)).showBackButton(); verify(dataSetBasicAttributesWorkflow, times(0)).edit(any(DataSetDef.class)); verify(errorPopupPresenter, times(1)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testOnTabChangedEvent_ConfigurationTab() { when(editWorkflow.getEditor()).thenReturn(dataSetDefEditor); TabChangedEvent event = mock(TabChangedEvent.class); when(event.getContext()).thenReturn(dataSetDefEditor); when(event.getTabId()).thenReturn(DataSetEditor.TAB_CONFIGURATION); presenter.currentWorkflow = editWorkflow; presenter.onTabChangedEvent(event); verify(editWorkflow, times(1)).clearButtons(); verify(editWorkflow, times(1)).showTestButton(); verify(editWorkflow, times(0)).showNextButton(); verify(editWorkflow, times(0)).showBackButton(); verify(editWorkflow, times(0)).edit(any(SQLDataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(0)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testOnTabChangedEvent_PreviewTab() { when(editWorkflow.getEditor()).thenReturn(dataSetDefEditor); TabChangedEvent event = mock(TabChangedEvent.class); when(event.getContext()).thenReturn(dataSetDefEditor); when(event.getTabId()).thenReturn(DataSetEditor.TAB_PREVIEW); presenter.currentWorkflow = editWorkflow; presenter.onTabChangedEvent(event); verify(editWorkflow, times(1)).clearButtons(); verify(editWorkflow, times(1)).showNextButton(); verify(editWorkflow, times(1)).showBackButton(); verify(editWorkflow, times(0)).showTestButton(); verify(editWorkflow, times(0)).edit(any(SQLDataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(0)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } @Test public void testOnTabChangedEvent_AdvancedTab() { when(editWorkflow.getEditor()).thenReturn(dataSetDefEditor); TabChangedEvent event = mock(TabChangedEvent.class); when(event.getContext()).thenReturn(dataSetDefEditor); when(event.getTabId()).thenReturn(DataSetEditor.TAB_ADVANCED); presenter.currentWorkflow = editWorkflow; presenter.onTabChangedEvent(event); verify(editWorkflow, times(1)).clearButtons(); verify(editWorkflow, times(1)).showNextButton(); verify(editWorkflow, times(1)).showBackButton(); verify(editWorkflow, times(0)).showTestButton(); verify(editWorkflow, times(0)).edit(any(SQLDataSetDef.class), any(List.class)); verify(errorPopupPresenter, times(0)).showMessage(anyString()); verify(view, times(0)).setWidget(any(IsWidget.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-displayer-client jar Dashbuilder Displayer Client org.jboss.errai errai-common org.jboss.errai errai-ioc org.jboss.errai errai-ui provided org.uberfire uberfire-api org.uberfire uberfire-client-api org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-widgets-properties-editor-api com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 org.gwtbootstrap3 gwtbootstrap3-extras org.dashbuilder dashbuilder-services-api org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-json org.dashbuilder dashbuilder-displayer-api org.kie.soup kie-soup-dataset-shared org.dashbuilder dashbuilder-common-client org.dashbuilder dashbuilder-dataset-client org.uberfire uberfire-widgets-commons org.uberfire uberfire-widgets-core-ace org.uberfire uberfire-widgets-properties-editor-client org.uberfire uberfire-testing-utils test org.kie.soup kie-soup-dataset-api test-jar test org.dashbuilder dashbuilder-dataset-client test-jar test com.google.gwt.gwtmockito gwtmockito test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/AbstractDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.OptionalDouble; import java.util.Set; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.ValidationError; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.DateIntervalPattern; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.GroupStrategy; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.export.ExportCallback; import org.dashbuilder.displayer.client.export.ExportFormat; import org.dashbuilder.displayer.client.formatter.ValueFormatter; /** * Base class for implementing custom displayers. *

Any derived class must implement: *

    *
  • The draw(), redraw() & close() methods.
  • *
  • The capture of events coming from the DisplayerListener interface.
  • *
*/ public abstract class AbstractDisplayer implements Displayer { public interface View extends IsWidget { void errorMissingSettings(); void errorMissingHandler(); void showLoading(); void showVisualization(); void clear(); void setId(String id); void errorDataSetNotFound(String uuid); void error(ClientRuntimeError error); void enableRefreshTimer(int seconds); void cancelRefreshTimer(); } public interface Formatter { String formatDate(String pattern, Date d); Date parseDate(String pattern, String d); String formatNumber(String pattern, Number n); String formatDayOfWeek(DayOfWeek dayOfWeek); String formatMonth(Month month); } public interface ExpressionEval { String evalExpression(String value, String expression); } protected DataSet dataSet; protected DataSetHandler dataSetHandler; protected DisplayerSettings displayerSettings; protected DisplayerConstraints displayerConstraints; protected List listenerList = new ArrayList<>(); protected Map> columnSelectionMap = new HashMap<>(); protected Map formatterMap = new HashMap<>(); protected Formatter formatter = null; protected ExpressionEval evaluator = null; protected DataSetFilter currentFilter = null; protected boolean refreshEnabled = true; protected boolean drawn = false; @Override public Widget asWidget() { return getView().asWidget(); } /** * It returns the actual implementation of the View *

- To be provided by the concrete displayer implementation -

*/ public abstract V getView(); /** * It initializes the constraints this displayer conforms to *

- To be provided by the concrete displayer implementation -

*/ public abstract DisplayerConstraints createDisplayerConstraints(); /** * The required logic in charge of rendering the visualization * once the data has been retrieved during a call to draw() *

- To be provided by the concrete displayer implementation -

*/ protected abstract void createVisualization(); /** * The required logic in charge of updating a visualization * once the data has been retrieved during a call to redraw() *

- To be provided by the concrete displayer implementation -

*/ protected abstract void updateVisualization(); public DisplayerConstraints getDisplayerConstraints() { if (displayerConstraints == null) { displayerConstraints = createDisplayerConstraints(); } return displayerConstraints; } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public void setDisplayerSettings(DisplayerSettings displayerSettings) { checkDisplayerSettings(displayerSettings); this.displayerSettings = displayerSettings; } public void checkDisplayerSettings(DisplayerSettings displayerSettings) { DisplayerConstraints constraints = getDisplayerConstraints(); if (displayerConstraints != null) { ValidationError error = constraints.check(displayerSettings); if (error != null) { throw error; } } } public DataSetHandler getDataSetHandler() { return dataSetHandler; } public void setDataSetHandler(DataSetHandler dataSetHandler) { this.dataSetHandler = dataSetHandler; } public Formatter getFormatter() { if (formatter == null) { formatter = new DisplayerGwtFormatter(); } return formatter; } public void setFormatter(Formatter formatter) { this.formatter = formatter; } public ExpressionEval getEvaluator() { if (evaluator == null) { evaluator = new DisplayerGwtExprEval(this); } return evaluator; } public void setEvaluator(ExpressionEval evaluator) { this.evaluator = evaluator; } public void addListener(DisplayerListener... listeners) { for (DisplayerListener listener : listeners) { listenerList.add(listener); } } public String getDisplayerId() { String id = displayerSettings.getUUID(); if (!StringUtils.isBlank(id)) { return id; } id = displayerSettings.getTitle(); if (!StringUtils.isBlank(id)) { int hash = id.hashCode(); return Integer.toString(hash < 0 ? hash*-1 : hash); } return null; } // DRAW & REDRAW @Override public boolean isDrawn() { return drawn; } /** * Draw the displayer by executing first the lookup call to retrieve the target data set */ @Override public void draw() { if (displayerSettings == null) { getView().errorMissingSettings(); } else if (dataSetHandler == null) { getView().errorMissingHandler(); } else if (!isDrawn()) { try { drawn = true; getView().showLoading(); beforeLoad(); beforeDataSetLookup(); dataSetHandler.lookupDataSet(new DataSetReadyCallback() { public void callback(DataSet result) { try { dataSet = result; afterLoad(); afterDataSetLookup(result); createVisualization(); getView().showVisualization(); // Set the id of the container panel so that the displayer can be easily located // by testing tools for instance. String id = getDisplayerId(); if (!StringUtils.isBlank(id)) { getView().setId(id); } // Draw done afterDraw(); } catch (Exception e) { // Give feedback on any initialization error showError(new ClientRuntimeError(e)); } } public void notFound() { getView().errorDataSetNotFound(displayerSettings.getDataSetLookup().getDataSetUUID()); } @Override public boolean onError(final ClientRuntimeError error) { showError(error); return false; } }); } catch (Exception e) { showError(new ClientRuntimeError(e)); } } } /** * Just reload the data set and make the current displayer to redraw. */ @Override public void redraw() { if (!isDrawn()) { draw(); } else { try { beforeLoad(); beforeDataSetLookup(); dataSetHandler.lookupDataSet(new DataSetReadyCallback() { public void callback(DataSet result) { try { dataSet = result; afterDataSetLookup(result); updateVisualization(); // Redraw done afterRedraw(); } catch (Exception e) { // Give feedback on any initialization error showError(new ClientRuntimeError(e)); } } public void notFound() { String uuid = displayerSettings.getDataSetLookup().getDataSetUUID(); getView().errorDataSetNotFound(uuid); handleError("Data set not found: " + uuid); } @Override public boolean onError(final ClientRuntimeError error) { showError(error); requestDraw(); return false; } }); } catch (Exception e) { showError(new ClientRuntimeError(e)); } } } private void requestDraw() { drawn = false; } public void showError(ClientRuntimeError error) { getView().error(error); handleError(error); } /** * Close the displayer */ @Override public void close() { getView().clear(); // Close done afterClose(); } /** * Call back method invoked just before the data set lookup is executed. */ protected void beforeDataSetLookup() { } /** * Call back method invoked just after the data set lookup is executed. */ protected void afterDataSetLookup(DataSet dataSet) { } // REFRESH TIMER @Override public void setRefreshOn(boolean enabled) { boolean changed = enabled != refreshEnabled; refreshEnabled = enabled; if (changed) { updateRefreshTimer(); } } @Override public boolean isRefreshOn() { return refreshEnabled; } protected void updateRefreshTimer() { if (isDrawn()) { int seconds = displayerSettings.getRefreshInterval(); if (refreshEnabled && seconds > 0) { getView().enableRefreshTimer(seconds); } else { getView().cancelRefreshTimer(); } } } // LIFECYCLE CALLBACKS protected void beforeLoad() { for (DisplayerListener listener : listenerList) { listener.onDataLookup(this); } } protected void afterLoad() { for (DisplayerListener listener : listenerList) { listener.onDataLoaded(this); } } protected void afterDraw() { updateRefreshTimer(); for (DisplayerListener listener : listenerList) { listener.onDraw(this); } } protected void afterRedraw() { updateRefreshTimer(); for (DisplayerListener listener : listenerList) { listener.onRedraw(this); } } protected void afterClose() { setRefreshOn(false); for (DisplayerListener listener : listenerList) { listener.onClose(this); } } public void handleError(final String message) { handleError(new ClientRuntimeError(message, null)); } public void handleError(final String message, final Throwable error) { handleError(new ClientRuntimeError(message, error)); } public void handleError(final Throwable error) { handleError(new ClientRuntimeError(error)); } public void handleError(final ClientRuntimeError error) { for (DisplayerListener listener : listenerList) { listener.onError(this, error); } } // CAPTURE EVENTS RECEIVED FROM OTHER DISPLAYERS @Override public void onDataLookup(Displayer displayer) { // Do nothing } @Override public void onDataLoaded(Displayer displayer) { // Do nothing } @Override public void onDraw(Displayer displayer) { // Do nothing } @Override public void onRedraw(Displayer displayer) { // Do nothing } @Override public void onClose(Displayer displayer) { // Do nothing } @Override public void onError(final Displayer displayer, ClientRuntimeError error) { // Do nothing } @Override public void onFilterEnabled(Displayer displayer, DataSetGroup groupOp) { if (displayerSettings.isFilterListeningEnabled()) { if (dataSetHandler.filter(groupOp)) { redraw(); } } } @Override public void onFilterEnabled(Displayer displayer, DataSetFilter filter) { if (displayerSettings.isFilterListeningEnabled()) { if (dataSetHandler.filter(filter)) { redraw(); } } } @Override public void onFilterUpdate(Displayer displayer, DataSetFilter oldFilter, DataSetFilter newFilter) { if (displayerSettings.isFilterListeningEnabled()) { boolean unfilter = dataSetHandler.unfilter(oldFilter); boolean filter = dataSetHandler.filter(newFilter); if (unfilter || filter) { redraw(); } } } @Override public void onFilterReset(Displayer displayer, List groupOps) { if (displayerSettings.isFilterListeningEnabled()) { boolean applied = false; for (DataSetGroup groupOp : groupOps) { if (dataSetHandler.unfilter(groupOp)) { applied = true; } } if (applied) { redraw(); } } } @Override public void onFilterReset(Displayer displayer, DataSetFilter filter) { if (displayerSettings.isFilterListeningEnabled()) { if (dataSetHandler.unfilter(filter)) { redraw(); } } } // DATA COLUMN VALUES SELECTION, FILTER & NOTIFICATION /** * Get the set of columns being filtered. */ public Set filterColumns() { return columnSelectionMap.keySet(); } /** * Get the current filter intervals for the given data set column. * * @param columnId The column identifier. * @return A list of intervals. */ public List filterIntervals(String columnId) { List selected = columnSelectionMap.get(columnId); if (selected == null) { return new ArrayList<>(); } return selected; } /** * Get the current filter interval matching the specified index * * @param columnId The column identifier. * @param idx The index of the interval * @return The target interval matching the specified parameters or null if it does not exist. */ public Interval filterInterval(String columnId, int idx) { List selected = columnSelectionMap.get(columnId); if (selected != null && !selected.isEmpty()) { for (Interval interval : selected) { if (interval.getIndex() == idx) { return interval; } } } return null; } /** * Get the current filter selected interval indexes for the given data set column. * * @param columnId The column identifier. * @return A list of interval indexes */ public List filterIndexes(String columnId) { List result = new ArrayList<>(); List selected = columnSelectionMap.get(columnId); if (selected == null) { return result; } for (Interval interval : selected) { result.add(interval.getIndex()); } return result; } /** * Updates the current filter values for the given data set column. * * @param columnId The column to filter for. * @param row The row selected. */ public void filterUpdate(String columnId, int row) { filterUpdate(columnId, row, null); } /** * Updates the current filter values for the given data set column. * * @param columnId The column to filter for. * @param row The row selected. * @param maxSelections The number of different selectable values available. */ public void filterUpdate(String columnId, int row, Integer maxSelections) { if (displayerSettings.isFilterEnabled()) { List selectedIntervals = columnSelectionMap.get(columnId); Interval intervalFiltered = filterInterval(columnId, row); // Existing interval reset if (intervalFiltered != null) { selectedIntervals.remove(intervalFiltered); if (!selectedIntervals.isEmpty()) { filterApply(columnId, selectedIntervals); } else { filterReset(columnId); } } // No current filter => Add the selected interval else if (selectedIntervals == null) { Interval intervalSelected = dataSetHandler.getInterval(columnId, row); if (intervalSelected != null) { selectedIntervals = new ArrayList<>(); selectedIntervals.add(intervalSelected); columnSelectionMap.put(columnId, selectedIntervals); filterApply(columnId, selectedIntervals); } } // Extra interval added to an already filtered column else { Interval intervalSelected = dataSetHandler.getInterval(columnId, row); if (intervalSelected != null) { if (displayerSettings.isFilterSelfApplyEnabled()) { selectedIntervals = new ArrayList<>(); columnSelectionMap.put(columnId, selectedIntervals); } selectedIntervals.add(intervalSelected); if (maxSelections != null && maxSelections > 0 && selectedIntervals.size() >= maxSelections) { filterReset(columnId); } else { filterApply(columnId, selectedIntervals); } } } } } /** * Filter the values of the given column. * * @param columnId The name of the column to filter. * @param intervalList A list of interval selections to filter for. */ public void filterApply(String columnId, List intervalList) { if (displayerSettings.isFilterEnabled()) { // For string column filters, init the group interval selection operation. DataSetGroup groupOp = dataSetHandler.getGroupOperation(columnId); groupOp.setSelectedIntervalList(intervalList); // Notify to those interested parties the selection event. if (displayerSettings.isFilterNotificationEnabled()) { for (DisplayerListener listener : listenerList) { listener.onFilterEnabled(this, groupOp); } } // Drill-down support if (displayerSettings.isFilterSelfApplyEnabled()) { dataSetHandler.drillDown(groupOp); redraw(); } } } /** * Apply the given filter * * @param filter A filter */ public void filterApply(DataSetFilter filter) { if (displayerSettings.isFilterEnabled()) { this.currentFilter = filter; // Notify to those interested parties the selection event. if (displayerSettings.isFilterNotificationEnabled()) { for (DisplayerListener listener : listenerList) { listener.onFilterEnabled(this, filter); } } // Drill-down support if (displayerSettings.isFilterSelfApplyEnabled()) { dataSetHandler.filter(filter); redraw(); } } } /** * Updates the current filter values for the given data set column. Any previous filter is reset. * * @param filter A filter */ public void filterUpdate(DataSetFilter filter) { if (displayerSettings.isFilterEnabled()) { DataSetFilter oldFilter = currentFilter; this.currentFilter = filter; // Notify to those interested parties the selection event. if (displayerSettings.isFilterNotificationEnabled()) { for (DisplayerListener listener : listenerList) { listener.onFilterUpdate(this, oldFilter, filter); } } // Drill-down support if (displayerSettings.isFilterSelfApplyEnabled()) { dataSetHandler.unfilter(oldFilter); dataSetHandler.filter(filter); redraw(); } } } /** * Clear any filter on the given column. * * @param columnId The name of the column to reset. */ public void filterReset(String columnId) { if (displayerSettings.isFilterEnabled()) { columnSelectionMap.remove(columnId); DataSetGroup groupOp = dataSetHandler.getGroupOperation(columnId); // Notify to those interested parties the reset event. if (displayerSettings.isFilterNotificationEnabled()) { for (DisplayerListener listener : listenerList) { listener.onFilterReset(this, Arrays.asList(groupOp)); } } // Apply the selection to this displayer if (displayerSettings.isFilterSelfApplyEnabled()) { dataSetHandler.drillUp(groupOp); redraw(); } } } /** * Clear any filter. */ public void filterReset() { if (displayerSettings.isFilterEnabled()) { List groupOpList = new ArrayList(); for (String columnId : columnSelectionMap.keySet()) { DataSetGroup groupOp = dataSetHandler.getGroupOperation(columnId); groupOpList.add(groupOp); } columnSelectionMap.clear(); // Notify to those interested parties the reset event. if (displayerSettings.isFilterNotificationEnabled()) { for (DisplayerListener listener : listenerList) { if (currentFilter != null) { listener.onFilterReset(this, currentFilter); } listener.onFilterReset(this, groupOpList); } } // Apply the selection to this displayer if (displayerSettings.isFilterSelfApplyEnabled()) { boolean applied = false; if (currentFilter != null) { if (dataSetHandler.unfilter(currentFilter)) { applied = true; } } for (DataSetGroup groupOp : groupOpList) { if (dataSetHandler.drillUp(groupOp)) { applied = true; } } if (applied) { redraw(); } } if (currentFilter != null) { currentFilter = null; } } } // DATA COLUMN SORT /** * Set the sort order operation to apply to the data set. * * @param columnId The name of the column to sort. * @param sortOrder The sort order. */ public void sortApply(String columnId, SortOrder sortOrder) { dataSetHandler.sort(columnId, sortOrder); } // DATA FORMATTING public String formatInterval(Interval interval, DataColumn column) { // Raw values if (column == null || column.getColumnGroup() == null) { return interval.getName(); } // Date interval String type = interval.getType(); if (StringUtils.isBlank(type)) type = column.getIntervalType(); if (StringUtils.isBlank(type)) type = column.getColumnGroup().getIntervalSize(); DateIntervalType intervalType = DateIntervalType.getByName(type); if (intervalType != null) { ColumnSettings columnSettings = displayerSettings.getColumnSettings(column.getId()); String pattern = columnSettings != null ? columnSettings.getValuePattern() : ColumnSettings.getDatePattern(intervalType); String expression = columnSettings != null ? columnSettings.getValueExpression() : null; if (pattern == null) { pattern = ColumnSettings.getDatePattern(intervalType); } if (expression == null && column.getColumnGroup().getStrategy().equals(GroupStrategy.FIXED)) { expression = ColumnSettings.getFixedExpression(intervalType); } return formatDate(intervalType, column.getColumnGroup().getStrategy(), interval.getName(), pattern, expression); } // Label interval ColumnSettings columnSettings = displayerSettings.getColumnSettings(column); String expression = columnSettings.getValueExpression(); if (StringUtils.isBlank(expression)) return interval.getName(); return getEvaluator().evalExpression(interval.getName(), expression); } public void addFormatter(String columnId, ValueFormatter formatter) { formatterMap.put(columnId, formatter); } public ValueFormatter getFormatter(String columnId) { return formatterMap.get(columnId); } public String formatValue(int row, int column) { Object value = row < dataSet.getRowCount() ? dataSet.getValueAt(row, column) : null; DataColumn columnObj = dataSet.getColumnByIndex(column); ValueFormatter formatter = getFormatter(columnObj.getId()); if (formatter != null) { return formatter.formatValue(dataSet, row, column); } return formatValue(value, columnObj); } public String formatValue(Object value, DataColumn column) { ValueFormatter formatter = getFormatter(column.getId()); if (formatter != null) { return formatter.formatValue(value); } ColumnSettings columnSettings = displayerSettings.getColumnSettings(column); String pattern = columnSettings.getValuePattern(); String empty = columnSettings.getEmptyTemplate(); String expression = columnSettings.getValueExpression(); if (value == null) { return empty; } // Date grouped columns DateIntervalType intervalType = DateIntervalType.getByName(column.getIntervalType()); if (intervalType != null) { ColumnGroup columnGroup = column.getColumnGroup(); return formatDate(intervalType, columnGroup.getStrategy(), value.toString(), pattern, expression); } // Label grouped columns, aggregations & raw values else { ColumnType columnType = column.getColumnType(); if (ColumnType.DATE.equals(columnType)) { Date d = (Date) value; return getFormatter().formatDate(pattern, d); } else if (ColumnType.NUMBER.equals(columnType)) { OptionalDouble od = OptionalDouble.empty(); if (value instanceof Number) { od = OptionalDouble.of(((Number) value).doubleValue()); } if (!StringUtils.isBlank(expression)) { String r = getEvaluator().evalExpression(value.toString(), expression); try { od = OptionalDouble.of(Double.parseDouble(r)); } catch (NumberFormatException e) { return r; } } return getFormatter().formatNumber(pattern, od.getAsDouble()); } else { if (StringUtils.isBlank(expression)) { return value.toString(); } return getEvaluator().evalExpression(value.toString(), expression); } } } // DATE FORMATTING protected String formatDate(DateIntervalType type, GroupStrategy strategy, String date, String pattern, String expression) { if (date == null) { return null; } String str = GroupStrategy.FIXED.equals(strategy) ? formatDateFixed(type, date) : formatDateDynamic(type, date, pattern); if (StringUtils.isBlank(expression)) { return str; } return getEvaluator().evalExpression(str, expression); } protected String formatDateFixed(DateIntervalType type, String date) { if (date == null) { return null; } int index = Integer.parseInt(date); if (DateIntervalType.DAY_OF_WEEK.equals(type)) { DayOfWeek dayOfWeek = DayOfWeek.getByIndex(index); return getFormatter().formatDayOfWeek(dayOfWeek); } if (DateIntervalType.MONTH.equals(type)) { Month month = Month.getByIndex(index); return getFormatter().formatMonth(month); } return date; } protected String formatDateDynamic(DateIntervalType type, String date, String pattern) { if (date == null) { return null; } Date d = parseDynamicGroupDate(type, date); return getFormatter().formatDate(pattern, d); } protected Date parseDynamicGroupDate(DateIntervalType type, String date) { String pattern = DateIntervalPattern.getPattern(type); return getFormatter().parseDate(pattern, date); } // EXPORT @Override public void export(ExportFormat format, int maxRows, ExportCallback callback) { if (dataSetHandler == null) { callback.noData(); } else { Map columnNameMap = new HashMap<>(); displayerSettings.getColumnSettingsList().forEach(cs -> columnNameMap.put(cs.getColumnId(), cs.getColumnName())); dataSetHandler.exportCurrentDataSetLookup(format, maxRows, callback, columnNameMap); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/AbstractDisplayerListener.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.List; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.DataSetGroup; /** * Base class for implementing custom displayer listeners. */ public abstract class AbstractDisplayerListener implements DisplayerListener { @Override public void onDataLookup(Displayer displayer) { } @Override public void onDataLoaded(Displayer displayer) { } @Override public void onDraw(Displayer displayer) { } @Override public void onRedraw(Displayer displayer) { } @Override public void onClose(Displayer displayer) { } @Override public void onFilterEnabled(Displayer displayer, DataSetGroup groupOp) { } @Override public void onFilterEnabled(Displayer displayer, DataSetFilter filter) { } @Override public void onFilterUpdate(Displayer displayer, DataSetFilter oldFilter, DataSetFilter newFilter) { } @Override public void onFilterReset(Displayer displayer, List groupOps) { } @Override public void onFilterReset(Displayer displayer, DataSetFilter filter) { } @Override public void onError(Displayer displayer, ClientRuntimeError error) { } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/AbstractErraiDisplayer.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.uberfire.client.mvp.UberElement; /** * Base class for implementing custom displayers where the view is implemented using Errai @Templated. */ public abstract class AbstractErraiDisplayer extends AbstractDisplayer { public interface View

extends AbstractDisplayer.View, UberElement

{ } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/AbstractErraiDisplayerView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.displayer.client.resources.i18n.DisplayerConstants; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.jboss.errai.ui.client.local.api.IsElement; public abstract class AbstractErraiDisplayerView

implements AbstractErraiDisplayer.View

, IsElement { private Element panel = DOM.createDiv(); private Element label = DOM.createLabel(); private Element visualization = null; private Timer refreshTimer = null; protected P presenter = null; protected Widget asWidget = ElementWrapperWidget.getWidget(panel); public void setPresenter(P presenter) { this.presenter = presenter; } public P getPresenter() { return presenter; } public void setVisualization(Element element) { visualization = element; } @Override public void setId(String id) { panel.setId(id); } @Override public Widget asWidget() { return asWidget; } @Override public void clear() { DOMUtil.removeAllChildren((Node) panel); ElementWrapperWidget.removeWidget(panel); } @Override public void showLoading() { displayMessage(DisplayerConstants.INSTANCE.initializing()); } @Override public void showVisualization() { if (visualization != null) { DOMUtil.removeAllChildren((Node) panel); panel.appendChild(visualization); } } @Override public void errorMissingSettings() { displayMessage(DisplayerConstants.INSTANCE.error() + DisplayerConstants.INSTANCE.error_settings_unset()); } @Override public void errorMissingHandler() { displayMessage(DisplayerConstants.INSTANCE.error() + DisplayerConstants.INSTANCE.error_handler_unset()); } @Override public void errorDataSetNotFound(String dataSetUUID) { displayMessage(CommonConstants.INSTANCE.dataset_lookup_dataset_notfound(dataSetUUID)); } @Override public void error(ClientRuntimeError e) { displayMessage(DisplayerConstants.INSTANCE.error() + e.getMessage()); if (e.getThrowable() != null) { GWT.log(e.getMessage(), e.getThrowable()); } else { GWT.log(e.getMessage()); } } @Override public void enableRefreshTimer(int seconds) { if (refreshTimer == null) { refreshTimer = new Timer() { public void run() { if (presenter.isDrawn()) { presenter.redraw(); } } }; } refreshTimer.schedule(seconds * 1000); } @Override public void cancelRefreshTimer() { if (refreshTimer != null) { refreshTimer.cancel(); } } public void displayMessage(String msg) { DOMUtil.removeAllChildren((Node) panel); panel.appendChild(label); label.setInnerText(msg); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/AbstractGwtDisplayer.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.uberfire.client.mvp.UberView; /** * Base class for implementing custom displayers where the view is implemented using GWT widgets. */ public abstract class AbstractGwtDisplayer extends AbstractDisplayer { public interface View

extends AbstractDisplayer.View, UberView

{ } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/AbstractGwtDisplayerView.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Label; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.displayer.client.resources.i18n.DisplayerConstants; public abstract class AbstractGwtDisplayerView

extends Composite implements AbstractGwtDisplayer.View

{ private FlowPanel panel = new FlowPanel(); private Label label = new Label(); private IsWidget visualization = null; private Timer refreshTimer = null; protected P presenter = null; public AbstractGwtDisplayerView() { initWidget(panel); } public void setPresenter(P presenter) { this.presenter = presenter; } public P getPresenter() { return presenter; } public void setVisualization(IsWidget widget) { visualization = widget; } @Override public void setId(String id) { panel.getElement().setId(id); } @Override public void clear() { panel.clear(); } @Override public void showLoading() { displayMessage(DisplayerConstants.INSTANCE.initializing()); } @Override public void showVisualization() { if (visualization != null) { panel.clear(); panel.add(visualization); } } @Override public void errorMissingSettings() { displayMessage(DisplayerConstants.INSTANCE.error() + DisplayerConstants.INSTANCE.error_settings_unset()); } @Override public void errorMissingHandler() { displayMessage(DisplayerConstants.INSTANCE.error() + DisplayerConstants.INSTANCE.error_handler_unset()); } @Override public void errorDataSetNotFound(String dataSetUUID) { displayMessage(CommonConstants.INSTANCE.dataset_lookup_dataset_notfound(dataSetUUID)); } @Override public void error(ClientRuntimeError e) { displayMessage(DisplayerConstants.INSTANCE.error() + e.getMessage()); if (e.getThrowable() != null) { GWT.log(e.getMessage(), e.getThrowable()); } else { GWT.log(e.getMessage()); } } @Override public void enableRefreshTimer(int seconds) { if (refreshTimer == null) { refreshTimer = new Timer() { public void run() { if (presenter.isDrawn()) { presenter.redraw(); } } }; } refreshTimer.schedule(seconds * 1000); } @Override public void cancelRefreshTimer() { if (refreshTimer != null) { refreshTimer.cancel(); } } public void displayMessage(String msg) { panel.clear(); panel.add(label); label.setText(msg); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/AbstractRendererLibrary.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.List; import org.dashbuilder.displayer.DisplayerType; /** * Base class for implementing custom renderer libraries. */ public abstract class AbstractRendererLibrary implements RendererLibrary { @Override public boolean isDefault(DisplayerType type) { return false; } @Override public void draw(List displayerList) { for (Displayer displayer : displayerList) { displayer.draw(); } } @Override public void redraw(List displayerList) { for (Displayer displayer : displayerList) { displayer.redraw(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/ClientSettings.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.displayer.DisplayerType; /** * This class provides some methods for defining the behaviour of the Dashbuilder client layer */ @ApplicationScoped public class ClientSettings { @Inject RendererManager rendererManager; @Inject DataSetClientServices dataSetClientServices; /** * Turns off the ability to push data sets from server (is enabled by default). Push is very useful when dealing * with small size data sets as the performance of any lookup request is much faster on client. */ public void turnOffDataSetPush() { dataSetClientServices.setPushRemoteDataSetEnabled(false); } /** * It's possible to have one or more renderer libs available per displayer type. If a displayer does not define * its renderer lib then the default one is taken. This method can be used to define the default renderers. * * @param displayerType The type of the displayer we want to configure. * @param rendererLib The UUID of the renderer library. */ public void setDefaultRenderer(DisplayerType displayerType, String rendererLib) { rendererManager.setDefaultRenderer(displayerType, rendererLib); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DataSetEditHandler.java ================================================ package org.dashbuilder.displayer.client; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.def.DataSetDef; /** * @since 0.4.0 */ public class DataSetEditHandler extends DataSetHandlerImpl { DataSetDef defEdit; public DataSetEditHandler(final DataSetClientServices clientServices, final DataSetLookup lookup, final DataSetDef defEdit) { super(clientServices, lookup); this.defEdit = defEdit; } @Override public void lookupDataSet(final DataSetReadyCallback callback) throws Exception { lookupCurrent.setTestMode(true); clientServices.lookupDataSet(defEdit, lookupCurrent, new DataSetReadyCallback() { public void callback(DataSet dataSet) { lastLookedUpDataSet = dataSet; callback.callback(dataSet); } public void notFound() { callback.notFound(); } @Override public boolean onError(final ClientRuntimeError error) { return callback.onError(error); } }); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DataSetHandler.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.Map; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.client.export.ExportCallback; import org.dashbuilder.displayer.client.export.ExportFormat; /** * Interface addressed to issue lookup requests over a data set instance. */ public interface DataSetHandler { /** * Retrieves any group operation present in the current data set lookup for the target column specified. * @param columnId The column id. to look for. * * @return The group operation that matches the given column id. Or null if no operation is found. */ DataSetGroup getGroupOperation(String columnId); /** * Get the interval at the given row for the column specified. * *

In case of grouped data sets, the interval may contain information * related to the group operation. For instance, for a data set grouped * by month, will return an interval containing the min/max dates of such month.

* *

For non-grouped or grouped by label data sets, will * return only an interval with the value of the row/column selected.

* * The interval information is useful for filtering purposes as the data provider needs * all the information related to the selected interval. * * @param columnId The column id. * @param row The row which interval we want to retrieve. * @return An interval with information related to the target row/column. Or null, if *
    *
  • the column does not exist,
  • *
  • the row index is out of bounds,
  • *
  • or the value is null.
  • *
*/ Interval getInterval(String columnId, int row); /** * Forces the underlying data set to be updated according the group interval selection filter. * * @param op The group interval selection operation to apply op.getSelectedIntervalNames() MUST NOT BE EMPTY. * @return false, if the target interval selection has already been applied - true, otherwise. */ boolean filter(DataSetGroup op); /** * Reverts the changes applied by a previous filter operation. * * @param op The operation to remove. * @return false, if no filter has been applied for the target operation - true, otherwise. */ boolean unfilter(DataSetGroup op); /** * Forces the underlying data set to be updated according the specified filter. * * @param op The filter operation to apply. * @return false, if the filter requested has already been applied - true, otherwise. */ boolean filter(DataSetFilter op); /** * Reverts the changes applied by a previous filter operation. * * @param op The operation to remove. * @return false, if no filter has been applied for the target operation - true, otherwise. */ boolean unfilter(DataSetFilter op); /** * Applies the specified group interval selection operation over the existing group op. * * @param op The group interval selection operation to apply op.getSelectedIntervalNames() MUST NOT BE EMPTY. * @return false, if drillDown is not applicable for the target operation - true, otherwise. */ boolean drillDown(DataSetGroup op); /** * Reverts the changes applied by a previous drillDown operation. * * @param op The operation to remove. * @return false, if no drillDown has been applied for the target operation - true, otherwise. */ boolean drillUp(DataSetGroup op); /** * Set the sort order operation to apply to the data set. * * @param columnId The name of the column to sort. * @param sortOrder The sort order. */ void sort(String columnId, SortOrder sortOrder); /** * Forces the next data set lookup request to retrieve only the specified row sub set. * * @param offset The position where the row sub set starts. * @param rows The number of rows to get. */ void limitDataSetRows(int offset, int rows); /** * Restore the current data set lookup instance to its base status. */ void resetAllOperations(); /** * Executes the current data set lookup request configured within this handler. * * @param callback The callback interface that is invoked right after the data is available. */ void lookupDataSet(DataSetReadyCallback callback) throws Exception; /** * Get the data set get on the last lookup call (if any) */ DataSet getLastDataSet(); /** * Get the current data set lookup (if any) */ DataSetLookup getCurrentDataSetLookup(); /** * Export the current data set to a file in the specified output format. * * @param format The output format * @param maxRows Max rows to be exported. * @param callback The callback instance to be notified * @param columnNameMap A map containing the column header names for every column in the data set lookup */ void exportCurrentDataSetLookup(ExportFormat format, int maxRows, ExportCallback callback, Map columnNameMap); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DataSetHandlerImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.*; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetExportReadyCallback; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.*; import org.dashbuilder.dataset.sort.ColumnSort; import org.dashbuilder.dataset.sort.DataSetSort; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.client.export.ExportCallback; import org.dashbuilder.displayer.client.export.ExportFormat; import org.uberfire.backend.vfs.Path; import java.util.*; public class DataSetHandlerImpl implements DataSetHandler { protected DataSetClientServices clientServices; protected DataSetLookup lookupBase; protected DataSetLookup lookupCurrent; protected DataSet lastLookedUpDataSet; public DataSetHandlerImpl(DataSetClientServices clientServices, DataSetLookup lookup) { this.clientServices = clientServices; this.lookupBase = lookup; this.lookupCurrent = lookup.cloneInstance(); } @Override public DataSet getLastDataSet() { return lastLookedUpDataSet; } @Override public DataSetLookup getCurrentDataSetLookup() { return lookupCurrent; } @Override public void resetAllOperations() { this.lookupCurrent = lookupBase.cloneInstance(); } @Override public void limitDataSetRows(int offset, int rows) { int offsetBase = lookupBase.getRowOffset(); int rowsBase = lookupBase.getNumberOfRows(); lookupCurrent.setRowOffset(offsetBase + offset); // base 0 to all, 0 to 20 => offset=0, rows=20 // base 0 to 1, 0 to 20 => offset=0, rows=1 // base 50 to 51, 0 to 20 => offset=50, rows=20 // base 10 to 31, 20 to 10 => offset=30, rows=10 // base 10 to 31, 0 to 50 => offset=10, rows=31 if (rowsBase < 1 || rowsBase > rows) { lookupCurrent.setNumberOfRows(rows); } } @Override public DataSetGroup getGroupOperation(String columnId) { String sourceId = _getSourceColumnId(columnId); int index = lookupCurrent.getLastGroupOpIndex(0, sourceId, false); if (index != -1) { return (DataSetGroup) lookupCurrent.getOperation(index).cloneInstance(); } DataSetGroup result = new DataSetGroup(); result.setColumnGroup(new ColumnGroup(sourceId, sourceId, GroupStrategy.DYNAMIC)); return result; } @Override public boolean filter(DataSetGroup op) { ColumnGroup cg = op.getColumnGroup(); if (cg == null) { throw new RuntimeException("Group ops require a pivot column to be specified."); } if (!op.isSelect()) { throw new RuntimeException("Group intervals not specified."); } // Avoid duplicates for (DataSetGroup next : lookupCurrent.getOperationList(DataSetGroup.class)) { if (op.equals(next)) { return false; } } // The interval selection op. must be added right before the first existing group op. DataSetGroup clone = op.cloneInstance(); //clone.getGroupFunctions().clear(); int idx = lookupCurrent.getFirstGroupOpIndex(0, null, null); _filter(idx < 0 ? 0 : idx, clone, false); return true; } @Override public boolean filter(DataSetFilter op) { if (op == null) { return false; } // Avoid duplicates for (DataSetFilter next : lookupCurrent.getOperationList(DataSetFilter.class)) { if (op.equals(next)) { return false; } } lookupCurrent.addOperation(0, op); return true; } @Override public boolean drillDown(DataSetGroup op) { ColumnGroup cg = op.getColumnGroup(); if (cg == null) { throw new RuntimeException("Group ops require a pivot column to be specified."); } if (!op.isSelect()) { throw new RuntimeException("Group intervals not specified."); } // Avoid duplicates for (DataSetGroup next : lookupCurrent.getOperationList(DataSetGroup.class)) { if (op.equals(next)) { return false; } } // Get the latest group op. for the target column being selected. int lastSelection = lookupCurrent.getLastGroupOpIndex(0, null, true) + 1; int targetGroup = lookupCurrent.getLastGroupOpIndex(lastSelection, cg.getColumnId(), false); // If the selection does not exists just add it. if (targetGroup == -1) { DataSetGroup clone = op.cloneInstance(); //clone.getGroupFunctions().clear(); _filter(lastSelection, clone, true); return true; } // If there not exists a group op after the target then the target op must be propagated along the selection. DataSetGroup targetOp = lookupCurrent.getOperation(targetGroup); int latestGroup = lookupCurrent.getLastGroupOpIndex(targetGroup + 1, null, false); if (latestGroup == -1) { DataSetGroup clone = targetOp.cloneInstance(); _filter(targetGroup + 1, clone, true); } // Enable the selection _select(targetOp, op.getSelectedIntervalList()); return true; } @Override public boolean unfilter(DataSetGroup op) { return _unfilter(op, false); } @Override public boolean unfilter(DataSetFilter op) { if (op == null) { return false; } int idx = lookupCurrent.getOperationIdx(op); if (idx != -1) { lookupCurrent.removeOperation(idx); return true; } return false; } @Override public boolean drillUp(DataSetGroup op) { return _unfilter(op, true); } @Override public void sort(String columnId, SortOrder sortOrder) { unsort(); String sourceId = _getSourceColumnId(columnId); DataSetSort sortOp = new DataSetSort(); sortOp.addSortColumn(new ColumnSort(sourceId, sortOrder)); lookupCurrent.addOperation(sortOp); } public boolean unsort() { int n = lookupCurrent.removeOperations(DataSetOpType.SORT); return n > 0; } @Override public void lookupDataSet(final DataSetReadyCallback callback) throws Exception { clientServices.lookupDataSet(lookupCurrent, new DataSetReadyCallback() { public void callback(DataSet dataSet) { lastLookedUpDataSet = dataSet; callback.callback(dataSet); } public void notFound() { callback.notFound(); } @Override public boolean onError(final ClientRuntimeError error) { return callback.onError(error); } }); } @Override public Interval getInterval(String columnId, int row) { if (lastLookedUpDataSet == null) { return null; } DataColumn column = lastLookedUpDataSet.getColumnById(columnId); if (column == null) { return null; } // Get the target value List values = column.getValues(); Object value = row < values.size() ? values.get(row) : null; if (value == null) { return null; } Interval result = new Interval(value.toString(), row); result.setType(column.getIntervalType()); result.setMinValue(column.getMinValue()); result.setMaxValue(column.getMaxValue()); return result; } @Override public void exportCurrentDataSetLookup(ExportFormat format, int maxRows, ExportCallback callback, Map columnNameMap) { // Export an empty data set does not make sense if (lastLookedUpDataSet == null || lastLookedUpDataSet.getRowCount() == 0) { callback.noData(); return; } // Ensure the entire dataset does not exceed the maximum export limit int allRows = lastLookedUpDataSet.getRowCountNonTrimmed(); if (maxRows > 0 && allRows > maxRows) { callback.tooManyRows(allRows); return; } try { // Create a backend export callback DataSetExportReadyCallback exportReadyCallback = new DataSetExportReadyCallback() { @Override public void exportReady(Path exportFilePath) { final String u = clientServices.getDownloadFileUrl(exportFilePath); callback.exportFileUrl(u); } @Override public void onError(ClientRuntimeError error) { callback.error(error); } }; // Export the entire data set DataSetLookup exportLookup = getCurrentDataSetLookup().cloneInstance(); exportLookup.setRowOffset(0); exportLookup.setNumberOfRows(maxRows); // Make sure the column names are set as specified if (exportLookup.getLastGroupOp() != null && columnNameMap != null) { for (GroupFunction groupFunction : exportLookup.getLastGroupOp().getGroupFunctions()) { String columnId = groupFunction.getColumnId(); if (columnNameMap.containsKey(columnId)) { String columnName = columnNameMap.get(columnId); groupFunction.setColumnId(columnName); } } } if (ExportFormat.XLS.equals(format)) { clientServices.exportDataSetExcel(exportLookup, exportReadyCallback); } else { clientServices.exportDataSetCSV(exportLookup, exportReadyCallback); } } catch (Exception e) { callback.error(new ClientRuntimeError(e)); } } // Internal filter/drillDown implementation logic protected Map> _groupOpsAdded = new HashMap<>(); protected Map> _groupOpsSelected = new HashMap<>(); protected void _filter(int index, DataSetGroup op, boolean drillDown) { ColumnGroup cgroup = op.getColumnGroup(); String columnId = cgroup.getColumnId(); if (!_groupOpsAdded.containsKey(columnId)) _groupOpsAdded.put(columnId, new ArrayList<>()); List filterOps = _groupOpsAdded.get(columnId); // When adding an external filter, look first if it exists an existing filter already. if (!drillDown) { for (GroupOpFilter filterOp : filterOps) { if (!filterOp.drillDown && filterOp.groupOp.getColumnGroup().equals(cgroup)) { filterOp.groupOp.getSelectedIntervalList().clear(); filterOp.groupOp.getSelectedIntervalList().addAll(op.getSelectedIntervalList()); return; } } } GroupOpFilter groupOpFilter = new GroupOpFilter(op, drillDown); filterOps.add(groupOpFilter); lookupCurrent.addOperation(index, op); } protected void _select(DataSetGroup op, List intervalList) { GroupOpFilter groupOpFilter = new GroupOpFilter(op, true); op.setSelectedIntervalList(intervalList); String columnId = op.getColumnGroup().getColumnId(); if (!_groupOpsSelected.containsKey(columnId)) { _groupOpsSelected.put(columnId, new ArrayList<>()); } _groupOpsSelected.get(columnId).add(groupOpFilter); } protected boolean _unfilter(DataSetGroup op, boolean drillDown) { boolean opFound = false; String columnId = op.getColumnGroup().getColumnId(); if (_groupOpsAdded.containsKey(columnId)) { Iterator it1 = _groupOpsAdded.get(columnId).iterator(); while (it1.hasNext()) { GroupOpFilter target = it1.next(); Iterator it2 = lookupCurrent.getOperationList().iterator(); while (it2.hasNext()) { DataSetOp next = it2.next(); if (next == target.groupOp && target.drillDown == drillDown) { it1.remove(); it2.remove(); opFound = true; } } } } if (_groupOpsSelected.containsKey(columnId)) { Iterator it1 = _groupOpsSelected.get(columnId).iterator(); while (it1.hasNext()) { GroupOpFilter target = it1.next(); Iterator it2 = lookupCurrent.getOperationList(DataSetGroup.class).iterator(); while (it2.hasNext()) { DataSetGroup next = it2.next(); if (next == target.groupOp && target.drillDown == drillDown) { it1.remove(); next.getSelectedIntervalList().clear(); next.getGroupFunctions().clear(); next.getSelectedIntervalList().addAll(target.intervalList); next.getGroupFunctions().addAll(target.groupFunctions); opFound = true; } } } } return opFound; } protected String _getSourceColumnId(String columnId) { if (lastLookedUpDataSet != null) { DataColumn column = lastLookedUpDataSet.getColumnById(columnId); if (column != null && column.getGroupFunction() != null) { String sourceId = column.getGroupFunction().getSourceId(); if (sourceId != null) { return sourceId; } } } for (List currentSelections : _groupOpsSelected.values()) { for (GroupOpFilter groupOpFilter : currentSelections) { GroupFunction gf = groupOpFilter.groupOp.getGroupFunction(columnId); if (gf != null) { return gf.getSourceId(); } } } return columnId; } protected static class GroupOpFilter { DataSetGroup groupOp; boolean drillDown = false; List groupFunctions; List intervalList; private GroupOpFilter(DataSetGroup op, boolean drillDown) { this.groupOp = op; this.drillDown = drillDown; this.groupFunctions = new ArrayList<>(op.getGroupFunctions()); this.intervalList = new ArrayList<>(op.getSelectedIntervalList()); } public String toString() { StringBuilder out = new StringBuilder(); out.append("drillDown(").append(drillDown).append(") "); if (groupOp != null) out.append("groupOp(").append(groupOp).append(")"); return out.toString(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/Displayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.export.ExportCallback; import org.dashbuilder.displayer.client.export.ExportFormat; import org.dashbuilder.displayer.client.formatter.ValueFormatter; /** * A Displayer takes care of drawing a DisplayerSettings instance. */ public interface Displayer extends DisplayerListener, IsWidget { /** * The data displayer to draw. */ void setDisplayerSettings(DisplayerSettings displayerSettings); DisplayerSettings getDisplayerSettings(); /** * The handler used to fetch and manipulate the data set. */ void setDataSetHandler(DataSetHandler dataSetHandler); DataSetHandler getDataSetHandler(); /** * Every Displayer implementation must define the set of features it supports as well as other behavioral settings. * These "constrains" are needed for two main reasons: *
    *
  • Validation purposes: in order to ensure the DisplayerSettings are valid and ready for rendering.
  • *
  • Edition purposes: in order to let the DisplayerEditor know what features/settings/behaviour this Displayer implementation supports.
  • *
*/ DisplayerConstraints getDisplayerConstraints(); /** * Add a listener interested in receive events generated within this displayer component. */ void addListener(DisplayerListener... listeners); /** * Registers a custom formatter for the given column */ void addFormatter(String columnId, ValueFormatter formatter); /** * Draw the chart */ void draw(); /** * Same as draw but does not necessary implies to repaint everything again. * It's just a matter of update & display the latest data set changes. */ void redraw(); /** * Check if the displayer is completely drawn. */ boolean isDrawn(); /** * Enables or disables the automatic refresh capability (enabled by default). * @see DisplayerSettings#getRefreshInterval() */ void setRefreshOn(boolean enabled); /** * Check if the automatic refresh is on. */ boolean isRefreshOn(); /** * Export the data being displayed into the specified output format. * * @param format The output format * @param maxRows Max rows to be exported. If lower or equals to 0 then all rows will be exported. * @param callback The callback instance to be notified */ void export(ExportFormat format, int maxRows, ExportCallback callback); /** * Frees any resource the displayer is consuming. */ void close(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DisplayerClientEntryPoint.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ui.shared.api.annotations.Bundle; @EntryPoint @Bundle("resources/i18n/CommonConstants.properties") public class DisplayerClientEntryPoint { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DisplayerCoordinator.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.DataSetGroup; import org.uberfire.mvp.Command; /** * The coordinator class holds a list of Displayer instances and it makes sure that the data shared among * all of them is properly synced. This means every time a data display modification request comes from any * of the displayer components the rest are updated to reflect those changes. */ @Dependent public class DisplayerCoordinator { protected List displayerList = new ArrayList<>(); protected Set listenerSet = new HashSet<>(); protected Map> rendererMap = new HashMap<>(); protected CoordinatorListener coordinatorListener = new CoordinatorListener(); protected Map> notificationVetoMap = new HashMap<>(); protected RendererManager rendererManager; @Inject public DisplayerCoordinator(RendererManager rendererManager) { this.rendererManager = rendererManager; } public void addListener(DisplayerListener... listeners) { if (listeners != null) { for (DisplayerListener listener : listeners) { listenerSet.add(listener); } displayerList.stream().forEach(displayer -> displayer.addListener(listeners)); } } public void addDisplayers(Collection displayers) { if (displayers != null) { displayers.stream().forEach(this::addDisplayer); } } public void addDisplayers(Displayer... displayers) { if (displayers != null) { for (Displayer displayer : displayers) { addDisplayer(displayer); } } } public void addDisplayer(Displayer displayer) { if (displayer != null && !displayerList.contains(displayer)) { displayerList.add(displayer); displayer.addListener(coordinatorListener); listenerSet.stream().forEach(displayer::addListener); RendererLibrary renderer = rendererManager.getRendererForDisplayer(displayer.getDisplayerSettings()); List rendererGroup = rendererMap.get(renderer); if (rendererGroup == null) { rendererGroup = new ArrayList<>(); rendererMap.put(renderer, rendererGroup); } rendererGroup.add(displayer); } } public List getDisplayerList() { return displayerList; } public boolean removeDisplayer(Displayer displayer) { if (displayer == null) { return false; } RendererLibrary renderer = rendererManager.getRendererForDisplayer(displayer.getDisplayerSettings()); List rendererGroup = rendererMap.get(renderer); if (rendererGroup != null) rendererGroup.remove(displayer); return displayerList.remove(displayer); } public void drawAll() { drawAll(null, null); } public void redrawAll() { redrawAll(null, null); } public void drawAll(Command onSuccess, Command onFailure) { coordinatorListener.init(onSuccess, onFailure, displayerList.size(), true); for (RendererLibrary renderer : rendererMap.keySet()) { List rendererGroup = rendererMap.get(renderer); renderer.draw(rendererGroup); } } public void redrawAll(Command onSuccess, Command onFailure) { coordinatorListener.init(onSuccess, onFailure, displayerList.size(), false); for (RendererLibrary renderer : rendererMap.keySet()) { List rendererGroup = rendererMap.get(renderer); renderer.redraw(rendererGroup); } } public void closeAll() { displayerList.stream().forEach(Displayer::close); } public void clear() { closeAll(); displayerList.clear(); listenerSet.clear(); rendererMap.clear(); notificationVetoMap.clear(); } public void addNotificationVeto(Displayer target, List vetoedDisplayers) { notificationVetoMap.put(target, vetoedDisplayers); } public void addNotificationVeto(List vetoedDisplayers) { for (Displayer target: vetoedDisplayers) { notificationVetoMap.put(target, vetoedDisplayers); } } public boolean isNotificationVetoed(Displayer from, Displayer to) { List vetoList = notificationVetoMap.get(to); return vetoList != null && vetoList.contains(from); } /** * Internal class that listens to events raised by any of the Displayer instances handled by this coordinator. */ private class CoordinatorListener implements DisplayerListener { int count = 0; int total = 0; Command onSuccess; Command onFailure; boolean draw; protected void init(Command onSuccess, Command onFailure, int total, boolean draw) { count = 0; this.onSuccess = onSuccess; this.onFailure = onFailure; this.draw = draw; this.total = total; } protected void count() { count++; if (count == total && onSuccess != null) { onSuccess.execute(); } } protected void error() { count++; if (count == total && onFailure != null) { onFailure.execute(); } } @Override public void onDataLookup(Displayer displayer) { displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onDataLookup(displayer)); } @Override public void onDataLoaded(Displayer displayer) { displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onDataLoaded(displayer)); } @Override public void onDraw(Displayer displayer) { if (draw) { count(); } displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onDraw(displayer)); } @Override public void onRedraw(Displayer displayer) { if (!draw) { count(); } displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onRedraw(displayer)); } public void onClose(Displayer displayer) { displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onClose(displayer)); } @Override public void onFilterEnabled(Displayer displayer, DataSetGroup groupOp) { displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onFilterEnabled(displayer, groupOp)); } @Override public void onFilterEnabled(Displayer displayer, DataSetFilter filter) { displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onFilterEnabled(displayer, filter)); } @Override public void onFilterUpdate(Displayer displayer, DataSetFilter oldFilter, DataSetFilter newFilter) { for (Displayer other : displayerList) { if (other != displayer && !isNotificationVetoed(displayer, other)) { other.onFilterUpdate(displayer, oldFilter, newFilter); } } } @Override public void onFilterReset(Displayer displayer, List groupOps) { displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onFilterReset(displayer, groupOps)); } @Override public void onFilterReset(Displayer displayer, DataSetFilter filter) { displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onFilterReset(displayer, filter)); } @Override public void onError(final Displayer displayer, ClientRuntimeError error) { error(); displayerList.stream() .filter(other -> other != displayer && !isNotificationVetoed(displayer, other)) .forEach(other -> other.onError(displayer, error)); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DisplayerGwtExprEval.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.displayer.client.resources.i18n.DisplayerConstants; public class DisplayerGwtExprEval implements AbstractDisplayer.ExpressionEval { public static final String[] _jsMalicious = {"document.", "window.", "alert(", "eval(", ".innerHTML"}; AbstractDisplayer presenter = null; public DisplayerGwtExprEval(AbstractDisplayer presenter) { this.presenter = presenter; } @Override public String evalExpression(String val, String expr) { if (StringUtils.isBlank(expr)) { return val; } for (String keyword : _jsMalicious) { if (expr.contains(keyword)) { presenter.handleError(DisplayerConstants.INSTANCE.displayer_keyword_not_allowed(expr)); throw new RuntimeException(DisplayerConstants.INSTANCE.displayer_keyword_not_allowed(expr)); } } try { return _evalExpression(val, expr); } catch (Exception e) { presenter.handleError(DisplayerConstants.INSTANCE.displayer_expr_invalid_syntax(expr), e); throw new RuntimeException(DisplayerConstants.INSTANCE.displayer_expr_invalid_syntax(expr)); } } protected native String _evalExpression(String val, String expr) /*-{ value = val; return eval(expr) + ''; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DisplayerGwtFormatter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.Date; import java.util.HashMap; import java.util.Map; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.NumberFormat; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.dataset.client.resources.i18n.DayOfWeekConstants; import org.dashbuilder.dataset.client.resources.i18n.MonthConstants; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.displayer.ColumnSettings; public class DisplayerGwtFormatter implements AbstractDisplayer.Formatter { protected static Map numberPatternMap = new HashMap(); protected static Map datePatternMap = new HashMap(); @Override public Date parseDate(String pattern, String d) { DateTimeFormat df = getDateFormat(pattern); return df.parse(d); } @Override public String formatDate(String pattern, Date d) { DateTimeFormat df = getDateFormat(pattern); return df.format(d); } @Override public String formatNumber(String pattern, Number n) { NumberFormat f = getNumberFormat(pattern); return f.format(n); } @Override public String formatDayOfWeek(DayOfWeek dayOfWeek) { return DayOfWeekConstants.INSTANCE.getString(dayOfWeek.name()); } @Override public String formatMonth(Month month) { return MonthConstants.INSTANCE.getString(month.name()); } protected NumberFormat getNumberFormat(String pattern) { if (StringUtils.isBlank(pattern)) { return getNumberFormat(ColumnSettings.NUMBER_PATTERN); } NumberFormat format = numberPatternMap.get(pattern); if (format == null) { format = NumberFormat.getFormat(pattern); numberPatternMap.put(pattern, format); } return format; } protected DateTimeFormat getDateFormat(String pattern) { if (StringUtils.isBlank(pattern)) { return getDateFormat(ColumnSettings.DATE_PATTERN); } DateTimeFormat format = datePatternMap.get(pattern); if (format == null) { format = DateTimeFormat.getFormat(pattern); datePatternMap.put(pattern, format); } return format; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DisplayerListener.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.List; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.DataSetGroup; /** * Interface addressed to capture events coming from a Displayer instance. */ public interface DisplayerListener { /** * Invoked just before the data lookup operation has been started, * * @param displayer The Displayer instance. */ void onDataLookup(Displayer displayer); /** * Invoked right after the data lookup finishes and the data set is available, * * @param displayer The Displayer instance. */ void onDataLoaded(Displayer displayer); /** * Invoked just after the displayer has been drawn. * * @param displayer The Displayer instance. */ void onDraw(Displayer displayer); /** * Invoked just after the displayer has been redrawn. * * @param displayer The Displayer instance. */ void onRedraw(Displayer displayer); /** * Invoked just after the displayer has been closed. * * @param displayer The Displayer instance. */ void onClose(Displayer displayer); /** * Invoked when a group interval selection filter request is executed on a given Displayer instance. * * @param displayer The Displayer instance where the interval selection event comes from. * @param groupOp The group interval selection operation. */ void onFilterEnabled(Displayer displayer, DataSetGroup groupOp); /** * Invoked when a filter request is executed on a given Displayer instance. * * @param displayer The Displayer instance where the filter request event comes from. * @param filter The filter operation. */ void onFilterEnabled(Displayer displayer, DataSetFilter filter); /** * Invoked when an update filter request is executed on an already filtered Displayer instance. * * @param displayer The Displayer instance where the filter request event comes from. * @param oldFilter The old filter operation. * @param newFilter The new filter operation. */ void onFilterUpdate(Displayer displayer, DataSetFilter oldFilter, DataSetFilter newFilter); /** * Invoked when a group interval reset request is executed on a given Displayer instance. * * @param displayer The Displayer instance where the interval selection event comes from. * @param groupOps The set of group interval selection operations reset. */ void onFilterReset(Displayer displayer, List groupOps); /** * Invoked when a filter reset request is executed on a given Displayer instance. * * @param displayer The Displayer instance where the filter event comes from. * @param filter The filter operation to reset. */ void onFilterReset(Displayer displayer, DataSetFilter filter); /** * Invoked when some error occurs. * @param displayer The Displayer instance event comes from. * @param error The error instance. */ void onError(final Displayer displayer, ClientRuntimeError error); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/DisplayerLocator.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.client.ClientDataSetManager; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.formatter.ValueFormatter; import org.dashbuilder.displayer.client.formatter.ValueFormatterRegistry; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; /** * The locator service for Displayer implementations. */ @ApplicationScoped public class DisplayerLocator { private DataSetClientServices clientServices; private ClientDataSetManager clientDataSetManager; private ValueFormatterRegistry formatterRegistry; private RendererManager rendererManager; public DisplayerLocator() { } @Inject public DisplayerLocator(DataSetClientServices clientServices, ClientDataSetManager clientDataSetManager, RendererManager rendererManager, ValueFormatterRegistry formatterRegistry) { this.clientServices = clientServices; this.clientDataSetManager = clientDataSetManager; this.rendererManager = rendererManager; this.formatterRegistry = formatterRegistry; } /** * Get the displayer component for the specified data displayer (with no data set attached). */ public Displayer lookupDisplayer(DisplayerSettings target) { RendererLibrary renderer = rendererManager.getRendererForDisplayer(target); Displayer displayer = renderer.lookupDisplayer(target); if (displayer == null) { String rendererUuid = target.getRenderer(); if (StringUtils.isBlank(rendererUuid)) throw new RuntimeException(CommonConstants.INSTANCE.displayerlocator_default_renderer_undeclared(target.getType().toString())); throw new RuntimeException(CommonConstants.INSTANCE.displayerlocator_unsupported_displayer_renderer(target.getType().toString(), rendererUuid)); } displayer.setDisplayerSettings(target); // Check if a DataSet has been set instead of a DataSetLookup. DataSetLookup dataSetLookup = target.getDataSetLookup(); if (target.getDataSet() != null) { DataSet dataSet = target.getDataSet(); clientDataSetManager.registerDataSet(dataSet); dataSetLookup = new DataSetLookup(dataSet.getUUID()); } DataSetHandler handler = new DataSetHandlerImpl(clientServices, dataSetLookup); displayer.setDataSetHandler(handler); setValueFormatters(displayer); return displayer; } protected void setValueFormatters(Displayer displayer) { Map m = formatterRegistry.get(displayer.getDisplayerSettings().getUUID()); for (String columnId : m.keySet()) { displayer.addFormatter(columnId, m.get(columnId)); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/RendererLibrary.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.List; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; /** * Main interface for renderer implementations. * *

A renderer library must:

*
    *
  • Perform all the required initializations before any displayer can be drawn
  • *
  • Declare the displayer types & subtypes supported
  • *
  • Take care of the initialization of displayer instances
  • *
*/ public interface RendererLibrary { /** * The unique universal identifier of the rederer */ String getUUID(); /** * The renderer display name */ String getName(); /** * Flag indicating if this renderer can act as the default one for the given displayer type. *

Default renderers are used when a displayer does not explicitly specifies one

*/ boolean isDefault(DisplayerType type); /** * The list of supported types */ List getSupportedTypes(); /** * The list of supported sub-types */ List getSupportedSubtypes(DisplayerType displayerType); /** * Initalize a displayer instance with the specified configuration. */ Displayer lookupDisplayer(DisplayerSettings displayer); /** * Draw a list of displayers */ void draw(List displayerList); /** * Re-draw a list of displayers */ void redraw(List displayerList); default boolean isOffline() { return true; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/RendererManager.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.EnumMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.Predicate; import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.renderer.RendererSettings; import org.dashbuilder.renderer.service.RendererSettingsService; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** * This class holds a registry of all the RendererLibrary implementations available. */ @EntryPoint @ApplicationScoped public class RendererManager { private SyncBeanManager beanManager; private List renderersList; private Map renderersDefault = new EnumMap<>(DisplayerType.class); private Map> renderersByType = new EnumMap<>(DisplayerType.class); private Map> renderersBySubType = new EnumMap<>(DisplayerSubType.class); CommonConstants i18n = CommonConstants.INSTANCE; Caller rendererSettingsService; public RendererManager() { } @Inject public RendererManager(SyncBeanManager beanManager, Caller rendererSettingsService) { this.beanManager = beanManager; this.rendererSettingsService = rendererSettingsService; } @PostConstruct protected void init() { rendererSettingsService.call((RendererSettings settings) -> lookupRenderers(settings)) .getSettings(); } protected void lookupRenderers(RendererSettings settings) { String defaultUUID = settings.getDefaultRenderer(); boolean onlyOffline = settings.isOffline(); renderersList = new ArrayList<>(); Collection> beanDefs = beanManager.lookupBeans(RendererLibrary.class); if (onlyOffline) { beanDefs = beanDefs.stream().filter(bd -> bd.getInstance().isOffline()).collect(Collectors.toList()); } if (defaultUUID != null && ! defaultUUID.isEmpty()) { beanDefs.stream() .map(SyncBeanDef::getInstance) .filter(render -> render.getUUID().equals(defaultUUID)) .findFirst().ifPresent(rend -> rend.getSupportedTypes().forEach(c -> renderersDefault.put(c, rend)) ); } for (SyncBeanDef beanDef : beanDefs) { RendererLibrary lib = beanDef.getInstance(); renderersList.add(lib); for (DisplayerType displayerType : DisplayerType.values()) { if (lib.isDefault(displayerType)) { renderersDefault.putIfAbsent(displayerType, lib); } } List types = lib.getSupportedTypes(); if (types != null && !types.isEmpty()) { for (DisplayerType type : types) { List set = renderersByType.get(type); if (set == null) { set = new ArrayList<>(); renderersByType.put(type, set); } set.add(lib); List subTypes = lib.getSupportedSubtypes(type); if (subTypes != null && !subTypes.isEmpty()) { for (DisplayerSubType subType : subTypes) { List subset = renderersBySubType.get(subType); if (subset == null) { subset = new ArrayList<>(); renderersBySubType.put(subType, subset); } subset.add(lib); } } } } } } public List getRenderers() { return renderersList; } public RendererLibrary getDefaultRenderer(DisplayerType displayerType) { return renderersDefault.get(displayerType); } public void setDefaultRenderer(DisplayerType displayerType, String rendererName) { renderersDefault.put(displayerType, getRendererByUUID(rendererName)); } public List getRenderersForType(DisplayerType displayerType) { return renderersByType.getOrDefault(displayerType, new ArrayList<>()); } public List getRenderersForType(DisplayerType type, DisplayerSubType subType) { List types = renderersByType.getOrDefault(type, Collections.emptyList()); List subTypes = renderersBySubType.getOrDefault(subType, Collections.emptyList()); if (type == null) { return subType == null ? renderersList : subTypes; } else if (subType == null) { return types; } else { List result = new ArrayList(subTypes); Iterator it = result.iterator(); while (it.hasNext()) { RendererLibrary rl = it.next(); if (!types.contains(rl)) { it.remove(); } } return result; } } public RendererLibrary getRendererByUUID(String renderer) { return getRendererByOrThrowError(renderer, lib -> lib.getUUID().equals(renderer)); } private RendererLibrary _getRendererByUUID(String renderer) { for (RendererLibrary lib : renderersList) { if (lib.getUUID().equals(renderer)) { return lib; } } return null; } public RendererLibrary getRendererByName(String renderer) { return getRendererByOrThrowError(renderer, lib -> lib.getName().equals(renderer)); } private RendererLibrary getRendererByOrThrowError(String renderer, Predicate test) { return renderersList.stream() .filter(test) .findFirst() .orElseThrow(() -> new RuntimeException(i18n.rendererliblocator_renderer_not_found(renderer))); } public RendererLibrary getRendererForType(DisplayerType displayerType) { return renderersDefault.getOrDefault(displayerType, renderersByType.get(displayerType).get(0)); } public RendererLibrary getRendererForDisplayer(DisplayerSettings target) { // Get the renderer specified if (!StringUtils.isBlank(target.getRenderer())) { RendererLibrary targetRenderer = _getRendererByUUID(target.getRenderer()); if (targetRenderer != null) return targetRenderer; } // Return always the renderer declared as default List renderersSupported = getRenderersForType(target.getType(), target.getSubtype()); RendererLibrary defaultRenderer = getDefaultRenderer(target.getType()); for (RendererLibrary rendererLibrary : renderersSupported) { if (defaultRenderer != null && rendererLibrary.equals(defaultRenderer)) { return defaultRenderer; } } // If no default then return the first supported one if (!renderersSupported.isEmpty()) return renderersSupported.get(0); throw new RuntimeException(i18n.renderermanager_renderer_not_available(target.getType().name())); } public boolean isTypeSupported(DisplayerType type) { return !getRenderersForType(type).isEmpty(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/component/ExternalComponentDispatcher.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import elemental2.core.JsMap; import elemental2.dom.DomGlobal; import elemental2.dom.MessageEvent; import jsinterop.base.Js; import org.dashbuilder.displayer.client.component.function.ComponentFunctionLocator; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.displayer.external.ExternalComponentFunction; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.dashbuilder.displayer.external.ExternalComponentMessageType; import org.dashbuilder.displayer.external.FunctionCallRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Listen to all component messages and find the destination. * */ @ApplicationScoped public class ExternalComponentDispatcher { private static final CommonConstants i18n = CommonConstants.INSTANCE; private static final Logger LOGGER = LoggerFactory.getLogger(ExternalComponentDispatcher.class); @Inject ExternalComponentMessageHelper messageHelper; @Inject ComponentFunctionLocator functionLocator; Set listeners; @PostConstruct public void setup() { listeners = new HashSet<>(); startListening(); } public void register(ExternalComponentListener listener) { // make the component listener ready by default listener.prepare(); listeners.add(listener); } public void unregister(ExternalComponentListener listener) { listeners.remove(listener); } public void onMessage(ExternalComponentMessage message) { ExternalComponentMessageType type = messageHelper.messageType(message); switch (type) { case FILTER: handleFilter(message); break; case FUNCTION_CALL: handleFunction(message); break; case READY: handleReady(message); break; case FIX_CONFIGURATION: handleConfiguration(message); break; case CONFIGURATION_OK: handleOkConfiguration(message); break; default: break; } } private void handleOkConfiguration(ExternalComponentMessage message) { findDestination(message, ExternalComponentListener::configurationOk); } private void handleConfiguration(ExternalComponentMessage message) { findDestination(message, destination -> destination.onConfigurationIssue(messageHelper.getConfigurationIssue(message) .orElse(i18n.componentConfigDefaultMessage()))); } private void handleFunction(ExternalComponentMessage message) { findDestination(message, destination -> { Optional functionCallOp = messageHelper.functionCallRequest(message); if (functionCallOp.isPresent()) { callFunction(destination, functionCallOp.get()); } else { destination.sendMessage(messageHelper.newFunctionRequestNotFound()); } }); } private void callFunction(ExternalComponentListener destination, FunctionCallRequest functionCallRequest) { Optional target = functionLocator.findFunctionByName(functionCallRequest.getFunctionName()); if (target.isPresent()) { execFunction(target.get(), functionCallRequest, destination::sendMessage); } else { destination.sendMessage(messageHelper.newFunctionNotFound(functionCallRequest)); } } private void execFunction(ExternalComponentFunction target, FunctionCallRequest functionCallRequest, Consumer consumeResult) { try { Map params = extractParams(functionCallRequest); target.exec(params, result -> consumeResult.accept(messageHelper.newFunctionSuccess(functionCallRequest, result)), error -> consumeResult.accept(messageHelper.newFunctionError(functionCallRequest, error))); } catch (Exception e) { consumeResult.accept(messageHelper.newFunctionError(functionCallRequest, e.getMessage())); } } private Map extractParams(FunctionCallRequest functionCallRequest) { Map params = new HashMap<>(); JsMap requestParams = functionCallRequest.getParameters(); if (requestParams != null) { requestParams.forEach((v, k, m) -> params.put(k, v)); } return params; } private void handleReady(ExternalComponentMessage message) { findDestination(message, ExternalComponentListener::prepare); } private void handleFilter(ExternalComponentMessage message) { findDestination(message, listener -> messageHelper.filterRequest(message).ifPresent(listener::onFilter)); } private void findDestination(ExternalComponentMessage message, Consumer consumeDestination) { Optional destinationOp = messageHelper.getComponentId(message) .flatMap(id -> listeners.stream() .filter(listener -> listener.getId().equals(id)) .findAny()); destinationOp.ifPresent(consumeDestination); if (!destinationOp.isPresent()) { LOGGER.warn("Ignoring message, destination not found."); } } private void startListening() { DomGlobal.window.addEventListener("message", e -> { MessageEvent event = Js.cast(e); if (event.data instanceof ExternalComponentMessage) { this.onMessage(Js.cast(event.data)); } }); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/component/ExternalComponentListener.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalFilterRequest; /** * Defines a contract for classes that want to listen for components messages. * */ public interface ExternalComponentListener { String getId(); void sendMessage(ExternalComponentMessage message); void onFilter(ExternalFilterRequest filterRequest); void onConfigurationIssue(String message); void prepare(); void configurationOk(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/component/ExternalComponentMessageHelperProducer.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; /** * Produce the helper for messages. * */ @ApplicationScoped public class ExternalComponentMessageHelperProducer { @Produces public ExternalComponentMessageHelper produce() { return new ExternalComponentMessageHelper(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/component/function/BackendFunctionLoader.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component.function; import java.util.List; import java.util.Map; import java.util.function.Consumer; import javax.annotation.PostConstruct; import javax.inject.Inject; import org.dashbuilder.displayer.external.ExternalComponentFunction; import org.dashbuilder.external.service.BackendComponentFunctionService; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.ioc.client.api.EntryPoint; /** * Generated wrapped client functions to proxy the call using BackendFunctionLoaderService. * */ @EntryPoint public class BackendFunctionLoader { private static final String UNKNOWN_BACKEND_ERROR = "Unknown backend error."; @Inject ComponentFunctionLocator componentFunctionLocator; @Inject Caller backendFunctionLoaderService; @PostConstruct public void loadBackendFunctions() { backendFunctionLoaderService.call((List result) -> this.registerFunctions(result)).listFunctions(); } private void registerFunctions(List result) { result.forEach(name -> componentFunctionLocator.registerFunction(new ExternalComponentFunction() { @Override public String getName() { return name; } @Override public void exec(Map params, Consumer onFinish, Consumer onError) { backendFunctionLoaderService.call(onFinish::accept, (Object message, Throwable throwable) -> { String errorMessage = UNKNOWN_BACKEND_ERROR; if (throwable != null && throwable.getMessage() != null) { errorMessage = throwable.getMessage(); } else if (message != null) { errorMessage = message.toString(); } onError.accept(errorMessage); return false; }).callFunction(name, params); } })); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/component/function/ComponentFunctionLocator.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component.function; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import elemental2.core.JsArray; import elemental2.dom.DomGlobal; import org.dashbuilder.displayer.external.ExternalComponentFunction; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** * Looks for components functions * */ @ApplicationScoped public class ComponentFunctionLocator { @Inject SyncBeanManager beanManager; List functions; @PostConstruct void loadFunctions() { functions = beanManager.lookupBeans(ExternalComponentFunction.class) .stream() .map(SyncBeanDef::getInstance) .collect(Collectors.toList()); DomGlobal.console.log("Registered " + functions.size() + " functions"); } public Optional findFunctionByName(String name) { return functions.stream().filter(f -> name.equals(f.getName())).findAny(); } public void registerFunction(ExternalComponentFunction function) { functions.add(function); } public JsArray listFunctions() { JsArray array = new JsArray<>(); functions.stream().map(ExternalComponentFunction::getName).forEach(array::push); return array; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/component/function/GWTVersion.java ================================================ package org.dashbuilder.displayer.client.component.function; import java.util.Map; import java.util.function.Consumer; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import org.dashbuilder.displayer.external.ExternalComponentFunction; /** * Returns GWT Version * */ @Dependent public class GWTVersion implements ExternalComponentFunction { @Override public void exec(Map params, Consumer onFinish, Consumer onError) { onFinish.accept(GWT.getVersion()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/component/function/ListFunctions.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component.function; import java.util.Map; import java.util.function.Consumer; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.displayer.external.ExternalComponentFunction; /** * A meta function to list available functions. * */ @Dependent public class ListFunctions implements ExternalComponentFunction { @Inject ComponentFunctionLocator locator; @Override public void exec(Map params, Consumer onFinish, Consumer onError) { onFinish.accept(locator.listFunctions()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/ColumnDetailsChangedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.dataset.group.GroupFunction; public class ColumnDetailsChangedEvent { GroupFunction columnFunction; public ColumnDetailsChangedEvent() { } public ColumnDetailsChangedEvent(GroupFunction columnFunction) { this.columnFunction = columnFunction; } public GroupFunction getColumnFunction() { return columnFunction; } public void setColumnFunction(GroupFunction columnFunction) { this.columnFunction = columnFunction; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/ColumnFilterChangedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.displayer.client.widgets.filter.ColumnFilterEditor; public class ColumnFilterChangedEvent { ColumnFilterEditor columnFilterEditor; public ColumnFilterChangedEvent() { } public ColumnFilterChangedEvent(ColumnFilterEditor columnFilterEditor) { this.columnFilterEditor = columnFilterEditor; } public ColumnFilterEditor getColumnFilterEditor() { return columnFilterEditor; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/ColumnFilterDeletedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.displayer.client.widgets.filter.ColumnFilterEditor; public class ColumnFilterDeletedEvent { ColumnFilterEditor columnFilterEditor; public ColumnFilterDeletedEvent() { } public ColumnFilterDeletedEvent(ColumnFilterEditor columnFilterEditor) { this.columnFilterEditor = columnFilterEditor; } public ColumnFilterEditor getColumnFilterEditor() { return columnFilterEditor; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DataSetFilterChangedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.dataset.filter.DataSetFilter; public class DataSetFilterChangedEvent { DataSetFilter filter; public DataSetFilterChangedEvent() { } public DataSetFilterChangedEvent(DataSetFilter filter) { this.filter = filter; } public DataSetFilter getFilter() { return filter; } public void setFilter(DataSetFilter filter) { this.filter = filter; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DataSetGroupDateChanged.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.dataset.group.ColumnGroup; public class DataSetGroupDateChanged { ColumnGroup columnGroup; public DataSetGroupDateChanged() { } public DataSetGroupDateChanged(ColumnGroup columnGroup) { this.columnGroup = columnGroup; } public ColumnGroup getColumnGroup() { return columnGroup; } public void setColumnGroup(ColumnGroup columnGroup) { this.columnGroup = columnGroup; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DataSetLookupChangedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.dataset.DataSetLookup; public class DataSetLookupChangedEvent { DataSetLookup dataSetLookup; public DataSetLookupChangedEvent() { } public DataSetLookupChangedEvent(DataSetLookup dataSetLookup) { this.dataSetLookup = dataSetLookup; } public DataSetLookup getDataSetLookup() { return dataSetLookup; } public void setDataSetLookup(DataSetLookup dataSetLookup) { this.dataSetLookup = dataSetLookup; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DisplayerEditorClosedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.displayer.DisplayerSettings; public class DisplayerEditorClosedEvent { DisplayerSettings displayerSettings; public DisplayerEditorClosedEvent() { } public DisplayerEditorClosedEvent(DisplayerSettings displayerSettings) { this.displayerSettings = displayerSettings; } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public void setDisplayerSettings(DisplayerSettings displayerSettings) { this.displayerSettings = displayerSettings; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DisplayerEditorSavedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.displayer.DisplayerSettings; public class DisplayerEditorSavedEvent { DisplayerSettings displayerSettings; public DisplayerEditorSavedEvent() { } public DisplayerEditorSavedEvent(DisplayerSettings displayerSettings) { this.displayerSettings = displayerSettings; } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public void setDisplayerSettings(DisplayerSettings displayerSettings) { this.displayerSettings = displayerSettings; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DisplayerSettingsChangedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.displayer.DisplayerSettings; public class DisplayerSettingsChangedEvent { DisplayerSettings displayerSettings; public DisplayerSettingsChangedEvent() { } public DisplayerSettingsChangedEvent(DisplayerSettings displayerSettings) { this.displayerSettings = displayerSettings; } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public void setDisplayerSettings(DisplayerSettings displayerSettings) { this.displayerSettings = displayerSettings; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DisplayerSubtypeSelectedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.displayer.DisplayerSubType; public class DisplayerSubtypeSelectedEvent { DisplayerSubType selectedSubType; public DisplayerSubtypeSelectedEvent() { } public DisplayerSubtypeSelectedEvent(DisplayerSubType selectedSubType) { this.selectedSubType = selectedSubType; } public DisplayerSubType getSelectedSubType() { return selectedSubType; } public void setSelectedSubType(DisplayerSubType selectedSubType) { this.selectedSubType = selectedSubType; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/DisplayerTypeSelectedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.displayer.DisplayerType; public class DisplayerTypeSelectedEvent { DisplayerType selectedType; public DisplayerTypeSelectedEvent() { } public DisplayerTypeSelectedEvent(DisplayerType selectedType) { this.selectedType = selectedType; } public DisplayerType getSelectedType() { return selectedType; } public void setSelectedType(DisplayerType selectedType) { this.selectedType = selectedType; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/GroupFunctionChangedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.dataset.group.GroupFunction; public class GroupFunctionChangedEvent { GroupFunction groupFunction; public GroupFunctionChangedEvent() { } public GroupFunctionChangedEvent(GroupFunction groupFunction) { this.groupFunction = groupFunction; } public GroupFunction getGroupFunction() { return groupFunction; } public void setGroupFunction(GroupFunction groupFunction) { this.groupFunction = groupFunction; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/events/GroupFunctionDeletedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.events; import org.dashbuilder.dataset.group.GroupFunction; public class GroupFunctionDeletedEvent { GroupFunction groupFunction; public GroupFunctionDeletedEvent() { } public GroupFunctionDeletedEvent(GroupFunction groupFunction) { this.groupFunction = groupFunction; } public GroupFunction getGroupFunction() { return groupFunction; } public void setGroupFunction(GroupFunction groupFunction) { this.groupFunction = groupFunction; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/export/ExportCallback.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.export; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.displayer.client.Displayer; /** * Interface for capturing the results of a {@link Displayer#export(ExportFormat, int, ExportCallback)} request */ public interface ExportCallback { void noData(); void tooManyRows(int rowNum); void exportFileUrl(String url); void error(ClientRuntimeError error); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/export/ExportFormat.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.export; public enum ExportFormat { CSV, XLS; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/formatter/AbstractValueFormatter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.formatter; import org.dashbuilder.dataset.DataSet; public abstract class AbstractValueFormatter implements ValueFormatter { public String formatValue(DataSet dataSet, int row, int column) { Object value = dataSet.getValueAt(row, column); return formatValue(value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/formatter/ValueFormatter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.formatter; import org.dashbuilder.dataset.DataSet; public interface ValueFormatter { String formatValue(DataSet dataSet, int row, int column); String formatValue(Object value); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/formatter/ValueFormatterRegistry.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.formatter; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class ValueFormatterRegistry { Map> formatterMap = new HashMap>(); public static final String _UNASSIGNED = "_unassigned"; public void register(String columnId, ValueFormatter formatter) { Map m = formatterMap.get(_UNASSIGNED); if (m == null) { m = new HashMap(); formatterMap.put(_UNASSIGNED, m); } m.put(columnId, formatter); } public void register(String displayerUuid, String columnId, ValueFormatter formatter) { Map m = formatterMap.get(displayerUuid); if (m == null) { m = new HashMap(); formatterMap.put(displayerUuid, m); } m.put(columnId, formatter); } public Map get(String displayerUuid) { Map results = new HashMap(); Map m = formatterMap.get(_UNASSIGNED); if (m != null) { results.putAll(m); } m = formatterMap.get(displayerUuid); if (m != null) { results.putAll(m); } return results; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/prototypes/DataSetPrototypes.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.prototypes; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.client.ClientDataSetManager; import org.dashbuilder.dataset.group.AggregateFunctionType; @ApplicationScoped public class DataSetPrototypes { public static final String CITY = "City / Urban area"; public static final String COUNTRY = "Country"; public static final String GDP_2014 = "GDP 2014"; public static final String GDP_2013 = "GDP 2013"; public static final String CONTINENT = "Continent"; public static final String AREA_SIZE = "Area size (km2)"; public static final String DENSITY = "Density (people / km2)"; public static final String REGION = "Region"; public static final String POPULATION = "Population"; ClientDataSetManager dataSetManager; public DataSet getWorldPopulation() { return dataSetManager.getDataSet("worldPopulation"); } public DataSet getTotalPopulation() { return dataSetManager.getDataSet("totalPopulation"); } public DataSet getCountryPopulation() { return dataSetManager.getDataSet("countryPopulation"); } public DataSet getTopRichCountries() { return dataSetManager.getDataSet("topRichCountries"); } public DataSet getContinentPopulation() { return dataSetManager.getDataSet("continentPopulation"); } public DataSet getPopulationLimits() { return dataSetManager.getDataSet("populationLimits"); } public DataSet getContinentPopulationExt() { return dataSetManager.getDataSet("continentPopulationExt"); } public DataSetPrototypes() { } @Inject public DataSetPrototypes(ClientDataSetManager dataSetManager) { this.dataSetManager = dataSetManager; init(); } public void init() { dataSetManager.registerDataSet(DataSetFactory .newDataSetBuilder() .uuid("topRichCountries") .label(COUNTRY) .number(GDP_2013) .number(GDP_2014) .row("United States", 16768100L, 17418925L) .row("China", 9240270L, 1038080L) .row("Japan", 4919563L, 4616335L) .row("Germany", 3730261L, 3859547L) .row("United Kingdom", 2678455L, 2945146L) .row("France", 2806428L, 2846889L) .row("Brazil", 2245673L, 2353025L) .buildDataSet()); dataSetManager.registerDataSet(DataSetFactory .newDataSetBuilder() .uuid("continentPopulation") .label(CONTINENT) .number(POPULATION) .row("Asia", 4298723000L) .row("Africa", 1110635000L) .row("North America", 972005000L) .row("South America", 972005000L) .row("Europe", 742452000L) .row("Oceania", 38304000L) .buildDataSet()); dataSetManager.registerDataSet(DataSetFactory .newDataSetBuilder() .uuid("populationLimits") .number(POPULATION) .number(POPULATION + "_max") .row(38304000L, 4298723000L) .buildDataSet()); dataSetManager.registerDataSet(DataSetFactory .newDataSetBuilder() .uuid("totalPopulation") .number(POPULATION) .row(42987L) .buildDataSet()); dataSetManager.registerDataSet(DataSetFactory .newDataSetBuilder() .uuid("continentPopulationExt") .label(CONTINENT) .number(AREA_SIZE) .number(DENSITY) .label(REGION) .number(POPULATION) .row("Asia", 43820000L, 95.0, "Asia", 4298723000L) .row("Africa", 30370000L, 33.7, "Africa", 1110635000L) .row("North America", 24490000L, 22.1, "North America", 972005000L) .row("South America", 17840000L, 22.0, "South America", 972005000L) .row("Europe", 10180000L, 72.5, "Europe", 742452000L) .row("Oceania", 9008500L, 3.2, "Oceania", 38304000L) .buildDataSet()); dataSetManager.registerDataSet(DataSetFactory .newDataSetBuilder() .uuid("worldPopulation") .label(CITY) .label(COUNTRY) .number(POPULATION) .number(AREA_SIZE) .number(DENSITY) .row("Tokyo/Yokohama", "Japan", 33200000L, 6993L, 4750L) .row("New York Metro", "USA", 17800000L, 8683L, 2050L) .row("Sao Paulo", "Brazil", 17700000L, 1968L, 9000L) .row("Seoul/Incheon", "South Korea", 17500000L, 1049L, 16700L) .row("Mexico City", "Mexico", 17400000L, 2072L, 8400L) .row("Osaka/Kobe/Kyoto", "Japan", 16425000L, 2564L, 6400L) .row("Manila", "Philippines", 14750000L, 1399L, 10550L) .row("Mumbai", "India", 14350000L, 484L, 29650L) .row("Delhi", "India", 14300000L, 1295L, 11050L) .row("Jakarta", "Indonesia", 14250000L, 1360L, 10500L) .row("Lagos", "Nigeria", 13400000L, 738L, 18150L) .row("Kolkata", "India", 12700000L, 531L, 23900L) .row("Cairo", "Egypt", 12200000L, 1295L, 9400L) .row("Los Angeles", "USA", 11789000L, 4320L, 2750L) .row("Buenos Aires", "Argentina", 11200000L, 2266L, 4950L) .row("Rio de Janeiro", "Brazil", 10800000L, 1580L, 6850L) .row("Moscow", "Russia", 10500000L, 2150L, 4900L) .row("Shanghai", "China", 10000000L, 746L, 13400L) .row("Karachi", "Pakistan", 9800000L, 518L, 18900L) .row("Paris", "France", 9645000L, 2723L, 3550L) .row("Istanbul", "Turkey", 9000000L, 1166L, 7700L) .row("Nagoya", "Japan", 9000000L, 2875L, 3150L) .row("Beijing", "China", 8614000L, 748L, 11500L) .row("Chicago", "USA", 8308000L, 5498L, 1500L) .row("London", "UK", 8278000L, 1623L, 5100L) .row("Shenzhen", "China", 8000000L, 466L, 17150L) .row("Essen/D�sseldorf", "Germany", 7350000L, 2642L, 2800L) .row("Tehran", "Iran", 7250000L, 686L, 10550L) .row("Bogota", "Colombia", 7000000L, 518L, 13500L) .row("Lima", "Peru", 7000000L, 596L, 11750L) .row("Bangkok", "Thailand", 6500000L, 1010L, 6450L) .row("Johannesburg/East Rand", "South Africa", 6000000L, 2396L, 2500L) .row("Chennai", "India", 5950000L, 414L, 14350L) .row("Taipei", "Taiwan", 5700000L, 376L, 15200L) .row("Baghdad", "Iraq", 5500000L, 596L, 9250L) .row("Santiago", "Chile", 5425000L, 648L, 8400L) .row("Bangalore", "India", 5400000L, 534L, 10100L) .row("Hyderabad", "India", 5300000L, 583L, 9100L) .row("St Petersburg", "Russia", 5300000L, 622L, 8550L) .row("Philadelphia", "USA", 5149000L, 4661L, 1100L) .row("Lahore", "Pakistan", 5100000L, 622L, 8200L) .row("Kinshasa", "Congo", 5000000L, 469L, 10650L) .row("Miami", "USA", 4919000L, 2891L, 1700L) .row("Ho Chi Minh City", "Vietnam", 4900000L, 518L, 9450L) .row("Madrid", "Spain", 4900000L, 945L, 5200L) .row("Tianjin", "China", 4750000L, 453L, 10500L) .row("Kuala Lumpur", "Malaysia", 4400000L, 1606L, 2750L) .row("Toronto", "Canada", 4367000L, 1655L, 2650L) .row("Milan", "Italy", 4250000L, 1554L, 2750L) .row("Shenyang", "China", 4200000L, 453L, 9250L) .row("Dallas/Fort Worth", "USA", 4146000L, 3644L, 1150L) .row("Boston", "USA", 4032000L, 4497L, 900L) .row("Belo Horizonte", "Brazil", 4000000L, 868L, 4600L) .row("Khartoum", "Sudan", 4000000L, 583L, 6850L) .row("Riyadh", "Saudi Arabia", 4000000L, 1101L, 3650L) .row("Singapore", "Singapore", 4000000L, 479L, 8350L) .row("Washington", "USA", 3934000L, 2996L, 1300L) .row("Detroit", "USA", 3903000L, 3267L, 1200L) .row("Barcelona", "Spain", 3900000L, 803L, 4850L) .row("Houston", "USA", 3823000L, 3355L, 1150L) .row("Athens", "Greece", 3685000L, 684L, 5400L) .row("Berlin", "Germany", 3675000L, 984L, 3750L) .row("Sydney", "Australia", 3502000L, 1687L, 2100L) .row("Atlanta", "USA", 3500000L, 5083L, 700L) .row("Guadalajara", "Mexico", 3500000L, 596L, 5900L) .row("San Francisco/Oakland", "USA", 3229000L, 1365L, 2350L) .row("Montreal.", "Canada", 3216000L, 1740L, 1850L) .row("Monterey", "Mexico", 3200000L, 479L, 6700L) .row("Melbourne", "Australia", 3162000L, 2080L, 1500L) .row("Ankara", "Turkey", 3100000L, 583L, 5300L) .row("Recife", "Brazil", 3025000L, 376L, 8050L) .row("Phoenix/Mesa", "USA", 2907000L, 2069L, 1400L) .row("Durban", "South Africa", 2900000L, 829L, 3500L) .row("Porto Alegre", "Brazil", 2800000L, 583L, 4800L) .row("Dalian", "China", 2750000L, 389L, 7100L) .row("Jeddah", "Saudi Arabia", 2750000L, 777L, 3550L) .row("Seattle", "USA", 2712000L, 2470L, 1100L) .row("Cape Town", "South Africa", 2700000L, 686L, 3950L) .row("San Diego", "USA", 2674000L, 2026L, 1300L) .row("Fortaleza", "Brazil", 2650000L, 583L, 4550L) .row("Curitiba", "Brazil", 2500000L, 648L, 3850L) .row("Rome", "Italy", 2500000L, 842L, 2950L) .row("Naples", "Italy", 2400000L, 583L, 4100L) .row("Minneapolis/St. Paul", "USA", 2389000L, 2316L, 1050L) .row("Tel Aviv", "Israel", 2300000L, 453L, 5050L) .row("Birmingham", "UK", 2284000L, 600L, 3800L) .row("Frankfurt", "Germany", 2260000L, 984L, 2300L) .row("Lisbon", "Portugal", 2250000L, 881L, 2550L) .row("Manchester", "UK", 2245000L, 558L, 4000L) .row("San Juan", "Puerto Rico", 2217000L, 2309L, 950L) .row("Katowice", "Poland", 2200000L, 544L, 4050L) .row("Tashkent", "Uzbekistan", 2200000L, 531L, 4150L) .row("Fukuoka", "Japan", 2150000L, 544L, 3950L) .row("Baku/Sumqayit", "Azerbaijan", 2100000L, 544L, 3850L) .row("St. Louis", "USA", 2078000L, 2147L, 950L) .row("Baltimore", "USA", 2076000L, 1768L, 1150L) .row("Sapporo", "Japan", 2075000L, 414L, 5000L) .row("Tampa/St. Petersburg", "USA", 2062000L, 2078L, 1000L) .row("Taichung", "Taiwan", 2000000L, 510L, 3900L) .row("Warsaw", "Poland", 2000000L, 466L, 4300L) .row("Denver", "USA", 1985000L, 1292L, 1550L) .row("Cologne/Bonn", "Germany", 1960000L, 816L, 2400L) .row("Hamburg", "Germany", 1925000L, 829L, 2300L) .row("Dubai", "UAE", 1900000L, 712L, 2650L) .row("Pretoria", "South Africa", 1850000L, 673L, 2750L) .row("Vancouver", "Canada", 1830000L, 1120L, 1650L) .row("Beirut", "Lebanon", 1800000L, 648L, 2800L) .row("Budapest", "Hungary", 1800000L, 702L, 2550L) .row("Cleveland", "USA", 1787000L, 1676L, 1050L) .row("Pittsburgh", "USA", 1753000L, 2208L, 800L) .row("Campinas", "Brazil", 1750000L, 492L, 3550L) .row("Harare", "Zimbabwe", 1750000L, 712L, 2450L) .row("Brasilia", "Brazil", 1625000L, 583L, 2800L) .row("Kuwait", "Kuwait", 1600000L, 544L, 2950L) .row("Munich", "Germany", 1600000L, 518L, 3100L) .row("Portland", "USA", 1583000L, 1228L, 1300L) .row("Brussels", "Belgium", 1570000L, 712L, 2200L) .row("Vienna", "Austria", 1550000L, 453L, 3400L) .row("San Jose", "USA", 1538000L, 674L, 2300L) .row("Damman", "Saudi Arabia", 1525000L, 673L, 2250L) .row("Copenhagen", "Denmark", 1525000L, 816L, 1850L) .row("Brisbane", "Australia", 1508000L, 1603L, 950L) .row("Riverside/San Bernardino", "USA", 1507000L, 1136L, 1350L) .row("Cincinnati", "USA", 1503000L, 1740L, 850L) .row("Accra", "Ghana", 1500000L, 453L, 3300L) .buildDataSet()); DataSet result = dataSetManager.lookupDataSet( DataSetFactory.newDataSetLookupBuilder() .dataset("worldPopulation") .group(COUNTRY) .column(COUNTRY) .column(POPULATION, AggregateFunctionType.SUM) .column(AREA_SIZE, AggregateFunctionType.SUM) .buildLookup()); result.setUUID("countryPopulation"); dataSetManager.registerDataSet(result); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/prototypes/DisplayerPrototypes.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.prototypes; import java.util.EnumMap; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.dataset.uuid.UUIDGenerator; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.MapColorScheme; import static org.dashbuilder.displayer.client.prototypes.DataSetPrototypes.*; @ApplicationScoped public class DisplayerPrototypes { protected DataSetPrototypes dataSetPrototypes; protected UUIDGenerator uuidGenerator; protected Map prototypeMap = new EnumMap<>(DisplayerType.class); protected Map subprotoMap = new EnumMap<>(DisplayerSubType.class); public DisplayerPrototypes() { } @Inject public DisplayerPrototypes(DataSetPrototypes dataSetPrototypes, UUIDGenerator uuidGenerator) { this.dataSetPrototypes = dataSetPrototypes; this.uuidGenerator = uuidGenerator; init(); } public void init() { prototypeMap.put(DisplayerType.PIECHART, DisplayerSettingsFactory .newPieChartSettings() .uuid("pieChartPrototype") .dataset(dataSetPrototypes.getContinentPopulation()) .title("Population per Continent") .titleVisible(false) .column(POPULATION) .expression("value/1000000") .format("Population", "#,### M") .width(500).height(300) .margins(10, 10, 10, 100) .legendOn("right") .set3d(true) .filterOn(false, true, true) .buildSettings()); prototypeMap.put(DisplayerType.BARCHART, DisplayerSettingsFactory .newBarChartSettings() .subType_Bar() .uuid("barChartPrototype") .dataset(dataSetPrototypes.getTopRichCountries()) .title("Top Rich Countries") .titleVisible(false) .column(COUNTRY).format("Country") .column(GDP_2013).format("2013", "$ #,### M") .column(GDP_2014).format("2014", "$ #,### M") .width(500).height(250) .margins(10, 40, 100, 50) .legendOn("right") .filterOn(false, true, true) .buildSettings()); prototypeMap.put(DisplayerType.LINECHART, DisplayerSettingsFactory .newLineChartSettings() .uuid("lineChartPrototype") .dataset(dataSetPrototypes.getContinentPopulation()) .title("Population per Continent") .titleVisible(false) .column(POPULATION) .expression("value/1000000") .format("Population", "#,### M") .width(500).height(300) .margins(10, 40, 90, 10) .legendOff() .filterOn(false, true, true) .buildSettings()); prototypeMap.put(DisplayerType.AREACHART, DisplayerSettingsFactory .newAreaChartSettings() .uuid("areaChartPrototype") .dataset(dataSetPrototypes.getContinentPopulation()) .title("Population per Continent") .titleVisible(false) .column(POPULATION) .expression("value/1000000") .format("Population", "#,### M") .width(500).height(300) .margins(10, 40, 90, 10) .legendOff() .filterOn(false, true, true) .buildSettings()); prototypeMap.put(DisplayerType.BUBBLECHART, DisplayerSettingsFactory .newBubbleChartSettings() .uuid("bubbleChartPrototype") .dataset(dataSetPrototypes.getContinentPopulationExt()) .title("Population per Continent") .titleVisible(false) .width(500).height(300) .margins(10, 30, 50, 10) .legendOff() .filterOn(false, true, true) .buildSettings()); prototypeMap.put(DisplayerType.METERCHART, DisplayerSettingsFactory .newMeterChartSettings() .uuid("meterChartPrototype") .dataset(dataSetPrototypes.getContinentPopulation()) .title("Population per Continent") .titleVisible(false) .width(400).height(300) .column(POPULATION) .expression("value/1000000") .format("Population", "#,### M") .margins(10, 10, 10, 10) .meter(0, 1000L, 3000L, 6000L) .filterOn(false, true, true) .buildSettings()); DisplayerSettings metricCard = DisplayerSettingsFactory .newMetricSettings() .uuid("metricCardPrototype") .dataset(dataSetPrototypes.getTotalPopulation()) .column(POPULATION).format("Population", "#,##0 MM") .subtype(DisplayerSubType.METRIC_CARD) .title("World population") .titleVisible(true) .width(200).height(100) .margins(0, 0, 0, 0) .backgroundColor("white") .filterOn(false, false, true) .htmlTemplate("
\n" + "

${title}

\n" + "

${value}

\n" + "
") .jsTemplate("if (${isFilterEnabled}) { \n" + " var filterOn = false;\n" + " ${this}.style.cursor=\"pointer\";\n" + "\n" + " ${this}.onmouseover = function() {\n" + " if (!filterOn) ${this}.style.backgroundColor = \"lightblue\";\n" + " };\n" + " ${this}.onmouseout = function() {\n" + " if (!filterOn) ${this}.style.backgroundColor = \"${bgColor}\";\n" + " };\n" + " ${this}.onclick = function() {\n" + " filterOn = !filterOn;\n" + " ${this}.style.backgroundColor = filterOn ? \"lightblue\" : \"${bgColor}\";\n" + " ${doFilter};\n" + " };\n" + "}") .buildSettings(); DisplayerSettings metricCard2 = DisplayerSettingsFactory .newMetricSettings() .uuid("metricCard2Prototype") .dataset(dataSetPrototypes.getTotalPopulation()) .column(POPULATION).format("Population", "#,##0 MM") .subtype(DisplayerSubType.METRIC_CARD2) .title("World population") .titleVisible(true) .width(200).height(100) .margins(0, 0, 0, 0) .backgroundColor("white") .filterOn(false, false, true) .htmlTemplate("

\n" + " ${title}\n" + "

\n" + "
\n" + "

\n" + " ${value}\n" + " \n" + " people\n" + " in the world\n" + " \n" + "

\n" + "
") .buildSettings(); DisplayerSettings metricQuota = DisplayerSettingsFactory .newMetricSettings() .uuid("metricQuotaPrototype") .dataset(dataSetPrototypes.getTotalPopulation()) .column(POPULATION).format("Population", "#,##0 MM") .subtype(DisplayerSubType.METRIC_QUOTA) .title("World population") .titleVisible(true) .width(200).height(100) .margins(0, 0, 0, 0) .metric(0, 0, 0, 100000) .filterOn(false, false, true) .htmlTemplate("
\n" + " ${title}\n" + "
\n" + "
\n" + "
\n" + " ${value}\n" + "
\n" + "
\n" + "
\n" + "
") .jsTemplate("var end = ${value.end};\n" + "var current = Math.round(${value.raw} * 100 / end);\n" + "${bar}.style.width = current + \"%\";") .buildSettings(); DisplayerSettings metricPlainText = DisplayerSettingsFactory .newMetricSettings() .uuid("metricPlainTextPrototype") .dataset(dataSetPrototypes.getTotalPopulation()) .column(POPULATION).format("Population", "#,##0 MM") .subtype(DisplayerSubType.METRIC_PLAIN_TEXT) .title("World population ") .titleVisible(true) .width(200).height(100) .margins(0, 0, 0, 0) .metric(0, 50000, 75000, 100000) .filterOn(false, false, true) .htmlTemplate("
\n" + " ${title}: ${value}\n" + "
\n") .jsTemplate("if (${value.raw} > ${value.critical}) { \n" + " ${valref}.style.color = \"red\"; \n" + "} else if (${value.raw} > ${value.warning}) { \n" + " ${valref}.style.color = \"yellow\"; \n" + "} else {\n" + " ${valref}.style.color = \"black\";\n" + "}") .buildSettings(); prototypeMap.put(DisplayerType.METRIC, metricCard); subprotoMap.put(DisplayerSubType.METRIC_CARD, metricCard); subprotoMap.put(DisplayerSubType.METRIC_CARD2, metricCard2); subprotoMap.put(DisplayerSubType.METRIC_QUOTA, metricQuota); subprotoMap.put(DisplayerSubType.METRIC_PLAIN_TEXT, metricPlainText); prototypeMap.put(DisplayerType.MAP, DisplayerSettingsFactory .newMapChartSettings() .uuid("mapChartPrototype") .dataset(dataSetPrototypes.getCountryPopulation()) .title("World Population") .titleVisible(false) .width(500).height(300) .margins(10, 10, 10, 10) .filterOn(false, true, true) .colorScheme(MapColorScheme.GREEN) .buildSettings()); prototypeMap.put(DisplayerType.TABLE, DisplayerSettingsFactory .newTableSettings() .uuid("tablePrototype") .dataset(dataSetPrototypes.getWorldPopulation()) .title("Population per Continent") .titleVisible(false) .column(POPULATION) .expression("value/1000000") .format("Population", "#,### M") .tableOrderEnabled(true) .tableOrderDefault(POPULATION, SortOrder.DESCENDING) .tablePageSize(10) .filterOn(false, true, true) .buildSettings()); prototypeMap.put(DisplayerType.EXTERNAL_COMPONENT, DisplayerSettingsFactory .newExternalDisplayerSettings() .uuid("externalComponentPrototype") .dataset(dataSetPrototypes.getTopRichCountries()) .column(COUNTRY).format("Country") .column(GDP_2014) .column(GDP_2013) .buildSettings()); DisplayerSettings selectorDropDown = DisplayerSettingsFactory .newSelectorSettings() .uuid("selectorDropDownPrototype") .dataset(dataSetPrototypes.getTopRichCountries()) .subtype(DisplayerSubType.SELECTOR_DROPDOWN) .title("Country selector").titleVisible(true) .column(COUNTRY).format("Country") .width(200) .multiple(true) .filterOn(false, true, false) .buildSettings(); DisplayerSettings selectorLabels = DisplayerSettingsFactory .newSelectorSettings() .uuid("selectorLabelsPrototype") .dataset(dataSetPrototypes.getTopRichCountries()) .subtype(DisplayerSubType.SELECTOR_LABELS) .title("Country selector").titleVisible(true) .column(COUNTRY).format("Country") .width(-1) .multiple(true) .filterOn(false, true, false) .buildSettings(); DisplayerSettings selectorSlider = DisplayerSettingsFactory .newSelectorSettings() .uuid("selectorSliderPrototype") .dataset(dataSetPrototypes.getPopulationLimits()) .subtype(DisplayerSubType.SELECTOR_SLIDER) .title("World population").titleVisible(true) .column(POPULATION).format("Population", "#,##0 MM").expression("value/1000000") .margins(0, 0, 0, 0) .width(-1) .filterOn(false, true, false) .buildSettings(); prototypeMap.put(DisplayerType.SELECTOR, selectorDropDown); subprotoMap.put(DisplayerSubType.SELECTOR_DROPDOWN, selectorDropDown); subprotoMap.put(DisplayerSubType.SELECTOR_LABELS, selectorLabels); subprotoMap.put(DisplayerSubType.SELECTOR_SLIDER, selectorSlider); } public DisplayerSettings getProto(DisplayerType type) { return getProto(type, null); } public DisplayerSettings getProto(DisplayerType type, DisplayerSubType subType) { boolean hasSubproto = subType != null && subprotoMap.containsKey(subType); DisplayerSettings proto = hasSubproto ? subprotoMap.get(subType) : prototypeMap.get(type); proto = proto.cloneInstance(); proto.setUUID(uuidGenerator.newUuid()); if (subType != null) { proto.setSubtype(subType); } return proto; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/CommonConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface CommonConstants extends Messages { CommonConstants INSTANCE = GWT.create( CommonConstants.class ); String ok(); String cancel(); String error(); String cause(); // Common settings editor literals String dataset_editor_notfound(); String common_button_addnew(); String common_dropdown_select(); String settingsEditor_caption(); String settingsJsonSource_caption(); String common_group(); String common_showTitle(); String common_title(); String common_title_placeholder(); String common_export(); String common_allowCSV(); String common_allowExcel(); String common_renderer(); String common_columns(); String columns_name(); String columns_pattern(); String columns_expression(); String columns_emptyvalue(); String common_columns_placeholder(); String refresh_group(); String refresh_interval(); String refresh_stale_data(); String chart_group(); String chart_width(); String chart_height(); String chart_bgColor(); String chart_marginGroup(); String chart_topMargin(); String chart_bottomMargin(); String chart_leftMargin(); String chart_rightMargin(); String chart_legendGroup(); String chart_legendShow(); String chart_legendPosition(); String chart_3d(); String table_group(); String table_pageSize(); String table_width(); String table_sortEnabled(); String table_sortColumn(); String table_sortColumn_placeholder(); String table_sortOrder(); String table_ascSortOrder(); String table_descSortOrder(); String table_columnPicker(); String axis_group(); String xaxis_showLabels(); String xaxis_angle(); String xaxis_title(); String xaxis_title_placeholder(); String yaxis_showLabels(); String yaxis_angle(); String yaxis_title(); String yaxis_title_placeholder(); String meter_group(); String meter_start(); String meter_warning(); String meter_critical(); String meter_end(); String filter_group(); String filter_enabled(); String filter_self(); String filter_listening(); String filter_notifications(); String selector_group(); String selector_width(); String selector_multiple(); String selector_show_inputs(); String filter_editor_selectcolumn(); String timeframe_from(); String timeframe_to(); String timeframe_first_month_year(); String case_sensitive(); String like_to_pattern_instructions(); String multiple_input_descriptions(); String group_columnid_label(); String dataset_groupdate_fixed_intervals(); String dataset_groupdate_empty_intervals(); String dataset_groupdate_interval_type(); String dataset_groupdate_max_intervals(); String dataset_groupdate_firstday(); String dataset_groupdate_firstmonth(); String settings_validation_integer(); String settings_validation_double(); String settings_validation_meter_unknown(); String settings_validation_meter_higher(String value); String settings_validation_meter_lower(String value); String settings_validation_meter_invalid(); // DataSetLookup editor literals String dataset_dataset(); String dataset_filters(); String dataset_rows(); String dataset_columns(); String dataset_lookup_group_columns_all(); String dataset_lookup_dataset_notfound(String uuid); String dataset_lookup_init_error(); // DisplayerEditor literals String displayer_editor_title(); String displayer_editor_new(); String displayer_editor_dataset_notfound(); String displayer_editor_datasetmetadata_fetcherror(); String displayer_editor_dataset_nolookuprequest(); String displayer_editor_incompatible_settings(); String displayer_editor_tab_type(); String displayer_editor_tab_data(); String displayer_editor_tab_display(); String displayer_editor_view_as_table(); String renderer_selector_title(); String displayerlocator_default_renderer_undeclared(String targetType); String displayerlocator_unsupported_displayer_renderer(String targetType, String rendererUuid); String rendererliblocator_renderer_not_found(String renderer); String rendererliblocator_multiple_renderers_found(String renderer); String expand(); String collapse(); String removeFilter(); String renderermanager_renderer_not_available(String type); String displayerviewer_displayer_not_created(); String chart_resizable(); String map_group(); String color_scheme(); String loadingComponent(); String componentEditor(); String componentNotFound(); String noPropertiesComponent(); String componentConfigDefaultMessage(); String mandatoryHelpHeader(); String mandatoryHelpText(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface DisplayerConstants extends Messages { DisplayerConstants INSTANCE = GWT.create(DisplayerConstants.class); String initializing(); String error(); String error_settings_unset(); String error_handler_unset(); String error_dataset_notfound(); String displayer_keyword_not_allowed(String expr); String displayer_expr_invalid_syntax(String expr); String userDefinedVariableDescription(); String valueRawVariableDescription(); String valueStartVariableDescription(); String valueWarningVariableDescription(); String valueCriticalVariableDescription(); String valueEndVariableDescription(); String valueVariableDescription(); String titleVariableDescription(); String widthVariableDescription(); String heightVariableDescription(); String marginTopVariableDescription(); String marginBottomVariableDescription(); String marginRightVariableDescription(); String marginLeftVariableDescription(); String bgColorVariableDescription(); String isFilterEnabledVariableDescription(); String isFilterOnVariableDescription(); String isEmptyVariableDescription(); String doFilterVariableDescription(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/DisplayerHtmlConstants.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface DisplayerHtmlConstants extends ConstantsWithLookup { DisplayerHtmlConstants INSTANCE = GWT.create(DisplayerHtmlConstants.class); String displayer_html_preview_link(); String displayer_source_code_html(); String displayer_source_code_javascript(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface DisplayerTypeConstants extends ConstantsWithLookup { DisplayerTypeConstants INSTANCE = GWT.create(DisplayerTypeConstants.class); String displayer_type_selector_tab_bar(); String displayer_type_selector_tab_pie(); String displayer_type_selector_tab_line(); String displayer_type_selector_tab_area(); String displayer_type_selector_tab_bubble(); String displayer_type_selector_tab_meter(); String displayer_type_selector_tab_metric(); String displayer_type_selector_tab_map(); String displayer_type_selector_tab_table(); String displayer_type_selector_tab_selector(); // Subtype enum literals String DISPLAYER_SUBTYPE_LINE(); String DISPLAYER_SUBTYPE_SMOOTH(); String DISPLAYER_SUBTYPE_AREA(); String DISPLAYER_SUBTYPE_STACKED(); String DISPLAYER_SUBTYPE_STEPPED(); String DISPLAYER_SUBTYPE_BAR(); String DISPLAYER_SUBTYPE_BAR_STACKED(); String DISPLAYER_SUBTYPE_COLUMN(); String DISPLAYER_SUBTYPE_COLUMN_STACKED(); String DISPLAYER_SUBTYPE_HISTOGRAM(); String DISPLAYER_SUBTYPE_PIE(); String DISPLAYER_SUBTYPE_PIE_3D(); String DISPLAYER_SUBTYPE_DONUT(); String DISPLAYER_SUBTYPE_MAP_REGIONS(); String DISPLAYER_SUBTYPE_MAP_MARKERS(); String DISPLAYER_SUBTYPE_METRIC_CARD(); String DISPLAYER_SUBTYPE_METRIC_CARD2(); String DISPLAYER_SUBTYPE_METRIC_QUOTA(); String DISPLAYER_SUBTYPE_METRIC_PLAIN_TEXT(); String DISPLAYER_SUBTYPE_SELECTOR_DROPDOWN(); String DISPLAYER_SUBTYPE_SELECTOR_LABELS(); String DISPLAYER_SUBTYPE_SELECTOR_SLIDER(); // Subtype selector tooltips String BARCHART_BAR_tt(); String BARCHART_BAR_STACKED_tt(); String BARCHART_COLUMN_tt(); String BARCHART_COLUMN_STACKED_tt(); String PIECHART_PIE_tt(); String PIECHART_PIE_3D_tt(); String PIECHART_DONUT_tt(); String AREACHART_AREA_tt(); String AREACHART_AREA_STACKED_tt(); String LINECHART_LINE_tt(); String LINECHART_SMOOTH_tt(); String MAP_MAP_REGIONS_tt(); String MAP_MAP_MARKERS_tt(); String BUBBLECHART_default_tt(); String METERCHART_default_tt(); String METRIC_METRIC_CARD_tt(); String METRIC_METRIC_CARD2_tt(); String METRIC_METRIC_QUOTA_tt(); String METRIC_METRIC_PLAIN_TEXT_tt(); String TABLE_default_tt(); String EXTERNAL_COMPONENT_default_tt(); String SELECTOR_SELECTOR_DROPDOWN_tt(); String SELECTOR_SELECTOR_LABELS_tt(); String SELECTOR_SELECTOR_SLIDER_tt(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/MapColorSchemeConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface MapColorSchemeConstants extends ConstantsWithLookup { public static final MapColorSchemeConstants INSTANCE = GWT.create(MapColorSchemeConstants.class); // MapColorScheme enum literals String COLOR_SCHEME_RED(); String COLOR_SCHEME_BLUE(); String COLOR_SCHEME_GREEN(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/PositionConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; public interface PositionConstants extends ConstantsWithLookup { public static final PositionConstants INSTANCE = GWT.create(PositionConstants.class); // Position enum literals String POSITION_BOTTOM(); String POSITION_TOP(); String POSITION_LEFT(); String POSITION_RIGHT(); String POSITION_IN(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/SourceCodeEditorConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface SourceCodeEditorConstants extends Messages { SourceCodeEditorConstants INSTANCE = GWT.create( SourceCodeEditorConstants.class ); String add_variable(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/i18n/SourceCodeValidatorConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface SourceCodeValidatorConstants extends Messages { SourceCodeValidatorConstants INSTANCE = GWT.create( SourceCodeValidatorConstants.class ); String js_keyword_not_allowed(String expr); String js_variable_not_found(String var); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/resources/images/DisplayerImagesResources.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.images; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundleWithLookup; import com.google.gwt.resources.client.ImageResource; public interface DisplayerImagesResources extends ClientBundleWithLookup { DisplayerImagesResources INSTANCE = GWT.create(DisplayerImagesResources.class); String DEFAULT_SUFFIX = "_default"; String SELECTED_SUFFIX = "_selected"; String UNSELECTED_SUFFIX = "_unselected"; // Convention for image resource method names: type_subtype_selected/unselected // TODO replace images with own harvest @Source("bar_selected.png") ImageResource BARCHART_BAR_selected(); @Source("bar_unselected.png") ImageResource BARCHART_BAR_unselected(); @Source("bar_stacked_selected.png") ImageResource BARCHART_BAR_STACKED_selected(); @Source("bar_stacked_unselected.png") ImageResource BARCHART_BAR_STACKED_unselected(); @Source("column_selected.png") ImageResource BARCHART_COLUMN_selected(); @Source("column_unselected.png") ImageResource BARCHART_COLUMN_unselected(); @Source("column_stacked_selected.png") ImageResource BARCHART_COLUMN_STACKED_selected(); @Source("column_stacked_unselected.png") ImageResource BARCHART_COLUMN_STACKED_unselected(); @Source("pie_selected.png") ImageResource PIECHART_PIE_selected(); @Source("pie_unselected.png") ImageResource PIECHART_PIE_unselected(); @Source("pie_3d_selected.png") ImageResource PIECHART_PIE_3D_selected(); @Source("pie_3d_unselected.png") ImageResource PIECHART_PIE_3D_unselected(); @Source("donut_selected.png") ImageResource PIECHART_DONUT_selected(); @Source("donut_unselected.png") ImageResource PIECHART_DONUT_unselected(); @Source("area_selected.png") ImageResource AREACHART_AREA_selected(); @Source("area_unselected.png") ImageResource AREACHART_AREA_unselected(); @Source("area_stacked_selected.png") ImageResource AREACHART_AREA_STACKED_selected(); @Source("area_stacked_unselected.png") ImageResource AREACHART_AREA_STACKED_unselected(); @Source("line_selected.png") ImageResource LINECHART_LINE_selected(); @Source("line_unselected.png") ImageResource LINECHART_LINE_unselected(); @Source("line_smooth_selected.png") ImageResource LINECHART_SMOOTH_selected(); @Source("line_smooth_unselected.png") ImageResource LINECHART_SMOOTH_unselected(); @Source("map_regions_selected.png") ImageResource MAP_MAP_REGIONS_selected(); @Source("map_regions_unselected.png") ImageResource MAP_MAP_REGIONS_unselected(); @Source("map_markers_selected.png") ImageResource MAP_MAP_MARKERS_selected(); @Source("map_markers_unselected.png") ImageResource MAP_MAP_MARKERS_unselected(); @Source("bubble_default.png") ImageResource BUBBLECHART_default(); @Source("meter_default.png") ImageResource METERCHART_default(); @Source("metric_card_selected.png") ImageResource METRIC_METRIC_CARD_selected(); @Source("metric_card_unselected.png") ImageResource METRIC_METRIC_CARD_unselected(); @Source("metric_card2_selected.png") ImageResource METRIC_METRIC_CARD2_selected(); @Source("metric_card2_unselected.png") ImageResource METRIC_METRIC_CARD2_unselected(); @Source("metric_quota_selected.png") ImageResource METRIC_METRIC_QUOTA_selected(); @Source("metric_quota_unselected.png") ImageResource METRIC_METRIC_QUOTA_unselected(); @Source("metric_plaintext_selected.png") ImageResource METRIC_METRIC_PLAIN_TEXT_selected(); @Source("metric_plaintext_unselected.png") ImageResource METRIC_METRIC_PLAIN_TEXT_unselected(); @Source("selector_dropdown_selected.png") ImageResource SELECTOR_SELECTOR_DROPDOWN_selected(); @Source("selector_dropdown_unselected.png") ImageResource SELECTOR_SELECTOR_DROPDOWN_unselected(); @Source("selector_labels_selected.png") ImageResource SELECTOR_SELECTOR_LABELS_selected(); @Source("selector_labels_unselected.png") ImageResource SELECTOR_SELECTOR_LABELS_unselected(); @Source("selector_slider_selected.png") ImageResource SELECTOR_SELECTOR_SLIDER_selected(); @Source("selector_slider_unselected.png") ImageResource SELECTOR_SELECTOR_SLIDER_unselected(); @Source("table_default.png") ImageResource TABLE_default(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DataSetLookupEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.DataSetOpType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetMetadataCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.displayer.client.events.DataSetFilterChangedEvent; import org.dashbuilder.displayer.client.events.DataSetGroupDateChanged; import org.dashbuilder.displayer.client.events.DataSetLookupChangedEvent; import org.dashbuilder.displayer.client.events.GroupFunctionChangedEvent; import org.dashbuilder.displayer.client.events.GroupFunctionDeletedEvent; import org.dashbuilder.displayer.client.widgets.filter.DataSetFilterEditor; import org.dashbuilder.displayer.client.widgets.group.ColumnFunctionEditor; import org.dashbuilder.displayer.client.widgets.group.DataSetGroupDateEditor; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberView; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; @Dependent public class DataSetLookupEditor implements IsWidget { public interface View extends UberView { void clearAll(); void clearDataSetSelector(); void enableDataSetSelectorHint(); void addDataSetItem(String name, String id); void removeDataSetItem(int index); void setSelectedDataSetIndex(int index); String getSelectedDataSetId(); void error(ClientRuntimeError error); void errorDataSetNotFound(String dataSetUUID); void setFilterEnabled(boolean enabled); void setGroupEnabled(boolean enabled); void clearGroupColumnSelector(); void setGroupByDateEnabled(boolean enabled); void setGroupColumnSelectorTitle(String title); void enableGroupColumnSelectorHint(); void addGroupColumnItem(String column); void setSelectedGroupColumnIndex(int index); String getSelectedGroupColumnId(); void setColumnsSectionEnabled(boolean enabled); void clearColumnList(); void setColumnSectionTitle(String title); void setAddColumnOptionEnabled(boolean enabled); void addColumnEditor(ColumnFunctionEditor editor); void removeColumnEditor(ColumnFunctionEditor editor); } public interface DataSetDefFilter { boolean accept(DataSetDef def); } View view; SyncBeanManager beanManager; DataSetClientServices clientServices; DataSetFilterEditor filterEditor; DataSetGroupDateEditor groupDateEditor; DataSetLookup dataSetLookup = null; DataSetLookupConstraints lookupConstraints = null; DataSetMetadata dataSetMetadata = null; Event changeEvent = null; List _dataSetDefList = new ArrayList(); Map _editorsMap = new HashMap(); DataSetDefFilter dataSetDefFilter = new DataSetDefFilter() { public boolean accept(DataSetDef def) { return true; } }; @Inject public DataSetLookupEditor(final View view, SyncBeanManager beanManager, DataSetFilterEditor filterEditor, DataSetGroupDateEditor groupDateEditor, DataSetClientServices clientServices, Event event) { this.view = view; this.beanManager = beanManager; this.filterEditor = filterEditor; this.groupDateEditor = groupDateEditor; this.clientServices = clientServices; this.changeEvent = event; this.dataSetLookup = null; this.lookupConstraints = null; this.dataSetMetadata = null; view.init(this); } public void init(DataSetLookupConstraints lookupConstraints, final DataSetLookup dataSetLookup) { this.dataSetLookup = dataSetLookup; this.lookupConstraints = lookupConstraints; this.view.clearAll(); this.clientServices.getPublicDataSetDefs((List dataSetDefs) -> { showDataSetDefs(dataSetDefs); if (dataSetLookup != null && dataSetLookup.getDataSetUUID() != null) { fetchMetadata(dataSetLookup.getDataSetUUID(), (DataSetMetadata metadata) -> updateDataSetLookup()); } }); } void fetchMetadata(final String uuid, final RemoteCallback callback) { try { clientServices.fetchMetadata(uuid, new DataSetMetadataCallback() { public void callback(DataSetMetadata metadata) { dataSetMetadata = metadata; callback.callback(metadata); } public void notFound() { view.errorDataSetNotFound(uuid); } public boolean onError(ClientRuntimeError error) { view.error(error); return false; } }); } catch (Exception e) { view.error(new ClientRuntimeError(e)); } } @Override public Widget asWidget() { return view.asWidget(); } public View getView() { return view; } public DataSetFilterEditor getFilterEditor() { return filterEditor; } public DataSetGroupDateEditor getGroupDateEditor() { return groupDateEditor; } public DataSetLookup getDataSetLookup() { return dataSetLookup; } public DataSetLookupConstraints getLookupConstraints() { return lookupConstraints; } public void setDataSetDefFilter(DataSetDefFilter dataSetDefFilter) { this.dataSetDefFilter = dataSetDefFilter; } public String getDataSetUUID() { return dataSetLookup == null ? null : dataSetLookup.getDataSetUUID(); } public String getColumnId(int index) { return dataSetMetadata.getColumnId(index); } public ColumnType getColumnType(int index) { return dataSetMetadata.getColumnType(index); } public ColumnType getColumnType(String columnId) { return columnId == null ? null : dataSetMetadata.getColumnType(columnId); } public DataSetGroup getFirstGroupOp() { List groupOpList = dataSetLookup.getOperationList(DataSetGroup.class); if (groupOpList.isEmpty()) { return null; } return groupOpList.get(0); } public boolean isFirstGroupOpDateBased() { DataSetGroup first = getFirstGroupOp(); if (first == null) { return false; } ColumnGroup cg = first.getColumnGroup(); if (cg == null) { return false; } ColumnType type = getColumnType(cg.getSourceId()); return ColumnType.DATE.equals(type); } public List getFirstGroupFunctions() { List groupOpList = dataSetLookup.getOperationList(DataSetGroup.class); if (groupOpList.isEmpty()) { return null; } return groupOpList.get(0).getGroupFunctions(); } public int getFirstGroupFunctionIdx(GroupFunction gf) { List groupOpList = dataSetLookup.getOperationList(DataSetGroup.class); if (groupOpList.isEmpty()) { return -1; } return groupOpList.get(0).getGroupFunctionIdx(gf); } public String getFirstGroupColumnId() { List groupOpList = dataSetLookup.getOperationList(DataSetGroup.class); if (groupOpList.isEmpty()) { return null; } DataSetGroup groupOp = groupOpList.get(0); if (groupOp.getColumnGroup() == null) { return null; } return groupOp.getColumnGroup().getSourceId(); } public List getAvailableGroupColumnIdxs() { List result = new ArrayList(); for (int i = 0; i < dataSetMetadata.getNumberOfColumns(); i++) { ColumnType columnType = dataSetMetadata.getColumnType(i); if (ColumnType.LABEL.equals(columnType) || ColumnType.DATE.equals(columnType) || ColumnType.NUMBER.equals(columnType)) { result.add(i); } } return result; } public void showDataSetDefs(List ds) { _dataSetDefList.clear(); view.clearDataSetSelector(); String selectedUUID = getDataSetUUID(); if (StringUtils.isBlank(selectedUUID)) { view.enableDataSetSelectorHint(); } boolean found = false; for (int i = 0; i < ds.size(); i++) { DataSetDef def = ds.get(i); if (dataSetDefFilter.accept(def)) { addDataSetDef(def); if (selectedUUID != null && selectedUUID.equals(def.getUUID())) { view.setSelectedDataSetIndex(i); found = true; } } } if (!StringUtils.isBlank(selectedUUID) && !found) { view.errorDataSetNotFound(selectedUUID); } } public void addDataSetDef(DataSetDef def) { _dataSetDefList.add(def); if (StringUtils.isBlank(def.getName())) { view.addDataSetItem(def.getUUID(), def.getUUID()); } else { view.addDataSetItem(def.getName(), def.getUUID()); } } public void removeDataSetDef(DataSetDef def) { int i = 0; Iterator it = _dataSetDefList.iterator(); while (it.hasNext()) { DataSetDef item = it.next(); if (item.getUUID().equals(def.getUUID())) { it.remove(); view.removeDataSetItem(i); } i++; } } void updateDataSetLookup() { view.setFilterEnabled(false); view.setGroupEnabled(false); view.setColumnsSectionEnabled(false); if (dataSetLookup != null && dataSetMetadata != null && lookupConstraints != null) { updateFilterControls(); updateGroupControls(); updateColumnControls(); } } void updateFilterControls() { view.setFilterEnabled(lookupConstraints.isFilterAllowed()); filterEditor.init(dataSetLookup.getFirstFilterOp(), dataSetMetadata); } void updateGroupControls() { view.setGroupEnabled(false); view.setGroupByDateEnabled(false); // Only show the group controls if group is enabled if (lookupConstraints.isGroupRequired() || lookupConstraints.isGroupAllowed()) { String groupColumnId = getFirstGroupColumnId(); // Always ensure a group exists when required if (lookupConstraints.isGroupRequired() && groupColumnId == null) { dataSetLookup = lookupConstraints.newDataSetLookup(dataSetMetadata); changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } List groupColumnIdxs = getAvailableGroupColumnIdxs(); String rowsTitle = lookupConstraints.getGroupsTitle(); view.setGroupEnabled(true); if (isFirstGroupOpDateBased()) { view.setGroupByDateEnabled(true); ColumnGroup columnGroup = getFirstGroupOp().getColumnGroup(); groupDateEditor.init(columnGroup); } if (!StringUtils.isBlank(rowsTitle)) { view.setGroupColumnSelectorTitle(rowsTitle); } view.clearGroupColumnSelector(); if (!lookupConstraints.isGroupRequired()) { view.enableGroupColumnSelectorHint(); } for (int i = 0; i < groupColumnIdxs.size(); i++) { int idx = groupColumnIdxs.get(i); String columnId = getColumnId(idx); view.addGroupColumnItem(columnId); if (groupColumnId != null && groupColumnId.equals(columnId)) { view.setSelectedGroupColumnIndex(i); } } } } void updateColumnControls() { String groupColumnId = getFirstGroupColumnId(); List groupFunctions = getFirstGroupFunctions(); String columnsTitle = lookupConstraints.getColumnsTitle(); boolean functionsRequired = lookupConstraints.isFunctionRequired(); boolean functionsEnabled = (groupColumnId != null || functionsRequired); boolean canDelete = groupFunctions.size() > lookupConstraints.getMinColumns(); int n = lookupConstraints.getMaxColumns(); boolean canAdd = lookupConstraints.areExtraColumnsAllowed() && (n < 0 || groupFunctions.size() < n); // Show the columns section view.setColumnsSectionEnabled(true); view.clearColumnList(); if (!StringUtils.isBlank(columnsTitle)) { view.setColumnSectionTitle(columnsTitle); } view.setAddColumnOptionEnabled(canAdd); // Destroy old editors Iterator it = _editorsMap.values().iterator(); while (it.hasNext()) { ColumnFunctionEditor editor = it.next(); beanManager.destroyBean(editor); } // Build the column editors _editorsMap.clear(); ColumnType lastTargetType = null; ColumnType[] targetTypes = lookupConstraints.getColumnTypes(groupFunctions.size()); for (int i = 0; i < groupFunctions.size(); i++) { final int columnIdx = i; final GroupFunction groupFunction = groupFunctions.get(columnIdx); if (targetTypes != null && i < targetTypes.length) { lastTargetType = targetTypes[i]; } if (columnIdx == 0 && groupColumnId != null && lookupConstraints.isGroupColumn()) { continue; } ColumnType columnType = null; if (targetTypes != null && i < targetTypes.length) { columnType = targetTypes[columnIdx]; } if (columnType == null) { columnType = lastTargetType; // Extra columns } String columnTitle = lookupConstraints.getColumnTitle(columnIdx); ColumnFunctionEditor columnEditor = beanManager.lookupBean(ColumnFunctionEditor.class).newInstance(); columnEditor.init(dataSetMetadata, groupFunction, columnType, columnTitle, functionsEnabled, canDelete); _editorsMap.put(_editorsMap.size(), columnEditor); view.addColumnEditor(columnEditor); } } int getGroupFunctionLastIdx(List groupFunctions, String sourceId) { int last = -1; for (GroupFunction gf : groupFunctions) { if (gf.getSourceId().equals(sourceId)) { int idx = getGroupFunctionColumnIdx(gf.getColumnId()); if (last == -1 || last < idx) { last = idx; } } } return last; } int getGroupFunctionColumnIdx(String columnId) { int sep = columnId.lastIndexOf('_'); if (sep != -1) { try { String str = columnId.substring(sep + 1); return Integer.parseInt(str); } catch (Exception e) { // Ignore } } return 1; } // View notifications void onDataSetSelected() { String selectedUUID = view.getSelectedDataSetId(); for (DataSetDef dataSetDef : _dataSetDefList) { if (dataSetDef.getUUID().equals(selectedUUID)) { fetchMetadata(selectedUUID, new RemoteCallback() { public void callback(DataSetMetadata metadata) { dataSetLookup = lookupConstraints.newDataSetLookup(metadata); updateDataSetLookup(); changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } }); } } } void onGroupColumnSelected() { DataSetGroup groupOp = getFirstGroupOp(); if (groupOp != null) { // Group reset String columnId = view.getSelectedGroupColumnId(); if (columnId == null) { groupOp.setColumnGroup(null); if (lookupConstraints.isGroupColumn()) { groupOp.getGroupFunctions().remove(0); } if (!lookupConstraints.isFunctionRequired()) { for (GroupFunction groupFunction : groupOp.getGroupFunctions()) { groupFunction.setFunction(null); } } } // Group column change else { groupOp.setColumnGroup(new ColumnGroup(columnId, columnId)); if (lookupConstraints.isGroupColumn()) { if (groupOp.getGroupFunctions().size() > 1) { groupOp.getGroupFunctions().remove(0); } GroupFunction groupFunction = new GroupFunction(columnId, columnId, null); groupOp.getGroupFunctions().add(0, groupFunction); } } } // Refresh the group by date editor if required view.setGroupByDateEnabled(false); if (isFirstGroupOpDateBased()) { view.setGroupByDateEnabled(true); ColumnGroup columnGroup = getFirstGroupOp().getColumnGroup(); groupDateEditor.init(columnGroup); } // Reset the column list updateColumnControls(); // Notify the changes changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } void onAddColumn() { if (lookupConstraints.areExtraColumnsAllowed()) { DataSetGroup op = getFirstGroupOp(); List functionList = op.getGroupFunctions(); GroupFunction last = functionList.get(functionList.size() - 1); GroupFunction clone = last.cloneInstance(); String newColumnId = lookupConstraints.buildUniqueColumnId(dataSetLookup, clone); clone.setColumnId(newColumnId); functionList.add(clone); updateColumnControls(); changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } } // DataSetFilterEditor events void onFilterChanged(@Observes DataSetFilterChangedEvent event) { DataSetFilter filterOp = event.getFilter(); dataSetLookup.removeOperations(DataSetOpType.FILTER); if (filterOp != null) { dataSetLookup.addOperation(0, filterOp); } changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } // DataSetGroupDateEditor events void onDateGroupChanged(@Observes DataSetGroupDateChanged event) { ColumnGroup columnGroup = event.getColumnGroup(); DataSetGroup groupOp = getFirstGroupOp(); if (groupOp != null) { groupOp.setColumnGroup(columnGroup); changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } } // ColumnFunctionEditor's events void onColumnFunctionChanged(@Observes GroupFunctionChangedEvent event) { GroupFunction gf = event.getGroupFunction(); String newColumnId = lookupConstraints.buildUniqueColumnId(dataSetLookup, gf); gf.setColumnId(newColumnId); changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } void onColumnFunctionDeleted(@Observes GroupFunctionDeletedEvent event) { List functionList = getFirstGroupFunctions(); boolean canDelete = functionList.size() > lookupConstraints.getMinColumns(); GroupFunction removed = event.getGroupFunction(); int index = getFirstGroupFunctionIdx(removed); if (canDelete && index >= 0) { functionList.remove(index); updateColumnControls(); changeEvent.fire(new DataSetLookupChangedEvent(dataSetLookup)); } } // Listen to data set lifecycle events void onDataSetDefRegisteredEvent(@Observes DataSetDefRegisteredEvent event) { checkNotNull("event", event); addDataSetDef(event.getDataSetDef()); } void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { checkNotNull("event", event); removeDataSetDef(event.getOldDataSetDef()); addDataSetDef(event.getNewDataSetDef()); } void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { checkNotNull("event", event); removeDataSetDef(event.getDataSetDef()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DataSetLookupEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.displayer.client.widgets.filter.DataSetFilterEditor; import org.dashbuilder.displayer.client.widgets.group.ColumnFunctionEditor; import org.dashbuilder.displayer.client.widgets.group.DataSetGroupDateEditor; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.Icon; import org.gwtbootstrap3.client.ui.ListBox; import org.gwtbootstrap3.client.ui.constants.IconType; @Dependent public class DataSetLookupEditorView extends Composite implements DataSetLookupEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); DataSetLookupEditor presenter; @UiField ListBox dataSetListBox; @UiField org.gwtbootstrap3.client.ui.Label statusLabel; @UiField Panel groupControlPanel; @UiField Label groupControlLabel; @UiField Icon groupDetailsIcon; @UiField ListBox groupColumnListBox; @UiField Panel groupDatePanel; @UiField(provided = true) DataSetGroupDateEditor groupDateEditor; @UiField Panel columnsControlPanel; @UiField Label columnsControlLabel; @UiField Panel columnsPanel; @UiField Button addColumnButton; @UiField Panel filtersControlPanel; @UiField(provided = true) DataSetFilterEditor filterEditor; boolean dataSetSelectorHintEnabled = false; boolean groupColumnSelectorHintEnabled = false; @Override public void init(DataSetLookupEditor presenter) { this.presenter = presenter; this.filterEditor = presenter.getFilterEditor(); this.groupDateEditor = presenter.getGroupDateEditor(); initWidget(uiBinder.createAndBindUi(this)); groupDetailsIcon.setType(IconType.ARROW_DOWN); groupDetailsIcon.addDomHandler(this::expandCollapseGroupDetails, ClickEvent.getType()); } @Override public void clearAll() { setFilterEnabled(false); setGroupEnabled(false); setColumnsSectionEnabled(false); clearDataSetSelector(); clearGroupColumnSelector(); clearColumnList(); } @Override public void clearDataSetSelector() { dataSetListBox.clear(); } @Override public void enableDataSetSelectorHint() { dataSetListBox.addItem(CommonConstants.INSTANCE.common_dropdown_select()); dataSetSelectorHintEnabled = true; } @Override public void addDataSetItem(String name, String id) { dataSetListBox.addItem(name, id); } @Override public void removeDataSetItem(int index) { dataSetListBox.removeItem(dataSetSelectorHintEnabled ? index + 1 : index); } @Override public void setSelectedDataSetIndex(int index) { dataSetListBox.setSelectedIndex(dataSetSelectorHintEnabled ? index + 1 : index); } @Override public String getSelectedDataSetId() { int idx = dataSetListBox.getSelectedIndex(); if (dataSetSelectorHintEnabled && idx == 0) { return null; } return dataSetListBox.getValue(idx); } @Override public void errorDataSetNotFound(String dataSetUUID) { statusLabel.setVisible(true); statusLabel.setText(CommonConstants.INSTANCE.dataset_lookup_dataset_notfound(dataSetUUID)); } @Override public void error(ClientRuntimeError e) { statusLabel.setVisible(true); statusLabel.setText(e.getCause()); if (e.getThrowable() != null) { GWT.log(e.getMessage(), e.getThrowable()); } else { GWT.log(e.getMessage()); } } @Override public void setFilterEnabled(boolean enabled) { filtersControlPanel.setVisible(enabled); } @Override public void setGroupEnabled(boolean enabled) { groupControlPanel.setVisible(enabled); } @Override public void clearGroupColumnSelector() { groupColumnListBox.clear(); } @Override public void setGroupByDateEnabled(boolean enabled) { groupDetailsIcon.setVisible(enabled); if (!enabled) { collapseGroupDatePanel(); } } public void collapseGroupDatePanel() { groupDatePanel.setVisible(false); groupDetailsIcon.setType(IconType.ARROW_DOWN); } public void expandGroupDatePanel() { groupDatePanel.setVisible(true); groupDetailsIcon.setType(IconType.ARROW_UP); } @Override public void setGroupColumnSelectorTitle(String title) { groupControlLabel.setText(title); } @Override public void enableGroupColumnSelectorHint() { groupColumnListBox.insertItem(CommonConstants.INSTANCE.dataset_lookup_group_columns_all(), 0); groupColumnSelectorHintEnabled = true; } @Override public void addGroupColumnItem(String column) { groupColumnListBox.addItem(column); } @Override public void setSelectedGroupColumnIndex(int index) { groupColumnListBox.setSelectedIndex(groupColumnSelectorHintEnabled ? index + 1 : index); } @Override public String getSelectedGroupColumnId() { int index = groupColumnListBox.getSelectedIndex(); if (groupColumnSelectorHintEnabled && index == 0) { return null; } return groupColumnListBox.getValue(index); } @Override public void setColumnsSectionEnabled(boolean enabled) { columnsControlPanel.setVisible(enabled); } @Override public void clearColumnList() { columnsPanel.clear(); } @Override public void setColumnSectionTitle(String title) { columnsControlLabel.setText(title); } @Override public void setAddColumnOptionEnabled(boolean enabled) { addColumnButton.setVisible(enabled); } @Override public void addColumnEditor(ColumnFunctionEditor editor) { columnsPanel.add(editor); } @Override public void removeColumnEditor(ColumnFunctionEditor editor) { columnsPanel.remove(editor); } // UI events @UiHandler(value = "dataSetListBox") public void onDataSetSelected(ChangeEvent changeEvent) { presenter.onDataSetSelected(); } @UiHandler(value = "addColumnButton") public void onAddColumnClicked(ClickEvent clickEvent) { presenter.onAddColumn(); } @UiHandler(value = "groupColumnListBox") public void onGroupColumnChanged(ChangeEvent changeEvent) { presenter.onGroupColumnSelected(); } public void expandCollapseGroupDetails(ClickEvent event) { if (groupDatePanel.isVisible()) { collapseGroupDatePanel(); } else { expandGroupDatePanel(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DataSetLookupEditorView.ui.xml ================================================ .statusLabel{ color: red; } .sectionLabel { font-weight: bold; } .cellPaddingPanel { padding: 3px; } .groupDatePanel { width: 200px; padding: 10px; background: #dddddd; border-radius: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.ValidationError; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.AbstractDisplayerListener; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerListener; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.displayer.client.RendererManager; import org.dashbuilder.displayer.client.events.DataSetLookupChangedEvent; import org.dashbuilder.displayer.client.events.DisplayerEditorClosedEvent; import org.dashbuilder.displayer.client.events.DisplayerEditorSavedEvent; import org.dashbuilder.displayer.client.events.DisplayerSettingsChangedEvent; import org.dashbuilder.displayer.client.events.DisplayerSubtypeSelectedEvent; import org.dashbuilder.displayer.client.events.DisplayerTypeSelectedEvent; import org.dashbuilder.displayer.client.prototypes.DisplayerPrototypes; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class DisplayerEditor implements IsWidget { private static final int DEFAULT_SECTION = 0; private static final int DATASET_LOOKUP_SECTION = 1; private static final int DISPLAY_SETTINGS_SECTION = 2; private static final int EXTERNAL_COMPONENT_SECTION = 3; public interface View extends UberView { String getBrandNewDisplayerTitle(); boolean isTableDisplayModeOn(); void setTableDisplayModeEnabled(boolean enabled); void showDisplayer(IsWidget displayer); void setTypeSelectionEnabled(boolean enabled); void setDisplaySettingsEnabled(boolean enabled); void setDataSetLookupConfEnabled(boolean enabled); void setComponentSettingsEnabled(boolean enabled); void goToTypeSelection(DisplayerTypeSelector typeSelector); void goToDataSetLookupConf(DataSetLookupEditor lookupEditor); void goToDisplaySettings(DisplayerSettingsEditor settingsEditor); void showTypeChangedWarning(Command yes, Command no); void error(String error); void error(ClientRuntimeError error); void gotoExternalComponentSettings(ExternalComponentPropertiesEditor externalComponentPropertiesEditor); } protected View view = null; protected DataSetClientServices clientServices = null; protected DisplayerLocator displayerLocator = null; protected DisplayerPrototypes displayerPrototypes = null; protected DisplayerSettings displayerSettings = null; protected DisplayerSettings selectedTypeSettings = null; protected boolean brandNewDisplayer = true; protected DisplayerTypeSelector typeSelector; protected DataSetLookupEditor lookupEditor; protected DisplayerSettingsEditor settingsEditor; protected DisplayerEditorStatus editorStatus; protected Displayer displayer = null; protected DisplayerHtmlEditor displayerHtmlEditor = null; protected int activeSection = -1; protected boolean typeSelectionEnabled = true; protected boolean dataLookupConfEnabled = true; protected boolean displaySettingsEnabled = true; protected boolean externalComponentSettingsEnabled = false; protected Event saveEvent; protected Event closeEvent; protected Command onCloseCommand = () -> { }; protected Command onSaveCommand = () -> { }; protected DisplayerType displayerType = DisplayerType.BARCHART; protected DisplayerSubType displayerSubType = null; protected RendererManager rendererManager; protected Event displayerSettingsChangedEvent; private ExternalComponentPropertiesEditor externalComponentPropertiesEditor; protected String currentRenderer = ""; DisplayerListener displayerListener = new AbstractDisplayerListener() { public void onError(Displayer displayer, ClientRuntimeError error) { view.error(error); } }; @Inject public DisplayerEditor(View view, DataSetClientServices clientServices, DisplayerLocator displayerLocator, DisplayerPrototypes displayerPrototypes, DisplayerTypeSelector typeSelector, DataSetLookupEditor lookupEditor, DisplayerSettingsEditor settingsEditor, DisplayerEditorStatus editorStatus, DisplayerHtmlEditor displayerHtmlEditor, Event savedEvent, Event closedEvent, RendererManager rendererManager, ExternalComponentPropertiesEditor externalComponentPropertiesEditor, Event displayerSettingsChangedEvent) { this.view = view; this.displayerLocator = displayerLocator; this.clientServices = clientServices; this.displayerPrototypes = displayerPrototypes; this.typeSelector = typeSelector; this.lookupEditor = lookupEditor; this.settingsEditor = settingsEditor; this.editorStatus = editorStatus; this.displayerHtmlEditor = displayerHtmlEditor; this.saveEvent = savedEvent; this.closeEvent = closedEvent; this.rendererManager = rendererManager; this.externalComponentPropertiesEditor = externalComponentPropertiesEditor; this.displayerSettingsChangedEvent = displayerSettingsChangedEvent; view.init(this); } public void setDisplayerType(DisplayerType displayerType) { this.displayerType = displayerType != null ? displayerType : DisplayerType.BARCHART; } public void setDisplayerSubType(DisplayerSubType displayerSubType) { this.displayerSubType = displayerSubType; } public void init(DisplayerSettings settings) { if (settings != null) { brandNewDisplayer = false; displayerSettings = settings; } else { brandNewDisplayer = true; displayerSettings = displayerPrototypes.getProto(displayerType, displayerSubType); displayerSettings.setTitle(view.getBrandNewDisplayerTitle()); } selectedTypeSettings = displayerSettings; initDisplayer(); initTypeSelector(); initLookupEditor(); initSettingsEditor(); initComponentEditor(); gotoLastSection(); showDisplayer(); currentRenderer = displayerSettings.getRenderer(); if (currentRenderer == null || currentRenderer.trim().isEmpty()) { currentRenderer = rendererManager.getDefaultRenderer(displayerSettings.getType()).getUUID(); } } private void initComponentEditor() { externalComponentPropertiesEditor.init(displayerSettings.getComponentId(), displayerSettings.getComponentProperties(), this::onComponentPropertiesUpdate); } protected boolean supportsHtmlTemplate() { return displayer.getDisplayerConstraints().getSupportedAttributes().contains(DisplayerAttributeDef.HTML_TEMPLATE); } protected void initDisplayer() { if (displayer != null) { displayer.close(); } displayer = displayerLocator.lookupDisplayer(displayerSettings); displayer.addListener(displayerListener); displayer.setRefreshOn(false); displayer.draw(); } protected void initLookupEditor() { DataSetLookupConstraints lookupConstraints = displayer.getDisplayerConstraints().getDataSetLookupConstraints(); lookupEditor.init(lookupConstraints, displayerSettings.getDataSetLookup()); } protected void initTypeSelector() { typeSelector.init(displayerSettings.getType(), displayerSettings.getSubtype()); } protected void initSettingsEditor() { settingsEditor.init(displayer); } @Override public Widget asWidget() { return view.asWidget(); } public View getView() { return view; } public boolean isBrandNewDisplayer() { return brandNewDisplayer; } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public Displayer getDisplayer() { return displayer; } public String getCurrentRenderer() { return currentRenderer; } public DisplayerTypeSelector getTypeSelector() { return typeSelector; } public DataSetLookupEditor getLookupEditor() { return lookupEditor; } public DisplayerSettingsEditor getSettingsEditor() { return settingsEditor; } public void setTypeSelectorEnabled(boolean enabled) { typeSelectionEnabled = enabled; view.setTypeSelectionEnabled(enabled); } public void setDataSetLookupConfEnabled(boolean enabled) { dataLookupConfEnabled = enabled; view.setDataSetLookupConfEnabled(enabled); } public void setDisplaySettingsEnabled(boolean enabled) { displaySettingsEnabled = enabled; view.setDisplaySettingsEnabled(enabled); } public void setExternalComponentSettingsEnabled(boolean enabled) { externalComponentSettingsEnabled = enabled; view.setComponentSettingsEnabled(enabled); } public void setOnSaveCommand(Command saveCommand) { this.onSaveCommand = saveCommand != null ? saveCommand : onCloseCommand; } public void setOnCloseCommand(Command closeCommand) { this.onCloseCommand = closeCommand != null ? closeCommand : onCloseCommand; } public void showDisplayer() { if (view.isTableDisplayModeOn()) { try { DisplayerSettings tableSettings = displayerSettings.cloneInstance(); tableSettings.setTitleVisible(false); tableSettings.setType(DisplayerType.TABLE); tableSettings.setTablePageSize(10); tableSettings.setTableWidth(800); tableSettings.setRenderer("default"); Displayer tableDisplayer = displayerLocator.lookupDisplayer(tableSettings); tableDisplayer.addListener(displayerListener); tableDisplayer.setRefreshOn(false); tableDisplayer.draw(); view.showDisplayer(tableDisplayer); } catch (Exception e) { view.error(new ClientRuntimeError(e)); } } else if (supportsHtmlTemplate()) { displayerHtmlEditor.setDisplayer(displayer); view.showDisplayer(displayerHtmlEditor); } else { view.showDisplayer(displayer); } } public void gotoFirstSectionEnabled() { if (typeSelectionEnabled) { gotoTypeSelection(); } else if (dataLookupConfEnabled) { gotoDataSetLookupConf(); } else if (displaySettingsEnabled) { gotoDisplaySettings(); } else if (externalComponentSettingsEnabled) { gotoExternalComponentSettings(); } else { view.error("Nothing to show!"); } } public void gotoLastSection() { int lastOption = editorStatus.getSelectedOption(displayerSettings.getUUID()); if (activeSection < 0 || activeSection != lastOption) { switch (lastOption) { case EXTERNAL_COMPONENT_SECTION: gotoExternalComponentSettings(); break; case DISPLAY_SETTINGS_SECTION: gotoDisplaySettings(); break; case DATASET_LOOKUP_SECTION: gotoDataSetLookupConf(); break; default: gotoFirstSectionEnabled(); break; } } } public void gotoTypeSelection() { activeSection = DEFAULT_SECTION; editorStatus.saveSelectedOption(displayerSettings.getUUID(), activeSection); view.goToTypeSelection(typeSelector); } public void gotoDataSetLookupConf() { activeSection = DATASET_LOOKUP_SECTION; editorStatus.saveSelectedOption(displayerSettings.getUUID(), activeSection); view.goToDataSetLookupConf(lookupEditor); view.setTableDisplayModeEnabled(!DisplayerType.TABLE.equals(displayerSettings.getType())); } public void gotoDisplaySettings() { activeSection = DISPLAY_SETTINGS_SECTION; editorStatus.saveSelectedOption(displayerSettings.getUUID(), activeSection); view.goToDisplaySettings(settingsEditor); } public void gotoExternalComponentSettings() { activeSection = EXTERNAL_COMPONENT_SECTION; editorStatus.saveSelectedOption(displayerSettings.getUUID(), activeSection); initComponentEditor(); view.gotoExternalComponentSettings(externalComponentPropertiesEditor); } public void save() { // Clear settings before return DisplayerConstraints displayerConstraints = displayer.getDisplayerConstraints(); displayerConstraints.removeUnsupportedAttributes(displayerSettings); // Dispose the displayer if (displayer != null) { displayer.close(); } // Notify event onSaveCommand.execute(); saveEvent.fire(new DisplayerEditorSavedEvent(displayerSettings)); } public void close() { if (displayer != null) { displayer.close(); } onCloseCommand.execute(); closeEvent.fire(new DisplayerEditorClosedEvent(displayerSettings)); } // Widget listeners callback notifications void onDataSetLookupChanged(@Observes DataSetLookupChangedEvent event) { DataSetLookup dataSetLookup = event.getDataSetLookup(); displayerSettings.setDataSet(null); displayerSettings.setDataSetLookup(dataSetLookup); removeStaleSettings(); initDisplayer(); initSettingsEditor(); showDisplayer(); } void onDisplayerSettingsChanged(@Observes DisplayerSettingsChangedEvent event) { String newRenderer = event.getDisplayerSettings().getRenderer(); displayerSettings = event.getDisplayerSettings(); initDisplayer(); showDisplayer(); if (newRenderer != null && !currentRenderer.equals(newRenderer)) { initSettingsEditor(); currentRenderer = newRenderer; } } void onDisplayerTypeChanged(@Observes DisplayerTypeSelectedEvent event) { displayerTypeChanged(event.getSelectedType(), null); } void onDisplayerSubtypeChanged(@Observes DisplayerSubtypeSelectedEvent event) { displayerTypeChanged(selectedTypeSettings.getType(), event.getSelectedSubType()); } void displayerTypeChanged(DisplayerType type, DisplayerSubType displayerSubType) { // Create new settings for the selected type selectedTypeSettings = displayerPrototypes.getProto(type, displayerSubType); DataSet oldDataSet = displayerSettings.getDataSet(); DataSetLookup oldDataLookup = displayerSettings.getDataSetLookup(); // Check if the current data lookup is compatible with the new displayer type if (oldDataSet == null && oldDataLookup != null) { Displayer displayer = displayerLocator.lookupDisplayer(selectedTypeSettings); DisplayerConstraints displayerConstraints = displayer.getDisplayerConstraints(); DataSetLookupConstraints dataConstraints = displayerConstraints.getDataSetLookupConstraints(); DataSetMetadata metadata = clientServices.getMetadata(oldDataLookup.getDataSetUUID()); // Keep the current data settings provided it satisfies the data constraints ValidationError validationError = dataConstraints.check(oldDataLookup, metadata); if (validationError == null) { selectedTypeSettings.setDataSet(null); selectedTypeSettings.setDataSetLookup(oldDataLookup); applySelectedType(); } // If the data lookup is not compatible then ask the user what to do else { view.showTypeChangedWarning(this::applySelectedType, this::abortSelectedType); } } // If the displayer is static (no data lookup) then just display the selected displayer prototype else { applySelectedType(); } } void applySelectedType() { // Remove the non supported attributes displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.TYPE); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.SUBTYPE); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.GENERAL_GROUP); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.CHART_GROUP); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.AXIS_GROUP); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.SELECTOR_GROUP); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.FILTER_GROUP); displayerSettings.removeDisplayerSetting(DisplayerAttributeGroupDef.HTML_GROUP); selectedTypeSettings.getSettingsFlatMap().putAll(displayerSettings.getSettingsFlatMap()); try { // Ensure the renderer supports the new type displayerLocator.lookupDisplayer(selectedTypeSettings); } catch (Exception e) { // The new type might not support the selected renderer. selectedTypeSettings.removeDisplayerSetting(DisplayerAttributeDef.RENDERER); view.error(new ClientRuntimeError(e)); } // Re-initialize the editor with the new settings init(selectedTypeSettings); removeStaleSettings(); } void abortSelectedType() { selectedTypeSettings = displayerSettings; typeSelector.init(displayerSettings.getType(), displayerSettings.getSubtype()); view.showDisplayer(displayer); } List getExistingDataColumnIds() { DataSet dataSet = displayerSettings.getDataSet(); DataSetLookup dataSetLookup = displayerSettings.getDataSetLookup(); List columnIds = new ArrayList(); if (dataSet != null) { for (DataColumn dataColumn : dataSet.getColumns()) { columnIds.add(dataColumn.getId()); } } else if (dataSetLookup != null) { int idx = dataSetLookup.getLastGroupOpIndex(0); if (idx != -1) { DataSetGroup groupOp = dataSetLookup.getOperation(idx); for (GroupFunction groupFunction : groupOp.getGroupFunctions()) { columnIds.add(groupFunction.getColumnId()); } } } return columnIds; } void removeStaleSettings() { List columnIds = getExistingDataColumnIds(); // Remove the settings for non existing columns Iterator it = displayerSettings.getColumnSettingsList().iterator(); while (it.hasNext()) { ColumnSettings columnSettings = it.next(); if (!columnIds.contains(columnSettings.getColumnId())) { it.remove(); } } // Reset table sort column if (!columnIds.contains(displayerSettings.getTableDefaultSortColumnId())) { displayerSettings.setTableDefaultSortColumnId(null); } } void onComponentPropertiesUpdate(Map updatedProperties) { updatedProperties.forEach(displayerSettings::setComponentProperty); displayerSettingsChangedEvent.fire(new DisplayerSettingsChangedEvent(displayerSettings)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerEditorPopup.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.web.bindery.event.shared.HandlerRegistration; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.gwtbootstrap3.client.shared.event.ModalHiddenEvent; import org.gwtbootstrap3.client.shared.event.ModalHiddenHandler; import org.gwtbootstrap3.client.shared.event.ModalShownEvent; import org.gwtbootstrap3.client.shared.event.ModalShownHandler; import org.gwtbootstrap3.client.ui.ModalBody; import org.uberfire.ext.widgets.common.client.common.popups.BaseModal; import org.uberfire.ext.widgets.common.client.common.popups.ButtonPressed; import org.uberfire.ext.widgets.common.client.common.popups.footers.ModalFooterOKCancelButtons; import org.uberfire.mvp.Command; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class DisplayerEditorPopup extends BaseModal { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField(provided = true) DisplayerEditor editor; private HandlerRegistration showHandlerRegistration; private String editDisplayerTitle = CommonConstants.INSTANCE.displayer_editor_title(); private String newDisplayerTitle = CommonConstants.INSTANCE.displayer_editor_new(); private DisplayerType displayerType = null; private DisplayerSubType displayerSubType = null; private ButtonPressed buttonPressed = ButtonPressed.CLOSE; @Inject public DisplayerEditorPopup(DisplayerEditor editor) { this.editor = editor; add(uiBinder.createAndBindUi(this)); ModalFooterOKCancelButtons footer = createModalFooterOKCancelButtons(); footer.enableCancelButton(true); footer.enableOkButton(true); add(footer); setWidth(1200+"px"); addHiddenHandler(); } public DisplayerEditorPopup init(DisplayerSettings settings) { ModalShownHandler shownHandler = createShownHandler(settings); this.showHandlerRegistration = this.addShownHandler(shownHandler); show(); return this; } public DisplayerSettings getDisplayerSettings() { return this.editor.getDisplayerSettings(); } public void setNewDisplayerTitle(String newDisplayerTitle) { this.newDisplayerTitle = newDisplayerTitle; } public void setEditDisplayerTitle(String editDisplayerTitle) { this.editDisplayerTitle = editDisplayerTitle; } public void setDisplayerType(DisplayerType displayerType) { this.displayerType = displayerType; } public void setDisplayerSubType(DisplayerSubType displayerSubType) { this.displayerSubType = displayerSubType; } public void setOnSaveCommand(Command saveCommand) { this.editor.setOnSaveCommand(saveCommand); } public void setOnCloseCommand(Command closeCommand) { this.editor.setOnCloseCommand(closeCommand); } public void setTypeSelectorEnabled(boolean enableTypeSelector) { this.editor.setTypeSelectorEnabled(enableTypeSelector); } public void setExternalDisplayerEnabled(boolean enabled) { this.editor.setExternalComponentSettingsEnabled(enabled); } /** *

The popup must be visible in order that the table can display the different row's values. So after popup is shown, initialize the editor.

*/ protected ModalShownHandler createShownHandler(final DisplayerSettings settings) { return new ModalShownHandler() { @Override public void onShown(ModalShownEvent modalShownEvent) { editor.setDisplayerType(displayerType); editor.setDisplayerSubType(displayerSubType); editor.init(settings); setTitle(editor.isBrandNewDisplayer() ? newDisplayerTitle : editDisplayerTitle); removeShownHandler(); } }; } protected void removeShownHandler() { if (this.showHandlerRegistration != null) { this.showHandlerRegistration.removeHandler(); this.showHandlerRegistration = null; } } protected void addHiddenHandler() { addHiddenHandler(new ModalHiddenHandler() { @Override public void onHidden(ModalHiddenEvent hiddenEvent) { if (userPressedCloseOrCancel()) { editor.close(); } } } ); } private boolean userPressedCloseOrCancel() { return ButtonPressed.CANCEL.equals(buttonPressed) || ButtonPressed.CLOSE.equals(buttonPressed); } protected ModalFooterOKCancelButtons createModalFooterOKCancelButtons() { return new ModalFooterOKCancelButtons( new com.google.gwt.user.client.Command() { @Override public void execute() { buttonPressed = ButtonPressed.OK; hide(); editor.save(); } }, new com.google.gwt.user.client.Command() { @Override public void execute() { buttonPressed = ButtonPressed.CANCEL; hide(); } }); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerEditorPopup.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerEditorStatus.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class DisplayerEditorStatus { Map displayerStatusMap = new HashMap(); public int getSelectedOption(String displayerUuid) { DisplayerStatus status = displayerStatusMap.get(displayerUuid); return (status == null ? -1 : status.selectedOption); } public void saveSelectedOption(String displayerUuid, int option) { DisplayerStatus status = fetch(displayerUuid); status.selectedOption = option; } private DisplayerStatus fetch(String displayerUuid) { DisplayerStatus status = displayerStatusMap.get(displayerUuid); if (status != null) return status; status = new DisplayerStatus(); displayerStatusMap.put(displayerUuid, status); return status; } private class DisplayerStatus { int selectedOption = -1; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.common.client.widgets.AlertPanel; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.gwtbootstrap3.client.ui.CheckBox; import org.gwtbootstrap3.client.ui.Column; import org.gwtbootstrap3.client.ui.Row; import org.gwtbootstrap3.client.ui.TabListItem; import org.gwtbootstrap3.client.ui.constants.AlertType; import org.uberfire.mvp.Command; @Dependent public class DisplayerEditorView extends Composite implements DisplayerEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField Column westColumn; @UiField Column leftColumn; @UiField Column centerColumn; @UiField TabListItem optionType; @UiField TabListItem optionData; @UiField TabListItem optionSettings; @UiField TabListItem optionComponentSettings; @UiField Row viewAsTableButtonRow; @UiField CheckBox viewAsTableButton; protected DisplayerEditor presenter; @Inject protected DisplayerErrorWidget errorWidget; public void init(DisplayerEditor presenter) { this.presenter = presenter; initWidget(uiBinder.createAndBindUi(this)); viewAsTableButtonRow.getElement().setAttribute("cellpadding", "5"); // disabled by default setComponentSettingsEnabled(false); } @Override public String getBrandNewDisplayerTitle() { return "- " + CommonConstants.INSTANCE.displayer_editor_new() + " -"; } @Override public void showDisplayer(IsWidget displayer) { centerColumn.clear(); centerColumn.add(displayer); } @Override public void setTypeSelectionEnabled(boolean enabled) { optionType.setVisible(enabled); goToOtherSectionIfActive(optionType); } @Override public void setDisplaySettingsEnabled(boolean enabled) { optionSettings.setVisible(enabled); goToOtherSectionIfActive(optionSettings); } @Override public void setDataSetLookupConfEnabled(boolean enabled) { optionData.setVisible(enabled); goToOtherSectionIfActive(optionData); } @Override public void setComponentSettingsEnabled(boolean enabled) { optionComponentSettings.setVisible(enabled); goToOtherSectionIfActive(optionComponentSettings); } @Override public boolean isTableDisplayModeOn() { return viewAsTableButtonRow.isVisible() && viewAsTableButton.getValue(); } @Override public void setTableDisplayModeEnabled(boolean enabled) { viewAsTableButtonRow.setVisible(enabled); } @Override public void goToTypeSelection(DisplayerTypeSelector typeSelector) { leftColumn.clear(); leftColumn.getElement().getStyle().setOverflowY(Style.Overflow.HIDDEN); leftColumn.add(typeSelector); viewAsTableButtonRow.setVisible(false); optionData.setActive(false); optionSettings.setActive(false); optionType.setActive(true); optionComponentSettings.setActive(false); } @Override public void goToDataSetLookupConf(DataSetLookupEditor lookupEditor) { leftColumn.clear(); leftColumn.getElement().getStyle().setOverflowY(Style.Overflow.AUTO); leftColumn.add(lookupEditor); optionSettings.setActive(false); optionType.setActive(false); optionData.setActive(true); optionComponentSettings.setActive(false); } @Override public void goToDisplaySettings(DisplayerSettingsEditor settingsEditor) { leftColumn.clear(); leftColumn.getElement().getStyle().setOverflowY(Style.Overflow.AUTO); leftColumn.add(settingsEditor); viewAsTableButtonRow.setVisible(false); optionType.setActive(false); optionData.setActive(false); optionSettings.setActive(true); optionComponentSettings.setActive(false); } @Override public void gotoExternalComponentSettings(ExternalComponentPropertiesEditor externalComponentPropertiesEditor) { leftColumn.clear(); leftColumn.getElement().getStyle().setOverflowY(Style.Overflow.AUTO); leftColumn.add(externalComponentPropertiesEditor); viewAsTableButtonRow.setVisible(false); optionType.setActive(false); optionData.setActive(false); optionSettings.setActive(false); optionComponentSettings.setActive(true); } @Override public void showTypeChangedWarning(Command yes, Command no) { AlertPanel alertPanel = new AlertPanel(); String alertMsg = CommonConstants.INSTANCE.displayer_editor_incompatible_settings(); alertPanel.show(AlertType.WARNING, alertMsg, 400, yes, no); centerColumn.clear(); centerColumn.add(alertPanel); } @Override public void error(String error) { centerColumn.clear(); centerColumn.add(errorWidget); errorWidget.show(error, null); GWT.log(error); } @Override public void error(ClientRuntimeError e) { centerColumn.clear(); centerColumn.add(errorWidget); errorWidget.show(e.getMessage(), e.getThrowable()); if (e.getThrowable() != null) { GWT.log(e.getMessage(), e.getThrowable()); } else { GWT.log(e.getMessage()); } } @UiHandler(value = "optionType") public void onTypeSelected(ClickEvent clickEvent) { presenter.gotoTypeSelection(); } @UiHandler(value = "optionData") public void onDataSelected(ClickEvent clickEvent) { presenter.gotoDataSetLookupConf(); } @UiHandler(value = "optionSettings") public void onSettingsSelected(ClickEvent clickEvent) { presenter.gotoDisplaySettings(); } @UiHandler(value = "optionComponentSettings") public void onExternalComponentSettingsSelected(ClickEvent clickEvent) { presenter.gotoExternalComponentSettings(); } @UiHandler(value = "viewAsTableButton") public void onRawTableChecked(ClickEvent clickEvent) { presenter.showDisplayer(); } private void goToOtherSectionIfActive(TabListItem item) { if (item.isActive()) { presenter.gotoFirstSectionEnabled(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerEditorView.ui.xml ================================================ .mainContainer { margin-top: 15px; } .leftColumn { overflow-x: hidden; overflow-y: auto; height: 370px; } .centerColumn { height: 390px; overflow: auto; } .viewAsTableButtonRow { font-size: small; } .viewAsTableButton { margin: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerError.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Row; @Dependent public class DisplayerError extends Composite { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField HTML errorMessage; @UiField HTML errorCause; @UiField Panel errorMessageRow; @UiField Panel errorCauseRow; public DisplayerError() { initWidget(uiBinder.createAndBindUi(this)); } public void show(final String message, final String cause) { errorMessage.setText(message != null ? message : ""); errorMessageRow.setVisible(message != null); errorCause.setText(cause != null ? cause : ""); errorCauseRow.setVisible(cause != null); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerError.ui.xml ================================================ .errorPanel { padding: 25px; } .errorRow { margin-bottom: 10px; } .errorLabel { font-weight: bold; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerErrorWidget.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ .displayer-error { margin: 10px; } .displayer-error-body { overflow-wrap: break-word; overflow: auto; max-height: 110px; } .displayer-error-title-icon { margin-right: 10px; } .error-details { resize: none; white-space: pre; cursor: text; border: none; } .chevron-title { margin-left: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerErrorWidget.html ================================================

================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerErrorWidget.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.user.client.ui.Composite; import elemental2.dom.HTMLAnchorElement; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLParagraphElement; import elemental2.dom.HTMLTextAreaElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class DisplayerErrorWidget extends Composite { @Inject @DataField private HTMLDivElement displayerErrorRoot; @Inject @DataField private HTMLParagraphElement errorBody; @Inject @DataField private HTMLDivElement errorDetailsSection; @Inject @DataField private HTMLTextAreaElement errorDetails; @Inject @DataField private HTMLAnchorElement chevronRight; @Inject @DataField private HTMLAnchorElement chevronDown; public void show(String message, Throwable t) { errorBody.textContent = message; errorDetails.value = buildErrorDetails(t); } private String buildErrorDetails(Throwable t) { StringBuilder sb = new StringBuilder(); Throwable cause = t.getCause(); sb.append(t.getMessage()); while (cause != null) { sb.append("\n Caused by: " + cause.getMessage()); cause = cause.getCause(); } return sb.toString(); } @EventHandler("chevronRight") public void onChevronRightClicked(final ClickEvent event) { showErrorDetails(true); } @EventHandler("chevronDown") public void onChevronDownClicked(final ClickEvent event) { showErrorDetails(false); } private void showErrorDetails(final boolean isVisible) { chevronRight.hidden = isVisible; chevronDown.hidden = !isVisible; errorDetailsSection.hidden = !isVisible; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerHtmlEditor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.widgets.sourcecode.HasHtmlTemplate; import org.dashbuilder.displayer.client.widgets.sourcecode.HasJsTemplate; import org.dashbuilder.displayer.client.widgets.sourcecode.SourceCodeEditor; import org.dashbuilder.displayer.client.widgets.sourcecode.SourceCodeType; import org.uberfire.client.mvp.UberView; import static org.dashbuilder.displayer.client.widgets.sourcecode.SourceCodeType.*; /** * UI component for the edition of a displayer component supporting HTML templates */ @Dependent public class DisplayerHtmlEditor implements IsWidget { public interface View extends UberView { void showDisplayer(IsWidget displayer); void clearSourceCodeItems(); void addSourceCodeItem(String name); void editSourceCodeItem(String name, IsWidget editor); } public class SourceCodeItem { String name; SourceCodeType type; DisplayerAttributeDef attributeDef; public SourceCodeItem(String name, SourceCodeType type, DisplayerAttributeDef attributeDef) { this.name = name; this.type = type; this.attributeDef = attributeDef; } } Displayer displayer; View view; SourceCodeEditor sourceCodeEditor; Set sourceCodeItems = new HashSet<>(); SourceCodeItem selectedSourceCodeItem = null; boolean showingDisplayer = true; @Inject public DisplayerHtmlEditor(View view, SourceCodeEditor sourceCodeEditor) { this.view = view; this.sourceCodeEditor = sourceCodeEditor; view.init(this); sourceCodeItems.add(new SourceCodeItem("html", HTML, DisplayerAttributeDef.HTML_TEMPLATE)); sourceCodeItems.add(new SourceCodeItem("javascript", JAVASCRIPT, DisplayerAttributeDef.JS_TEMPLATE)); } @Override public Widget asWidget() { return view.asWidget(); } public Displayer getDisplayer() { return displayer; } public void setDisplayer(Displayer displayer) { this.selectedSourceCodeItem = null; this.displayer = displayer; initSourceCodeItems(); showDisplayer(); } public boolean showDisplayer() { if (sourceCodeEditor.hasErrors()) { sourceCodeEditor.focus(); return false; } view.showDisplayer(displayer); showingDisplayer = true; displayer.redraw(); return true; } public void initSourceCodeItems() { view.clearSourceCodeItems(); Set attrs = displayer.getDisplayerConstraints().getSupportedAttributes(); for (SourceCodeItem sourceCodeItem : sourceCodeItems) { if (attrs.contains(sourceCodeItem.attributeDef)) { view.addSourceCodeItem(sourceCodeItem.name); } } } public SourceCodeItem getSourceCodeItem(String name) { for (SourceCodeItem sourceCodeItem : sourceCodeItems) { if (sourceCodeItem.name.equals(name)) { return sourceCodeItem; } } return null; } public boolean onSourceCodeItemSelected(String name) { selectedSourceCodeItem = getSourceCodeItem(name); String code = displayer.getDisplayerSettings().getDisplayerSetting(selectedSourceCodeItem.attributeDef); Map varMap = null; if (selectedSourceCodeItem.type == SourceCodeType.HTML && displayer instanceof HasHtmlTemplate) { varMap = ((HasHtmlTemplate) displayer).getHtmlVariableMap(); } if (selectedSourceCodeItem.type == SourceCodeType.JAVASCRIPT && displayer instanceof HasJsTemplate) { varMap = ((HasJsTemplate) displayer).getJsVariableMap(); } sourceCodeEditor.init(selectedSourceCodeItem.type, code, varMap, this::onSourceCodeChanged); sourceCodeEditor.focus(); showingDisplayer = false; view.editSourceCodeItem(name, sourceCodeEditor); return true; } public void onSourceCodeChanged() { if (!sourceCodeEditor.hasErrors()) { String newCode = sourceCodeEditor.getCode(); displayer.getDisplayerSettings().setDisplayerSetting(selectedSourceCodeItem.attributeDef, newCode); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerHtmlEditorView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerHtmlEditorView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.displayer.client.resources.i18n.DisplayerHtmlConstants; import org.jboss.errai.common.client.dom.Anchor; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.NodeList; import org.jboss.errai.common.client.dom.ListItem; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class DisplayerHtmlEditorView extends Composite implements DisplayerHtmlEditor.View { @Inject @DataField FlowPanel contentPanel; @Inject @DataField UnorderedList tabList; @Inject @DataField ListItem previewItem; @Inject @DataField Anchor previewAnchor; LIElement selectedItem; DisplayerHtmlEditor presenter; @Override public void init(DisplayerHtmlEditor presenter) { this.presenter = presenter; } @Override public void showDisplayer(IsWidget displayer) { contentPanel.clear(); contentPanel.add(displayer); previewItem.setClassName("active"); previewAnchor.setTextContent(DisplayerHtmlConstants.INSTANCE.displayer_html_preview_link()); } @Override public void clearSourceCodeItems() { removeAllChildren(tabList); tabList.appendChild(previewItem); } @Override public void editSourceCodeItem(String name, IsWidget editor) { contentPanel.clear(); contentPanel.add(editor); } @Override public void addSourceCodeItem(String name) { AnchorElement anchor = Document.get().createAnchorElement(); String displayName = DisplayerHtmlConstants.INSTANCE.getString("displayer_source_code_" + name); anchor.setInnerText(displayName); LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); tabList.appendChild((Node) li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if(Event.ONCLICK == event.getTypeInt()) { presenter.onSourceCodeItemSelected(name); if (selectedItem != null) { selectedItem.setClassName(""); selectedItem.getStyle().setCursor(Style.Cursor.POINTER); } selectedItem = li; selectedItem.setClassName("active"); selectedItem.getStyle().setCursor(Style.Cursor.DEFAULT); previewItem.setClassName(""); } }); } private void removeAllChildren(org.jboss.errai.common.client.dom.Element element) { NodeList nodeList = element.getChildNodes(); int lenght = nodeList.getLength(); for (int i=0; i { void clear(); void show(); void dataSetNotFound(); void error(String message); void addCategory(DisplayerAttributeDef attributeDef); void addTextProperty(DisplayerAttributeDef attributeDef, String value, PropertyFieldValidator... validators); void addTextProperty(String propId, String propName, String value, PropertyFieldValidator... validators); void addBooleanProperty(DisplayerAttributeDef attributeDef, boolean value); void addColorProperty(DisplayerAttributeDef attributeDef, String color); void addListProperty(DisplayerAttributeDef attributeDef, List optionList, String selectedValue); String getColumnNameI18n(); String getColumnExpressionI18n(); String getColumnPatternI18n(); String getPositionLiteralI18n(Position position); String getIntegerValidationFailedI18n(); String getDoubleValidationFailedI18n(); String getMeterStartI18n(); String getMeterWarningI18n(); String getMeterCriticalI18n(); String getMeterEndI18n(); String getMeterUnknownI18n(); String getMeterValidationHigherI18n(String level); String getMeterValidationLowerI18n(String level); String getMeterValidationInvalidI18n(); String getMapColorSchemeI18n(MapColorScheme colorScheme); } protected View view; protected DisplayerLocator displayerLocator; protected RendererManager rendererManager; protected Displayer displayer; protected DisplayerSettings displayerSettings; protected DisplayerConstraints displayerContraints; private Set supportedAttributes; protected Event settingsChangedEvent; public static final String COLUMNS_PREFFIX = "columns."; @Inject public DisplayerSettingsEditor(View view, DisplayerLocator displayerLocator, RendererManager rendererManager, Event settingsChangedEvent) { this.view = view; this.displayerLocator = displayerLocator; this.rendererManager = rendererManager; this.settingsChangedEvent = settingsChangedEvent; view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public void init(Displayer displayer) { try { this.displayer = displayer; this.displayerSettings = displayer.getDisplayerSettings(); this.displayerContraints = displayer.getDisplayerConstraints(); this.supportedAttributes = displayerContraints.getSupportedAttributes(); displayer.getDataSetHandler().lookupDataSet(new DataSetReadyCallback() { @Override public void callback(DataSet dataSet) { show(); } @Override public void notFound() { view.dataSetNotFound(); } @Override public boolean onError(final ClientRuntimeError error) { console(error.getThrowable()); view.error(error.getMessage()); return false; } }); } catch (Exception e) { console(e); view.error(e.toString()); } } public boolean isSupported(DisplayerAttributeDef attributeDef) { return supportedAttributes.contains(attributeDef); } public boolean isSupported(DisplayerAttributeGroupDef groupDef) { if (supportedAttributes.contains(groupDef)) { for (DisplayerAttributeDef attrDef : groupDef.getChildren()) { if (attrDef instanceof DisplayerAttributeGroupDef) { continue; } if (supportedAttributes.contains(attrDef)) { return true; } } } return false; } void show() { view.clear(); if (isSupported(GENERAL_GROUP)) { view.addCategory(GENERAL_GROUP); if (isSupported(TITLE)) { view.addTextProperty(TITLE, displayerSettings.getTitle()); } if (isSupported(TITLE_VISIBLE)) { view.addBooleanProperty(TITLE_VISIBLE, displayerSettings.isTitleVisible()); } } if (isSupported(RENDERER)) { view.addCategory(RENDERER); List optionList = new ArrayList(); for (RendererLibrary option : rendererManager.getRenderersForType(displayerSettings.getType())) { optionList.add(option.getUUID()); } if (optionList.size() > 1) { RendererLibrary renderer = rendererManager.getRendererForDisplayer(displayerSettings); view.addListProperty(RENDERER, optionList, renderer.getUUID()); } } if (isSupported(CHART_GROUP)) { view.addCategory(CHART_GROUP); if (isSupported(CHART_RESIZABLE)) { view.addBooleanProperty(CHART_RESIZABLE, displayerSettings.isResizable()); } if (isSupported(CHART_WIDTH)) { view.addTextProperty(CHART_WIDTH, String.valueOf(displayerSettings.getChartWidth()), createLongValidator()); } if (isSupported(CHART_HEIGHT)) { view.addTextProperty(CHART_HEIGHT, String.valueOf(displayerSettings.getChartHeight()), createLongValidator()); } if (isSupported(CHART_BGCOLOR)) { view.addColorProperty(CHART_BGCOLOR, displayerSettings.getChartBackgroundColor()); } if (isSupported(CHART_3D)) { view.addBooleanProperty(CHART_3D, displayerSettings.isChart3D()); } } if (isSupported(CHART_MARGIN_GROUP)) { view.addCategory(CHART_MARGIN_GROUP); if (isSupported(CHART_MARGIN_TOP)) { view.addTextProperty(CHART_MARGIN_TOP, String.valueOf(displayerSettings.getChartMarginTop()), createLongValidator()); } if (isSupported(CHART_MARGIN_BOTTOM)) { view.addTextProperty(CHART_MARGIN_BOTTOM, String.valueOf(displayerSettings.getChartMarginBottom()), createLongValidator()); } if (isSupported(CHART_MARGIN_LEFT)) { view.addTextProperty(CHART_MARGIN_LEFT, String.valueOf(displayerSettings.getChartMarginLeft()), createLongValidator()); } if (isSupported(CHART_MARGIN_RIGHT)) { view.addTextProperty(CHART_MARGIN_RIGHT, String.valueOf(displayerSettings.getChartMarginRight()), createLongValidator()); } } if (isSupported(CHART_LEGEND_GROUP)) { view.addCategory(CHART_LEGEND_GROUP); if (isSupported(CHART_SHOWLEGEND)) { view.addBooleanProperty(CHART_SHOWLEGEND, displayerSettings.isChartShowLegend()); } if (isSupported(CHART_LEGENDPOSITION)) { List optionList = new ArrayList(); for (Position position : Position.values()) { String positionLabel = view.getPositionLiteralI18n(position); optionList.add(positionLabel); } if (optionList.size() > 1) { String positionLabel = view.getPositionLiteralI18n(displayerSettings.getChartLegendPosition()); view.addListProperty(CHART_LEGENDPOSITION, optionList, positionLabel); } } } if (isSupported(XAXIS_GROUP) || isSupported(YAXIS_GROUP)) { view.addCategory(XAXIS_GROUP); if (isSupported(XAXIS_SHOWLABELS)) { view.addBooleanProperty(XAXIS_SHOWLABELS, displayerSettings.isXAxisShowLabels()); } if (isSupported(XAXIS_TITLE)) { view.addTextProperty(XAXIS_TITLE, displayerSettings.getXAxisTitle()); } if (isSupported(XAXIS_LABELSANGLE)) { view.addTextProperty(XAXIS_LABELSANGLE, String.valueOf(displayerSettings.getXAxisLabelsAngle())); } if (isSupported(YAXIS_SHOWLABELS)) { view.addBooleanProperty(YAXIS_SHOWLABELS, displayerSettings.isXAxisShowLabels()); } if (isSupported(YAXIS_TITLE)) { view.addTextProperty(YAXIS_TITLE, displayerSettings.getYAxisTitle()); } } if (isSupported(TABLE_GROUP)) { view.addCategory(TABLE_GROUP); if (isSupported(TABLE_PAGESIZE)) { view.addTextProperty(TABLE_PAGESIZE, String.valueOf(displayerSettings.getTablePageSize()), createLongValidator()); } if (isSupported(TABLE_WIDTH)) { view.addTextProperty(TABLE_WIDTH, String.valueOf(displayerSettings.getTableWidth()), createLongValidator()); } if (isSupported(TABLE_SORTENABLED)) { view.addBooleanProperty(TABLE_SORTENABLED, displayerSettings.isTableSortEnabled()); } if (isSupported(TABLE_SORTCOLUMNID)) { final List optionList = new ArrayList(); DataSet dataSet = displayer.getDataSetHandler().getLastDataSet(); List dsColumns = dataSet.getColumns(); optionList.add(""); for (DataColumn column : dsColumns) { optionList.add(column.getId()); } view.addListProperty(TABLE_SORTCOLUMNID, optionList, displayerSettings.getTableDefaultSortColumnId()); } if (isSupported(TABLE_SORTORDER)) { List optionList = new ArrayList(); optionList.add(SortOrder.ASCENDING.toString()); optionList.add(SortOrder.DESCENDING.toString()); view.addListProperty(TABLE_SORTORDER, optionList, displayerSettings.getTableDefaultSortOrder().toString()); } if (isSupported(TABLE_COLUMN_PICKER_ENABLED)) { view.addBooleanProperty(TABLE_COLUMN_PICKER_ENABLED, displayerSettings.isTableColumnPickerEnabled()); } } if (isSupported(METER_GROUP)) { view.addCategory(METER_GROUP); if (isSupported(METER_START)) { view.addTextProperty(METER_START, String.valueOf(displayerSettings.getMeterStart()), createMeterValidator(displayerSettings, 0)); } if (isSupported(METER_WARNING)) { view.addTextProperty(METER_WARNING, String.valueOf(displayerSettings.getMeterWarning()), createMeterValidator(displayerSettings, 1)); } if (isSupported(METER_CRITICAL)) { view.addTextProperty(METER_CRITICAL, String.valueOf(displayerSettings.getMeterCritical()), createMeterValidator(displayerSettings, 2)); } if (isSupported(METER_END)) { view.addTextProperty(METER_END, String.valueOf(displayerSettings.getMeterEnd()), createMeterValidator(displayerSettings, 3)); } } if (isSupported(FILTER_GROUP)) { view.addCategory(FILTER_GROUP); if (isSupported(FILTER_ENABLED)) { view.addBooleanProperty(FILTER_ENABLED, displayerSettings.isFilterEnabled()); } if (isSupported(FILTER_SELFAPPLY_ENABLED)) { view.addBooleanProperty(FILTER_SELFAPPLY_ENABLED, displayerSettings.isFilterSelfApplyEnabled()); } if (isSupported(FILTER_LISTENING_ENABLED)) { view.addBooleanProperty(FILTER_LISTENING_ENABLED, displayerSettings.isFilterListeningEnabled()); } if (isSupported(FILTER_NOTIFICATION_ENABLED)) { view.addBooleanProperty(FILTER_NOTIFICATION_ENABLED, displayerSettings.isFilterNotificationEnabled()); } } if (isSupported(SELECTOR_GROUP)) { view.addCategory(SELECTOR_GROUP); if (isSupported(SELECTOR_WIDTH)) { view.addTextProperty(SELECTOR_WIDTH, String.valueOf(displayerSettings.getSelectorWidth()), createLongValidator()); } if (isSupported(SELECTOR_MULTIPLE)) { view.addBooleanProperty(SELECTOR_MULTIPLE, displayerSettings.isSelectorMultiple()); } if (isSupported(SELECTOR_SHOW_INPUTS)) { view.addBooleanProperty(SELECTOR_SHOW_INPUTS, displayerSettings.isSelectorInputsEnabled()); } } if (isSupported(REFRESH_GROUP)) { view.addCategory(REFRESH_GROUP); if (isSupported(REFRESH_INTERVAL)) { view.addTextProperty(REFRESH_INTERVAL, String.valueOf(displayerSettings.getRefreshInterval()), createLongValidator()); } if (isSupported(REFRESH_STALE_DATA)) { view.addBooleanProperty(REFRESH_STALE_DATA, displayerSettings.isRefreshStaleData()); } } if (isSupported(COLUMNS_GROUP)) { view.addCategory(COLUMNS_GROUP); DataSet dataSet = displayer.getDataSetHandler().getLastDataSet(); for (int i = 0; i < dataSet.getColumns().size(); i++) { DataColumn dataColumn = dataSet.getColumnByIndex(i); ColumnSettings cs = displayerSettings.getColumnSettings(dataColumn); String fieldSuffix = COLUMNS_PREFFIX + cs.getColumnId() + "."; String expression = cs.getValueExpression(); String pattern = cs.getValuePattern(); view.addTextProperty(fieldSuffix + "name", view.getColumnNameI18n() + (i + 1), cs.getColumnName()); if (expression != null) { view.addTextProperty(fieldSuffix + "expression", " " + view.getColumnExpressionI18n(), expression); } if (pattern != null) { view.addTextProperty(fieldSuffix + "pattern", " " + view.getColumnPatternI18n(), pattern); } /* Non-critical. Disable for the time being. if (isSupported(COLUMN_EMPTY)) { String empty = cs.getEmptyTemplate(); view.addTextProperty(fieldSuffix + "empty", " " + view.getColumnEmptyI18n(), empty); }*/ } } if (isSupported(EXPORT_GROUP)) { view.addCategory(EXPORT_GROUP); if (isSupported(EXPORT_TO_CSV)) { view.addBooleanProperty(EXPORT_TO_CSV, displayerSettings.isCSVExportAllowed()); } if (isSupported(EXPORT_TO_XLS)) { view.addBooleanProperty(EXPORT_TO_XLS, displayerSettings.isExcelExportAllowed()); } } if (isSupported(MAP_GROUP)) { view.addCategory(MAP_GROUP); if (isSupported(MAP_COLOR_SCHEME)) { List colorsSchemes = Stream.of(MapColorScheme.values()) .map(view::getMapColorSchemeI18n) .collect(Collectors.toList()); String mapColorSchemePositionLabel = view.getMapColorSchemeI18n(displayerSettings.getMapColorScheme()); view.addListProperty(MAP_COLOR_SCHEME, colorsSchemes, mapColorSchemePositionLabel); } } view.show(); } void onAttributeChanged(String attrKey, String attrValue) { if (attrKey.startsWith(COLUMNS_PREFFIX)) { String[] strings = attrKey.split("\\."); if (strings.length == 3) { String columnId = strings[1]; String setting = strings[2]; if ("name".equals(setting)) { displayerSettings.setColumnName(columnId, attrValue); } else if ("empty".equals(setting)) { displayerSettings.setColumnEmptyTemplate(columnId, attrValue); } else if ("pattern".equals(setting)) { displayerSettings.setColumnValuePattern(columnId, attrValue); } else if ("expression".equals(setting)) { displayerSettings.setColumnValueExpression(columnId, attrValue); } } } else { displayerSettings.setDisplayerSetting(attrKey, attrValue); } settingsChangedEvent.fire(new DisplayerSettingsChangedEvent(displayerSettings)); } // Custom property validators public LongValidator createLongValidator() { return new LongValidator(); } public DoubleValidator createDoubleValidator() { return new DoubleValidator(); } public MeterValidator createMeterValidator(DisplayerSettings settings, int level) { return new MeterValidator(settings, level); } /** * Property Editor Validator for integers */ public class LongValidator implements PropertyFieldValidator { @Override public boolean validate(Object value) { try { Long.parseLong(value.toString()); return true; } catch (Exception e) { return false; } } @Override public String getValidatorErrorMessage() { return view.getIntegerValidationFailedI18n(); } } /** * Property Editor Validator for doubles */ public class DoubleValidator implements PropertyFieldValidator { @Override public boolean validate(Object value) { try { Double.parseDouble(value.toString()); return true; } catch (Exception e) { return false; } } @Override public String getValidatorErrorMessage() { return view.getDoubleValidationFailedI18n(); } } /** * Property Editor Validator for meter intervals */ public class MeterValidator extends LongValidator { private DisplayerSettings displayerSettings; private int level; private boolean lowerOk = true; private boolean upperOk = true; public MeterValidator(DisplayerSettings displayerSettings, int level) { this.displayerSettings = displayerSettings; this.level = level; } private long getLevelValue(int level) { switch (level) { case 0: return displayerSettings.getMeterStart(); case 1: return displayerSettings.getMeterWarning(); case 2: return displayerSettings.getMeterCritical(); case 3: return displayerSettings.getMeterEnd(); } return level < 0 ? Long.MIN_VALUE : Long.MAX_VALUE; } private String getLevelDescr(int level) { switch (level) { case 0: return view.getMeterStartI18n(); case 1: return view.getMeterWarningI18n(); case 2: return view.getMeterCriticalI18n(); case 3: return view.getMeterEndI18n(); } return view.getMeterUnknownI18n(); } @Override public boolean validate(Object value) { if (!super.validate(value)) { return false; } long thisLevel = Long.parseLong(value.toString()); long lowerLevel = getLevelValue(level - 1); long upperLevel = getLevelValue(level + 1); lowerOk = thisLevel >= lowerLevel; upperOk = thisLevel <= upperLevel; return lowerOk && upperOk; } @Override public String getValidatorErrorMessage() { if (!lowerOk) { return view.getMeterValidationHigherI18n(getLevelDescr(level - 1)); } if (!upperOk) { return view.getMeterValidationLowerI18n(getLevelDescr(level + 1)); } return view.getMeterValidationInvalidI18n(); } } private void console(Throwable e) { if (DomGlobal.console != null) { DomGlobal.console.error("Error running displayer."); DomGlobal.console.error(e); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerSettingsEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.MapColorScheme; import org.dashbuilder.displayer.Position; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.displayer.client.resources.i18n.MapColorSchemeConstants; import org.dashbuilder.displayer.client.resources.i18n.PositionConstants; import org.gwtbootstrap3.client.ui.Label; import org.gwtbootstrap3.client.ui.constants.LabelType; import org.uberfire.ext.properties.editor.client.PropertyEditorWidget; import org.uberfire.ext.properties.editor.model.PropertyEditorCategory; import org.uberfire.ext.properties.editor.model.PropertyEditorChangeEvent; import org.uberfire.ext.properties.editor.model.PropertyEditorEvent; import org.uberfire.ext.properties.editor.model.PropertyEditorFieldInfo; import org.uberfire.ext.properties.editor.model.validators.PropertyFieldValidator; import static org.uberfire.ext.properties.editor.model.PropertyEditorType.*; import static org.dashbuilder.displayer.DisplayerAttributeGroupDef.*; @Dependent public class DisplayerSettingsEditorView extends Composite implements DisplayerSettingsEditor.View { interface Binder extends UiBinder {} private static final Binder uiBinder = GWT.create( Binder.class ); @UiField Panel mainPanel; @UiField PropertyEditorWidget propertyEditor; DisplayerSettingsEditor presenter; List categories = new ArrayList(); Map attrMapI18n = new HashMap(); PropertyEditorCategory category = null; public static final String PROPERTY_EDITOR_ID = "displayerSettingsEditor"; @Override public void init(DisplayerSettingsEditor presenter) { this.presenter = presenter; attrMapI18n.put(GENERAL_GROUP, CommonConstants.INSTANCE.common_group()); attrMapI18n.put(TITLE, CommonConstants.INSTANCE.common_title()); attrMapI18n.put(TITLE_VISIBLE, CommonConstants.INSTANCE.common_showTitle()); attrMapI18n.put(ALLOW_EXPORT_CSV, CommonConstants.INSTANCE.common_allowCSV()); attrMapI18n.put(ALLOW_EXPORT_EXCEL, CommonConstants.INSTANCE.common_allowExcel()); attrMapI18n.put(EXPORT_GROUP, CommonConstants.INSTANCE.common_export()); attrMapI18n.put(EXPORT_TO_CSV, CommonConstants.INSTANCE.common_allowCSV()); attrMapI18n.put(EXPORT_TO_XLS, CommonConstants.INSTANCE.common_allowExcel()); attrMapI18n.put(RENDERER, CommonConstants.INSTANCE.common_renderer()); attrMapI18n.put(CHART_GROUP, CommonConstants.INSTANCE.chart_group()); attrMapI18n.put(CHART_WIDTH, CommonConstants.INSTANCE.chart_width()); attrMapI18n.put(CHART_HEIGHT, CommonConstants.INSTANCE.chart_height()); attrMapI18n.put(CHART_RESIZABLE, CommonConstants.INSTANCE.chart_resizable()); attrMapI18n.put(CHART_BGCOLOR, CommonConstants.INSTANCE.chart_bgColor()); attrMapI18n.put(CHART_3D, CommonConstants.INSTANCE.chart_3d()); attrMapI18n.put(CHART_MARGIN_GROUP, CommonConstants.INSTANCE.chart_marginGroup()); attrMapI18n.put(CHART_MARGIN_TOP, CommonConstants.INSTANCE.chart_topMargin()); attrMapI18n.put(CHART_MARGIN_BOTTOM, CommonConstants.INSTANCE.chart_bottomMargin()); attrMapI18n.put(CHART_MARGIN_LEFT, CommonConstants.INSTANCE.chart_leftMargin()); attrMapI18n.put(CHART_MARGIN_RIGHT, CommonConstants.INSTANCE.chart_rightMargin()); attrMapI18n.put(CHART_LEGEND_GROUP, CommonConstants.INSTANCE.chart_legendGroup()); attrMapI18n.put(CHART_SHOWLEGEND, CommonConstants.INSTANCE.chart_legendShow()); attrMapI18n.put(CHART_LEGENDPOSITION, CommonConstants.INSTANCE.chart_legendPosition()); attrMapI18n.put(XAXIS_GROUP, CommonConstants.INSTANCE.axis_group()); attrMapI18n.put(YAXIS_GROUP, CommonConstants.INSTANCE.axis_group()); attrMapI18n.put(XAXIS_SHOWLABELS, CommonConstants.INSTANCE.xaxis_showLabels()); attrMapI18n.put(XAXIS_TITLE, CommonConstants.INSTANCE.xaxis_title()); attrMapI18n.put(XAXIS_LABELSANGLE, CommonConstants.INSTANCE.xaxis_angle()); attrMapI18n.put(YAXIS_SHOWLABELS, CommonConstants.INSTANCE.yaxis_showLabels()); attrMapI18n.put(YAXIS_TITLE, CommonConstants.INSTANCE.yaxis_title()); attrMapI18n.put(TABLE_GROUP, CommonConstants.INSTANCE.table_group()); attrMapI18n.put(TABLE_PAGESIZE, CommonConstants.INSTANCE.table_pageSize()); attrMapI18n.put(TABLE_WIDTH, CommonConstants.INSTANCE.table_width()); attrMapI18n.put(TABLE_SORTENABLED, CommonConstants.INSTANCE.table_sortEnabled()); attrMapI18n.put(TABLE_SORTCOLUMNID, CommonConstants.INSTANCE.table_sortColumn()); attrMapI18n.put(TABLE_SORTORDER, CommonConstants.INSTANCE.table_sortOrder()); attrMapI18n.put(TABLE_COLUMN_PICKER_ENABLED, CommonConstants.INSTANCE.table_columnPicker()); attrMapI18n.put(METER_GROUP, CommonConstants.INSTANCE.meter_group()); attrMapI18n.put(METER_START, CommonConstants.INSTANCE.meter_start()); attrMapI18n.put(METER_WARNING, CommonConstants.INSTANCE.meter_warning()); attrMapI18n.put(METER_CRITICAL, CommonConstants.INSTANCE.meter_critical()); attrMapI18n.put(METER_END, CommonConstants.INSTANCE.meter_end()); attrMapI18n.put(FILTER_GROUP, CommonConstants.INSTANCE.filter_group()); attrMapI18n.put(FILTER_ENABLED, CommonConstants.INSTANCE.filter_enabled()); attrMapI18n.put(FILTER_SELFAPPLY_ENABLED, CommonConstants.INSTANCE.filter_self()); attrMapI18n.put(FILTER_LISTENING_ENABLED, CommonConstants.INSTANCE.filter_listening()); attrMapI18n.put(FILTER_NOTIFICATION_ENABLED, CommonConstants.INSTANCE.filter_notifications()); attrMapI18n.put(SELECTOR_GROUP, CommonConstants.INSTANCE.selector_group()); attrMapI18n.put(SELECTOR_WIDTH, CommonConstants.INSTANCE.selector_width()); attrMapI18n.put(SELECTOR_MULTIPLE, CommonConstants.INSTANCE.selector_multiple()); attrMapI18n.put(SELECTOR_SHOW_INPUTS, CommonConstants.INSTANCE.selector_show_inputs()); attrMapI18n.put(REFRESH_GROUP, CommonConstants.INSTANCE.refresh_group()); attrMapI18n.put(REFRESH_INTERVAL, CommonConstants.INSTANCE.refresh_interval()); attrMapI18n.put(REFRESH_STALE_DATA, CommonConstants.INSTANCE.refresh_stale_data()); attrMapI18n.put(COLUMNS_GROUP, CommonConstants.INSTANCE.common_columns()); attrMapI18n.put(MAP_GROUP, CommonConstants.INSTANCE.map_group()); attrMapI18n.put(MAP_COLOR_SCHEME, CommonConstants.INSTANCE.color_scheme()); initWidget(uiBinder.createAndBindUi(this)); } @Override public void clear() { categories.clear(); } @Override public void show() { propertyEditor.handle(new PropertyEditorEvent(PROPERTY_EDITOR_ID, categories)); } @Override public void dataSetNotFound() { mainPanel.add(new Label(LabelType.WARNING, CommonConstants.INSTANCE.error() + CommonConstants.INSTANCE.displayer_editor_dataset_notfound())); } @Override public void error(String message) { mainPanel.add(new Label(LabelType.WARNING, CommonConstants.INSTANCE.error() + message)); } @Override public void addCategory(DisplayerAttributeDef attributeDef) { String catName = attrMapI18n.get(attributeDef); category = new PropertyEditorCategory(catName); categories.add(category); } @Override public void addTextProperty(DisplayerAttributeDef attributeDef, String value, PropertyFieldValidator... validators) { String propName = attrMapI18n.get(attributeDef); category.withField(new PropertyEditorFieldInfo(propName, value, TEXT) .withValidators(validators) .withKey(attributeDef.getFullId())); } @Override public void addTextProperty(String propId, String propName, String value, PropertyFieldValidator... validators) { category.withField(new PropertyEditorFieldInfo(propName, value, TEXT) .withValidators(validators) .withKey(propId)); } @Override public void addBooleanProperty(DisplayerAttributeDef attributeDef, boolean value) { String propName = attrMapI18n.get(attributeDef); category.withField(new PropertyEditorFieldInfo(propName, Boolean.toString(value), BOOLEAN) .withKey(attributeDef.getFullId())); } @Override public void addColorProperty(DisplayerAttributeDef attributeDef, String color) { String propName = attrMapI18n.get(attributeDef); category.withField(new PropertyEditorFieldInfo(propName, color, COLOR) .withKey(attributeDef.getFullId())); } @Override public void addListProperty(DisplayerAttributeDef attributeDef, List optionList, String selectedValue) { String propName = attrMapI18n.get(attributeDef); category.withField(new PropertyEditorFieldInfo(propName, selectedValue, COMBO) .withComboValues(optionList) .withKey(attributeDef.getFullId())); } @Override public String getColumnNameI18n() { return CommonConstants.INSTANCE.columns_name(); } @Override public String getColumnExpressionI18n() { return CommonConstants.INSTANCE.columns_expression(); } @Override public String getColumnPatternI18n() { return CommonConstants.INSTANCE.columns_pattern(); } @Override public String getPositionLiteralI18n(Position position) { return PositionConstants.INSTANCE.getString("POSITION_" + position.toString()); } @Override public String getIntegerValidationFailedI18n() { return CommonConstants.INSTANCE.settings_validation_integer(); } @Override public String getDoubleValidationFailedI18n() { return CommonConstants.INSTANCE.settings_validation_double(); } @Override public String getMeterStartI18n() { return CommonConstants.INSTANCE.meter_start(); } @Override public String getMeterWarningI18n() { return CommonConstants.INSTANCE.meter_warning(); } @Override public String getMeterCriticalI18n() { return CommonConstants.INSTANCE.meter_critical(); } @Override public String getMeterEndI18n() { return CommonConstants.INSTANCE.meter_end(); } @Override public String getMeterUnknownI18n() { return CommonConstants.INSTANCE.settings_validation_meter_unknown(); } @Override public String getMeterValidationHigherI18n(String level) { return CommonConstants.INSTANCE.settings_validation_meter_higher(level); } @Override public String getMeterValidationLowerI18n(String level) { return CommonConstants.INSTANCE.settings_validation_meter_lower(level); } @Override public String getMeterValidationInvalidI18n() { return CommonConstants.INSTANCE.settings_validation_meter_invalid(); } @Override public String getMapColorSchemeI18n(MapColorScheme colorScheme) { return MapColorSchemeConstants.INSTANCE.getString("COLOR_SCHEME_" + colorScheme.toString()); } /** * Capture & process the modification events sent by the property editor */ protected void onPropertyEditorChange(@Observes PropertyEditorChangeEvent event) { PropertyEditorFieldInfo property = event.getProperty(); if (property.getEventId().equalsIgnoreCase(PROPERTY_EDITOR_ID)) { String attrKey = property.getKey(); String attrValue = event.getNewValue(); presenter.onAttributeChanged(attrKey, attrValue); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerSettingsEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerSettingsJSONSourceViewer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.JsonSourceViewer; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; public class DisplayerSettingsJSONSourceViewer extends Composite { interface SettingsEditorUIBinder extends UiBinder {} private static final SettingsEditorUIBinder uiBinder = GWT.create( SettingsEditorUIBinder.class ); DisplayerSettings displayerSettings; DisplayerSettingsJSONMarshaller jsonMarshaller; @UiField public JsonSourceViewer jsonSourceViewer; @Inject public DisplayerSettingsJSONSourceViewer() { initWidget( uiBinder.createAndBindUi( this ) ); jsonMarshaller = DisplayerSettingsJSONMarshaller.get(); } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public void setDisplayerSettings(DisplayerSettings displayerSettings) { jsonSourceViewer.setContent(jsonMarshaller.toJsonObject(displayerSettings)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerSettingsJSONSourceViewer.ui.xml ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerSubtypeSelector.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.RendererLibrary; import org.dashbuilder.displayer.client.RendererManager; import org.dashbuilder.displayer.client.events.DisplayerSubtypeSelectedEvent; import org.uberfire.client.mvp.UberView; @Dependent public class DisplayerSubtypeSelector implements IsWidget { public interface View extends UberView { void clear(); void show(DisplayerType type, DisplayerSubType subtype); void select(DisplayerSubType subtype); void showDefault(DisplayerType type); } View view = null; RendererManager rendererManager; DisplayerSubType selectedSubtype; Event selectEvent; @Inject public DisplayerSubtypeSelector(View view, RendererManager rendererManager, Event selectEvent) { this.view = view; this.rendererManager = rendererManager; this.selectEvent = selectEvent; view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public DisplayerSubType getSelectedSubtype() { return selectedSubtype; } public void init(DisplayerType type, DisplayerSubType selectedSubType) { view.clear(); RendererLibrary rendererLibrary = rendererManager.getRendererForType(type); if (rendererLibrary != null) { List supportedSubTypes = rendererLibrary.getSupportedSubtypes(type); if (supportedSubTypes != null && !supportedSubTypes.isEmpty()) { for (int i = 0; i < supportedSubTypes.size(); i++) { DisplayerSubType subtype = supportedSubTypes.get(i); // Double check the renderer library for invalid subtypes for this type if (!type.getSubTypes().contains(subtype)) { throw new RuntimeException("Wrong subtype (" + subtype + ") indicated for type " + type + " by renderer library " + rendererLibrary.getUUID()); } boolean initiallySelected = selectedSubType != null ? subtype == selectedSubType : i == 0; view.show(type, subtype); if (initiallySelected) { view.select(subtype); } } } else { view.showDefault(type); } } } void onSelect(DisplayerSubType subtype) { selectedSubtype = subtype; selectEvent.fire(new DisplayerSubtypeSelectedEvent(selectedSubtype)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerSubtypeSelectorView.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.HashMap; import java.util.Map; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.web.bindery.event.shared.HandlerRegistration; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.resources.i18n.DisplayerTypeConstants; import org.dashbuilder.displayer.client.resources.images.DisplayerImagesResources; import org.gwtbootstrap3.client.ui.Image; import org.gwtbootstrap3.client.ui.constants.ImageType; public class DisplayerSubtypeSelectorView extends Composite implements DisplayerSubtypeSelector.View { DisplayerSubtypeSelector presenter; Map imageWidgets = new HashMap(5); FlexTable subtypes = new FlexTable(); VerticalPanel subtypePanel = new VerticalPanel(); DisplayerSubTypeImageWidget selectedWidget = null; @Override public void init(DisplayerSubtypeSelector presenter) { this.presenter = presenter; subtypePanel.add(subtypes); initWidget(subtypePanel); } @Override public void clear() { subtypes.removeAllRows(); imageWidgets.clear(); } @Override public void show(DisplayerType type, final DisplayerSubType subtype) { String resourcePrefix = type.toString() + "_" + subtype.toString(); ImageResource selectedIR = (ImageResource) DisplayerImagesResources.INSTANCE.getResource(resourcePrefix + DisplayerImagesResources.SELECTED_SUFFIX); ImageResource unselectedIR = (ImageResource) DisplayerImagesResources.INSTANCE.getResource(resourcePrefix + DisplayerImagesResources.UNSELECTED_SUFFIX); String tooltip = DisplayerTypeConstants.INSTANCE.getString(resourcePrefix + "_tt"); final DisplayerSubTypeImageWidget dstiw = new DisplayerSubTypeImageWidget(selectedIR, unselectedIR, tooltip, false); imageWidgets.put(subtype, dstiw); subtypes.setWidget(subtypes.getRowCount(), 0, dstiw); dstiw.setSelectClickHandler(e -> { if (!dstiw.isSelected) { select(subtype); presenter.onSelect(subtype); } }); } @Override public void select(DisplayerSubType subtype) { if (selectedWidget != null) { selectedWidget.unselect(); } selectedWidget = imageWidgets.get(subtype); selectedWidget.select(); } @Override public void showDefault(DisplayerType type) { // Show a default image for those chart types that don't have any subtypes ImageResource selectedIR = (ImageResource)DisplayerImagesResources.INSTANCE.getResource(type.toString() + DisplayerImagesResources.DEFAULT_SUFFIX ); String tooltip = DisplayerTypeConstants.INSTANCE.getString(type.toString() + DisplayerImagesResources.DEFAULT_SUFFIX + "_tt"); DisplayerSubTypeImageWidget dstiw = new DisplayerSubTypeImageWidget(selectedIR, null, tooltip, true); subtypes.clear(); subtypes.setWidget(0, 0, dstiw); } public class DisplayerSubTypeImageWidget extends Composite { private FlexTable container = new FlexTable(); private boolean isSelected = false; private Image selected; private Image unselected; public DisplayerSubTypeImageWidget(ImageResource selectedImage, ImageResource unselectedImage, String tooltip, boolean initiallySelected) { initWidget(container); isSelected = initiallySelected; if (selectedImage != null) { selected = new Image(selectedImage); selected.setType(ImageType.THUMBNAIL); selected.setTitle(tooltip); selected.setVisible(isSelected); selected.addStyleName("selDispSubtype"); //for selenium container.setWidget(0, 0, selected); } if (unselectedImage != null) { unselected = new Image(unselectedImage); unselected.setType(ImageType.THUMBNAIL); unselected.setTitle(tooltip); unselected.setVisible(!isSelected); unselected.getElement().getStyle().setCursor(Style.Cursor.POINTER); container.setWidget(0, 1, unselected); } } public HandlerRegistration setSelectClickHandler(ClickHandler selectedClickHandler) { return unselected != null ? unselected.addClickHandler(selectedClickHandler) : null; } public void select() { isSelected = true; selected.setVisible(true); unselected.setVisible(false); } public void unselect() { isSelected = false; selected.setVisible(false); unselected.setVisible(true); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerTypeSelector.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Arrays; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.RendererManager; import org.dashbuilder.displayer.client.events.DisplayerTypeSelectedEvent; import org.uberfire.client.mvp.UberView; @Dependent public class DisplayerTypeSelector implements IsWidget { public interface View extends UberView { void clear(); void show(DisplayerType type); void select(DisplayerType type); } View view = null; DisplayerType selectedType = DisplayerType.BARCHART; DisplayerSubtypeSelector subtypeSelector; Event typeSelectedEvent; RendererManager rendererManager; @Inject public DisplayerTypeSelector(View view, DisplayerSubtypeSelector subtypeSelector, Event typeSelectedEvent, RendererManager rendererManager) { this.view = view; this.subtypeSelector = subtypeSelector; this.typeSelectedEvent = typeSelectedEvent; this.rendererManager = rendererManager; view.init(this); view.clear(); Arrays.stream(DisplayerType.values()) .filter(rendererManager::isTypeSupported) .forEach(view::show); view.select(selectedType); } @Override public Widget asWidget() { return view.asWidget(); } public DisplayerType getSelectedType() { return selectedType; } public DisplayerSubType getSelectedSubType() { return subtypeSelector.getSelectedSubtype(); } public DisplayerSubtypeSelector getSubtypeSelector() { return subtypeSelector; } public void init(DisplayerType selectedType, DisplayerSubType selectedSubtype) { this.selectedType = selectedType; view.select(selectedType); subtypeSelector.init(selectedType, selectedSubtype); } void onSelect(DisplayerType type) { selectedType = type; subtypeSelector.init(type, null); typeSelectedEvent.fire(new DisplayerTypeSelectedEvent(selectedType)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerTypeSelectorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.resources.i18n.DisplayerTypeConstants; import org.gwtbootstrap3.client.ui.NavTabs; import org.gwtbootstrap3.client.ui.TabListItem; import org.gwtbootstrap3.client.ui.TabPane; @Dependent public class DisplayerTypeSelectorView extends Composite implements DisplayerTypeSelector.View { interface ViewBinder extends UiBinder {} private static ViewBinder uiBinder = GWT.create(ViewBinder.class); Map displayerNames = new HashMap(); @UiField NavTabs navTabs; @UiField TabPane displayerSubTypePane; DisplayerTypeSelector presenter; @Override public void init(DisplayerTypeSelector presenter) { this.presenter = presenter; displayerNames.put(DisplayerType.BARCHART, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_bar()); displayerNames.put(DisplayerType.PIECHART, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_pie()); displayerNames.put(DisplayerType.LINECHART, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_line()); displayerNames.put(DisplayerType.AREACHART, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_area()); displayerNames.put(DisplayerType.BUBBLECHART, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_bubble()); displayerNames.put(DisplayerType.METERCHART, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_meter()); displayerNames.put(DisplayerType.METRIC, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_metric()); displayerNames.put(DisplayerType.MAP, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_map()); displayerNames.put(DisplayerType.TABLE, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_table()); displayerNames.put(DisplayerType.SELECTOR, DisplayerTypeConstants.INSTANCE.displayer_type_selector_tab_selector()); initWidget(uiBinder.createAndBindUi(this)); displayerSubTypePane.add(presenter.getSubtypeSelector()); displayerSubTypePane.setActive(true); } @Override public void clear() { navTabs.clear(); } @Override public void show(DisplayerType type) { String displayerName = displayerNames.get(type); DisplayerTab tab = new DisplayerTab(displayerName, type); tab.setDataTargetWidget(displayerSubTypePane); navTabs.add(tab); } @Override public void select(DisplayerType type) { for (int i=0; i ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/DisplayerViewer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.ui.*; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.AbstractDisplayerListener; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerListener; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.uberfire.mvp.Command; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; @Dependent public class DisplayerViewer extends Composite { protected DisplayerSettings displayerSettings; protected Panel container = new FlowPanel(); protected Label label = new Label(); protected Displayer displayer; protected Boolean isShowRendererSelector = false; @Inject protected DisplayerErrorWidget errorWidget; protected boolean error = true; protected DisplayerLocator displayerLocator; protected RendererSelector rendererSelector; ClientRuntimeError displayerInitializationError; CommonConstants i18n = CommonConstants.INSTANCE; DisplayerListener displayerListener = new AbstractDisplayerListener() { public void onDraw(Displayer displayer) { if (error) { show(); } } public void onRedraw(Displayer displayer) { if (error) { show(); } } public void onError(Displayer displayer, ClientRuntimeError error) { error(error); } }; @Inject public DisplayerViewer(DisplayerLocator displayerLocator, RendererSelector rendererSelector) { this.displayerLocator = displayerLocator; this.rendererSelector = rendererSelector; initWidget(container); } public DisplayerSettings getDisplayerSettings() { return displayerSettings; } public void setIsShowRendererSelector(Boolean isShowRendererSelector) { this.isShowRendererSelector = isShowRendererSelector; } public Displayer getDisplayer() { return displayer; } public void init(DisplayerSettings displayerSettings) { try { // Lookup the displayer checkNotNull("displayerSettings", displayerSettings); this.displayerSettings = displayerSettings; this.displayer = displayerLocator.lookupDisplayer(displayerSettings); this.displayer.addListener(displayerListener); // Make the displayer visible show(); } catch (Exception e) { displayerInitializationError = new ClientRuntimeError(e); error(displayerInitializationError); } } protected void show() { // Add the displayer into a container container.clear(); final FlowPanel displayerContainer = new FlowPanel(); displayerContainer.add(displayer); // Add the renderer selector (if enabled) if (isShowRendererSelector) { rendererSelector.init(displayerSettings, RendererSelector.SelectorType.TAB, 300, new Command() { public void execute() { displayerSettings.setRenderer(rendererSelector.getRendererLibrary().getUUID()); displayer = displayerLocator.lookupDisplayer(displayerSettings); displayer.draw(); displayerContainer.clear(); displayerContainer.add(displayer); } }); container.add(rendererSelector); } container.add(displayerContainer); error = false; } public Displayer draw() { if (displayerInitializationError != null ) { error(displayerInitializationError, i18n.displayerviewer_displayer_not_created()); } else { try { // Draw the displayer displayer.draw(); } catch (Exception e) { error(new ClientRuntimeError(e)); } } return displayer; } public Displayer redraw() { try { checkNotNull("displayerSettings", displayerSettings); checkNotNull("displayer", displayer); displayer.setDisplayerSettings(displayerSettings); displayer.redraw(); } catch (Exception e) { error(new ClientRuntimeError(e)); } return displayer; } public void error(ClientRuntimeError e) { String message = e.getMessage(); if (e.getThrowable() != null) { message = e.getThrowable().getMessage(); } error(e, message); } public void error(ClientRuntimeError e, String message) { container.clear(); container.add(errorWidget); errorWidget.show(message, e.getThrowable()); error = true; GWT.log(e.getMessage(), e.getThrowable()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.uberfire.client.mvp.UberView; @Dependent public class ExternalComponentEditor implements IsWidget { public interface View extends UberView { } @Inject View view; @Inject ExternalComponentPropertiesEditor propertiesEditor; @Inject ExternalComponentPresenter externalComponentPresenter; @Inject ExternalComponentMessageHelper messageHelper; private Map newProperties; @PostConstruct public void init() { view.init(this); } public void withComponent(String componentId, Map properties) { propertiesEditor.init(componentId, properties, this::propertiesChange); externalComponentPresenter.withComponent(componentId); propertiesChange(properties); } public void propertiesChange(Map propertiesChange) { this.newProperties = propertiesChange; Map props = new HashMap<>(propertiesChange); ExternalComponentMessage message = messageHelper.newInitMessage(props); externalComponentPresenter.sendMessage(message); } public Map getNewProperties() { return newProperties; } public ExternalComponentPresenter getExternalComponentPresenter() { return externalComponentPresenter; } public ExternalComponentPropertiesEditor getPropertiesEditor() { return propertiesEditor; } @Override public Widget asWidget() { return view.asWidget(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentEditorPopUp.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.uberfire.ext.widgets.common.client.common.popups.BaseModal; import org.uberfire.ext.widgets.common.client.common.popups.footers.ModalFooterOKCancelButtons; import org.uberfire.mvp.Command; @Dependent public class ExternalComponentEditorPopUp extends BaseModal { private final CommonConstants i18n = CommonConstants.INSTANCE; @Inject ExternalComponentEditor externalComponentEditor; private Command closeCommand; private Command saveCommand; @PostConstruct public void setup() { ModalFooterOKCancelButtons footer = createModalFooterOKCancelButtons(); footer.enableCancelButton(true); footer.enableOkButton(true); setBody(externalComponentEditor.asWidget()); add(footer); setTitle(i18n.componentEditor()); setWidth(1200 + "px"); } public void init(String componentId, Map properties, Command closeCommand, Command saveCommand) { this.closeCommand = closeCommand; this.saveCommand = saveCommand; this.addShowHandler(e -> externalComponentEditor.withComponent(componentId, properties)); show(); } protected ModalFooterOKCancelButtons createModalFooterOKCancelButtons() { return new ModalFooterOKCancelButtons(() -> { hide(); saveCommand.execute(); }, () -> { hide(); closeCommand.execute(); }); } public Map getProperties() { return externalComponentEditor.getNewProperties(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentEditorView.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ .componentEditorRootContainer { margin-top: 15px; } .componentEditorPropertiesColumn { overflow-x: hidden; overflow-y: auto; height: 370px; } .componentEditorPreviewColumn { height: 390px; overflow: auto; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentEditorView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentEditorView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.Composite; import elemental2.dom.HTMLDivElement; import org.jboss.errai.common.client.dom.elemental2.Elemental2DomUtil; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class ExternalComponentEditorView extends Composite implements ExternalComponentEditor.View { @Inject @DataField HTMLDivElement componentEditorRootContainer; @Inject @DataField HTMLDivElement componentEditorPropertiesColumn; @Inject @DataField HTMLDivElement componentEditorPreviewColumn; @Inject Elemental2DomUtil domUtil; @Override public void init(ExternalComponentEditor presenter) { domUtil.appendWidgetToElement(componentEditorPropertiesColumn, presenter.getPropertiesEditor().asWidget()); domUtil.appendWidgetToElement(componentEditorPreviewColumn, presenter.getExternalComponentPresenter().getView().asWidget()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentPresenter.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.function.Consumer; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.DOM; import org.dashbuilder.displayer.client.component.ExternalComponentDispatcher; import org.dashbuilder.displayer.client.component.ExternalComponentListener; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.dashbuilder.displayer.external.ExternalFilterRequest; import org.uberfire.client.mvp.UberView; @Dependent public class ExternalComponentPresenter implements ExternalComponentListener { /** * The base URL for components server. It should match the */ private static final String COMPONENT_SERVER_PATH = "dashbuilder/component"; /** * Unique Runtime ID for the component. It is used to identify messages coming from the component. */ final String componentRuntimeId = DOM.createUniqueId(); private Consumer filterConsumer; public interface View extends UberView { void setComponentURL(String url); void postMessage(ExternalComponentMessage message); void makeReady(); void configurationIssue(String message); void configurationOk(); } @Inject View view; @Inject ExternalComponentDispatcher dispatcher; @Inject ExternalComponentMessageHelper messageHelper; @PostConstruct public void init() { view.init(this); dispatcher.register(this); } @PreDestroy public void destroy() { dispatcher.unregister(this); } @Override public String getId() { return componentRuntimeId; } @Override public void onFilter(ExternalFilterRequest filterRequest) { if (filterConsumer != null) { filterConsumer.accept(filterRequest); } } @Override public void prepare() { view.makeReady(); } @Override public void onConfigurationIssue(String message) { view.configurationIssue(message); } @Override public void configurationOk() { view.configurationOk(); } public void withComponent(String componentId) { String url = buildUrl(componentId); view.setComponentURL(url); } public void withComponent(String componentId, String partition) { String url = buildUrl(componentId, partition); view.setComponentURL(url); } public void sendMessage(ExternalComponentMessage message) { messageHelper.withId(message, componentRuntimeId); view.postMessage(message); } public View getView() { return view; } public void setFilterConsumer(Consumer filterConsumer) { this.filterConsumer = filterConsumer; } public String getComponentId() { return componentRuntimeId; } private String buildUrl(String componentId) { return buildUrl(componentId, ""); } private String buildUrl(String componentId, String partition) { return String.join("/", GWT.getHostPageBaseURL(), COMPONENT_SERVER_PATH, partition, componentId, "index.html"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentPropertiesEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Stream; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.external.model.ComponentParameter; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentService; import org.jboss.errai.common.client.api.Caller; import org.uberfire.client.mvp.UberView; import org.uberfire.ext.properties.editor.model.PropertyEditorCategory; import org.uberfire.ext.properties.editor.model.PropertyEditorFieldInfo; import org.uberfire.ext.properties.editor.model.PropertyEditorType; import org.uberfire.ext.properties.editor.model.validators.MandatoryValidator; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; @Dependent public class ExternalComponentPropertiesEditor implements IsWidget { private static final CommonConstants i18n = CommonConstants.INSTANCE; private static final MandatoryValidator MANDATORY_VALIDATOR = new MandatoryValidator(); private static final String DEFAULT_CATEGORY = "Component Properties"; public interface View extends UberView { void componentNotFound(); void addCategories(Collection categories); void noPropertiesComponent(); } @Inject View view; @Inject Caller externalComponentService; @Inject BusyIndicatorView loading; private ExternalComponent currentComp; Map settings; Consumer> onPropertiesChange; @PostConstruct public void init() { view.init(this); } public void init(String componentId, Map settings, Consumer> onPropertiesChange) { this.settings = new HashMap<>(settings); this.onPropertiesChange = onPropertiesChange; if (componentId == null) { view.componentNotFound(); } else { loading.showBusyIndicator(i18n.loadingComponent()); externalComponentService.call((Optional comp) -> this.loadProperties(comp)) .byId(componentId); } } private void loadProperties(Optional compOp) { loading.hideBusyIndicator(); if (compOp.isPresent()) { currentComp = compOp.get(); loadProperties(); } else { view.componentNotFound(); } } private void loadProperties() { List parameters = currentComp.getParameters(); if (parameters == null || parameters.isEmpty()) { view.noPropertiesComponent(); } else { Map categories = new HashMap<>(); categories.put(DEFAULT_CATEGORY, new PropertyEditorCategory(DEFAULT_CATEGORY)); parameters.forEach(this::initializeSetting); notifyPropertyChange(); for (ComponentParameter param : parameters) { PropertyEditorCategory category = categories.get(DEFAULT_CATEGORY); if (param.getCategory() != null) { String catName = param.getCategory(); category = categories.computeIfAbsent(catName, PropertyEditorCategory::new); } category.withField(buildField(param)); } view.addCategories(categories.values()); } } public void onPropertyChange(String key, String value) { settings.put(key, value); notifyPropertyChange(); } private void notifyPropertyChange() { if (onPropertiesChange != null) { onPropertiesChange.accept(settings); } } private PropertyEditorFieldInfo buildField(ComponentParameter p) { String fieldKey = p.getName(); String currentValue = settings.get(fieldKey); PropertyEditorType type = getType(p.getType()); PropertyEditorFieldInfo field = new PropertyEditorFieldInfo(p.getLabel(), p.getDefaultValue(), type); field.withKey(fieldKey); if (field.getType() == PropertyEditorType.COMBO) { field.withComboValues(p.getComboValues()); } if (p.isMandatory()) { field.withValidators(Collections.singleton(MANDATORY_VALIDATOR)); field.withHelpInfo(i18n.mandatoryHelpHeader(), i18n.mandatoryHelpText()); } if (currentValue != null) { field.setCurrentStringValue(currentValue); } return field; } private PropertyEditorType getType(String type) { return Stream.of(PropertyEditorType.values()) .filter(t -> t.name().equalsIgnoreCase(type)) .findFirst().orElse(PropertyEditorType.TEXT); } private void initializeSetting(ComponentParameter p) { String componentProperty = settings.get(p.getName()); if (componentProperty == null) { settings.put(p.getName(), p.getDefaultValue()); } } @Override public Widget asWidget() { return view.asWidget(); } void setExternalComponentService(Caller externalComponentService) { this.externalComponentService = externalComponentService; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentPropertiesEditorView.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #externalComponentPropertiesPane { width: 100%; height: 100%; } #externalComponentPropertiesRoot { overflow: auto; height: auto; width: 100%; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentPropertiesEditorView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentPropertiesEditorView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.inject.Named; import com.google.gwt.dom.client.Document; import com.google.gwt.user.client.ui.Composite; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.jboss.errai.common.client.dom.elemental2.Elemental2DomUtil; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.properties.editor.client.PropertyEditorWidget; import org.uberfire.ext.properties.editor.model.PropertyEditorCategory; import org.uberfire.ext.properties.editor.model.PropertyEditorChangeEvent; import org.uberfire.ext.properties.editor.model.PropertyEditorEvent; import org.uberfire.ext.properties.editor.model.PropertyEditorFieldInfo; @Dependent @Templated public class ExternalComponentPropertiesEditorView extends Composite implements ExternalComponentPropertiesEditor.View { private final CommonConstants i18n = CommonConstants.INSTANCE; private final String externalComponentEditorId = Document.get().createUniqueId(); @Inject @DataField HTMLDivElement externalComponentPropertiesRoot; @Inject @DataField HTMLDivElement messageContainer; @Inject @DataField @Named("strong") HTMLElement messageTextContainer; @Inject Elemental2DomUtil elementalUtil; private PropertyEditorWidget propertyEditorWidget; private ExternalComponentPropertiesEditor presenter; @Override public void init(ExternalComponentPropertiesEditor presenter) { this.presenter = presenter; messageContainer.hidden = true; propertyEditorWidget = new PropertyEditorWidget(); elementalUtil.appendWidgetToElement(externalComponentPropertiesRoot, propertyEditorWidget); } @Override public void componentNotFound() { showMessage(i18n.componentNotFound()); } @Override public void addCategories(Collection categories) { messageContainer.hidden = true; externalComponentPropertiesRoot.hidden = false; List catList = new ArrayList<>(categories); propertyEditorWidget.handle(new PropertyEditorEvent(externalComponentEditorId, catList)); } protected void onPropertyEditorChange(@Observes PropertyEditorChangeEvent event) { PropertyEditorFieldInfo property = event.getProperty(); if (property.getEventId().equalsIgnoreCase(externalComponentEditorId)) { presenter.onPropertyChange(property.getKey(), property.getCurrentStringValue()); } } @Override public void noPropertiesComponent() { showMessage(i18n.noPropertiesComponent()); } private void showMessage(String message) { messageContainer.hidden = false; externalComponentPropertiesRoot.hidden = true; messageTextContainer.textContent = message; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentView.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #externalComponentIFrame { border: 0; width: 100%; height: 100%; display: block; position: relative; } .configuration-error-title-icon { margin-right: 10px; } .configuration-issue-message-box { margin: 10px; } .externalConfigurationIssueDetails { overflow-wrap: break-word; overflow: auto; max-height: 110px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentView.html ================================================

================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/ExternalComponentView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Composite; import elemental2.dom.Event; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLIFrameElement; import elemental2.dom.HTMLParagraphElement; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class ExternalComponentView extends Composite implements ExternalComponentPresenter.View { @Inject @DataField HTMLDivElement componentRoot; @Inject @DataField HTMLIFrameElement externalComponentIFrame; @Inject @DataField HTMLDivElement configurationIssueRoot; @Inject @DataField HTMLParagraphElement configurationDetails; @Inject ExternalComponentMessageHelper messageHelper; private boolean componentLoaded = false; private ExternalComponentMessage lastMessage; private ExternalComponentMessage initMessage; @Override public void init(ExternalComponentPresenter presenter) { showComponent(); } @Override public void setComponentURL(String url) { externalComponentIFrame.src = url; componentLoaded = false; externalComponentIFrame.onload = this::onInvoke; } @Override public void postMessage(ExternalComponentMessage message) { if (componentLoaded) { postMessageToComponent(message); } else { if (messageHelper.isInit(message)) { this.initMessage = message; } else { this.lastMessage = message; } } } private void postMessageToComponent(Object message) { if (externalComponentIFrame != null && externalComponentIFrame.contentWindow != null) { externalComponentIFrame.contentWindow.postMessage(message, Window.Location.getHref()); } } @Override public void makeReady() { // ready not supported at the moment. } @Override public void configurationIssue(String message) { configurationDetails.textContent = message; showConfigurationIssue(); } @Override public void configurationOk() { showComponent(); } private void showConfigurationIssue() { configurationIssueRoot.style.display = "block"; externalComponentIFrame.style.display = "none"; } private void showComponent() { configurationIssueRoot.style.display = "none"; externalComponentIFrame.style.display = "block"; } /** * Workaround to resolve generics after GWT upgrade. See https://issues.redhat.com/browse/AF-2542 */ private Object onInvoke(Event e) { componentLoaded = true; if (initMessage != null) { postMessageToComponent(initMessage); } if (lastMessage != null) { postMessageToComponent(lastMessage); } return null; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/RendererSelector.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.List; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.RendererLibrary; import org.dashbuilder.displayer.client.RendererManager; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; public class RendererSelector implements IsWidget { public enum SelectorType { LIST, RADIO, TAB; } public interface View extends UberView { void setVisible(boolean visible); void setWidth(int width); void setHeight(int height); void clearRendererSelector(); void addRendererItem(String renderer); void setSelectedRendererIndex(int index); String getRendererSelected(); } public interface TabListView extends View { } public interface ListBoxView extends View { } public interface RadioListView extends View { } View tabListView; View listBoxView; View radioListView; View view; RendererManager rendererManager; RendererLibrary rendererLibrary; Command selectCommand; @Inject public RendererSelector(TabListView tabListView, ListBoxView listBoxView, RadioListView radioListView, RendererManager rendererManager) { this.tabListView = tabListView; this.listBoxView = listBoxView; this.radioListView = radioListView; this.rendererManager = rendererManager; this.rendererLibrary = null; } @Override public Widget asWidget() { return view.asWidget(); } public RendererLibrary getRendererLibrary() { return rendererLibrary; } public void init(DisplayerSettings displayerSettings, SelectorType selectorType, int width, Command onSelectCommand) { // Choose the target view switch (selectorType) { case LIST: view = listBoxView; break; case RADIO: view = radioListView; break; case TAB: view = tabListView; break; } this.view.init(this); this.selectCommand = onSelectCommand; RendererLibrary rendererLibrary = rendererManager.getRendererForDisplayer(displayerSettings); List renderers = rendererManager.getRenderersForType(displayerSettings.getType(), displayerSettings.getSubtype()); if (renderers != null && renderers.size() > 1) { view.setVisible(true); view.setWidth(width); view.clearRendererSelector(); // Build the selector for (int i=0; i * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; public class RendererSelectorListBoxView extends Composite implements RendererSelector.ListBoxView { interface RendererSelectorBinder extends UiBinder {} private static final RendererSelectorBinder uiBinder = GWT.create(RendererSelectorBinder.class); @UiField Panel mainPanel; @UiField ListBox listBox; RendererSelector presenter = null; @Override public void init(final RendererSelector presenter) { this.presenter = presenter; initWidget(uiBinder.createAndBindUi(this)); listBox.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { presenter.onRendererSelected(); } }); } @Override public void setWidth(int width) { super.setWidth(width + "px"); mainPanel.setWidth(width + "px"); listBox.setWidth(width + "px"); } @Override public void setHeight(int height) { super.setHeight(height + "px"); mainPanel.setHeight(height + "px"); listBox.setWidth(height + "px"); } @Override public void clearRendererSelector() { listBox.clear(); } @Override public void addRendererItem(String renderer) { listBox.addItem(renderer); } @Override public void setSelectedRendererIndex(int index) { listBox.setSelectedIndex(index); } @Override public String getRendererSelected() { return listBox.getSelectedValue(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/RendererSelectorListBoxView.ui.xml ================================================ .mainPanelStyle { margin: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/RendererSelectorRadioListView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.RadioButton; public class RendererSelectorRadioListView extends Composite implements RendererSelector.RadioListView { interface RendererSelectorBinder extends UiBinder {} private static final RendererSelectorBinder uiBinder = GWT.create(RendererSelectorBinder.class); @UiField HorizontalPanel radioButtonsPanel; RendererSelector presenter = null; RadioButton selectedRadio = null; @Override public void init(final RendererSelector presenter) { this.presenter = presenter; initWidget(uiBinder.createAndBindUi(this)); } @Override public void setWidth(int width) { super.setWidth(width + "px"); radioButtonsPanel.setWidth(width + "px"); } @Override public void setHeight(int height) { super.setHeight(height + "px"); radioButtonsPanel.setHeight(height + "px"); } @Override public void clearRendererSelector() { radioButtonsPanel.clear(); selectedRadio = null; } @Override public void addRendererItem(final String renderer) { final RadioButton rb = new RadioButton(renderer); rb.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { unselectCurrent(); presenter.onRendererSelected(); } }); radioButtonsPanel.add(rb); } protected void unselectCurrent() { if (selectedRadio != null) { selectedRadio.setValue(false); } } @Override public void setSelectedRendererIndex(int index) { unselectCurrent(); selectedRadio = (RadioButton) radioButtonsPanel.getWidget(index); selectedRadio.setValue(true); } @Override public String getRendererSelected() { return selectedRadio == null ? null : selectedRadio.getText(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/RendererSelectorRadioListView.ui.xml ================================================ .mainPanelStyle { margin: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/RendererSelectorTabListView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.NavTabs; import org.gwtbootstrap3.client.ui.TabContent; import org.gwtbootstrap3.client.ui.TabListItem; import org.gwtbootstrap3.client.ui.TabPane; import org.gwtbootstrap3.client.ui.TabPanel; public class RendererSelectorTabListView extends Composite implements RendererSelector.TabListView { interface RendererSelectorBinder extends UiBinder {} private static final RendererSelectorBinder uiBinder = GWT.create(RendererSelectorBinder.class); @UiField TabPanel tabPanel; @UiField TabContent tabContent; @UiField NavTabs navTabs; RendererSelector presenter = null; TabListItem selectedTab = null; @Override public void init(final RendererSelector presenter) { this.presenter = presenter; initWidget(uiBinder.createAndBindUi(this)); } @Override public void setWidth(int width) { super.setWidth(width + "px"); tabPanel.setWidth(width + "px"); } @Override public void setHeight(int height) { super.setHeight(height + "px"); tabPanel.setHeight(height + "px"); } @Override public void clearRendererSelector() { tabContent.clear(); navTabs.clear(); selectedTab = null; } @Override public void addRendererItem(final String renderer) { final TabPane pane = new TabPane(); final TabListItem tabListItem = new TabListItem(); tabListItem.setDataTargetWidget(pane); tabListItem.setText(renderer); tabListItem.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { selectedTab = tabListItem; presenter.onRendererSelected(); } }); tabContent.add(pane); navTabs.add(tabListItem); } @Override public void setSelectedRendererIndex(int index) { TabListItem tabListItem = (TabListItem) navTabs.getWidget(index); tabListItem.setActive(true); tabListItem.showTab(); } @Override public String getRendererSelected() { return selectedTab == null ? null : selectedTab.getText().trim(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/RendererSelectorTabListView.ui.xml ================================================ .mainPanelStyle { margin: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/ColumnFilterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.date.TimeFrame; import org.dashbuilder.displayer.client.events.ColumnFilterChangedEvent; import org.dashbuilder.displayer.client.events.ColumnFilterDeletedEvent; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class ColumnFilterEditor implements IsWidget { public interface View extends UberView { void clearFunctionSelector(); void addFunctionItem(CoreFunctionType function); void setFunctionSelected(String function); int getSelectedFunctionIndex(); void showFilterConfig(); void clearFilterConfig(); void addFilterConfigWidget(IsWidget widget); String formatDate(Date date); String formatNumber(Number number); } View view = null; SyncBeanManager beanManager = null; ColumnFilter filter = null; DataSetMetadata metadata = null; Event changedEvent = null; Event deletedEvent = null; @Inject public ColumnFilterEditor(View view, SyncBeanManager beanManager, Event changedEvent, Event deletedEvent) { this.view = view; this.beanManager = beanManager; this.changedEvent = changedEvent; this.deletedEvent = deletedEvent; this.view.init(this); } public void init(DataSetMetadata metadata, ColumnFilter filter) { this.filter = filter; this.metadata = metadata; initFilterSelector(); initFilterConfig(); } public ColumnFilter getFilter() { return filter; } public View getView() { return view; } @Override public Widget asWidget() { return view.asWidget(); } public void expand() { view.showFilterConfig(); } // View notifications public void onSelectFilterFunction() { int selectedIdx = view.getSelectedFunctionIndex(); if (selectedIdx >= 0) { CoreFunctionFilter coreFilter = getCoreFilter(); CoreFunctionType functionType = getAvailableFunctions(coreFilter).get(selectedIdx); ColumnType columnType = metadata.getColumnType(coreFilter.getColumnId()); List params = FilterFactory.createParameters(columnType, functionType); coreFilter.setType(functionType); coreFilter.setParameters(params); initFilterSelector(); fireFilterChanged(); if (!initFilterConfig().isEmpty()) { view.showFilterConfig(); } } } public void onDeleteFilter() { deletedEvent.fire(new ColumnFilterDeletedEvent(this)); } // Internals protected CoreFunctionFilter getCoreFilter() { try { return (CoreFunctionFilter) filter; } catch (Exception e) { return null; } } protected List createFilterInputControls() { List filterInputControls = new ArrayList(); CoreFunctionFilter coreFilter = getCoreFilter(); if (CoreFunctionType.LIKE_TO.equals(coreFilter.getType())) { FunctionParameterEditor paramInput = createLikeToFunctionWidget(coreFilter); filterInputControls.add(paramInput); } else { for (int i = 0; i < coreFilter.getType().getParametersCount(); i++) { FunctionParameterEditor paramInput = createParamInputWidget(coreFilter, i); filterInputControls.add(paramInput); } } return filterInputControls; } protected void initFilterSelector() { CoreFunctionFilter coreFilter = getCoreFilter(); if (coreFilter != null) { view.clearFunctionSelector(); String currentFunction = formatFilterFunction(coreFilter); view.setFunctionSelected(currentFunction); List calculateAvailableFunctions = getAvailableFunctions(coreFilter); for (CoreFunctionType functionType : calculateAvailableFunctions) { view.addFunctionItem(functionType); } } } protected List getAvailableFunctions(CoreFunctionFilter coreFilter) { ColumnType columnType = metadata.getColumnType(coreFilter.getColumnId()); List functionTypes = CoreFunctionType.getSupportedTypes(columnType); Iterator it = functionTypes.iterator(); while (it.hasNext()) { CoreFunctionType next = it.next(); if (next.equals(coreFilter.getType())) { it.remove(); } } return functionTypes; } protected List initFilterConfig() { view.clearFilterConfig(); List inputs = createFilterInputControls(); if (!inputs.isEmpty()) { for (IsWidget input : inputs) { view.addFilterConfigWidget(input); } inputs.get(0).setFocus(true); } return inputs; } protected void updateSelectedFilter() { String currentFunction = formatFilterFunction(getCoreFilter()); view.setFunctionSelected(currentFunction); fireFilterChanged(); } protected void fireFilterChanged() { changedEvent.fire(new ColumnFilterChangedEvent(this)); } protected FunctionParameterEditor createParamInputWidget(final CoreFunctionFilter coreFilter, final int paramIndex) { final List paramList = coreFilter.getParameters(); ColumnType columnType = metadata.getColumnType(coreFilter.getColumnId()); CoreFunctionType functionType = coreFilter.getType(); boolean isMultiple = CoreFunctionType.IN.equals(functionType) || CoreFunctionType.NOT_IN.equals(functionType); if (ColumnType.DATE.equals(columnType)) { if (CoreFunctionType.TIME_FRAME.equals(coreFilter.getType())) { return createTimeFrameWidget(paramList, paramIndex); } return createDateInputWidget(paramList, paramIndex); } if (!isMultiple) { if (ColumnType.NUMBER.equals(columnType)) { return createNumberInputWidget(paramList, paramIndex); } return createTextInputWidget(paramList, paramIndex); } else { if (ColumnType.NUMBER.equals(columnType)) { return createMultipleNumberInputWidget(paramList); } return createMultipleTextInputWidget(paramList); } } protected FunctionParameterEditor createDateInputWidget(final List paramList, final int paramIndex) { Date param = (Date) paramList.get(paramIndex); final DateParameterEditor input = beanManager.lookupBean(DateParameterEditor.class).newInstance(); input.setValue(param); input.setOnChangeCommand(new Command() { public void execute() { paramList.set(paramIndex, input.getValue()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createNumberInputWidget(final List paramList, final int paramIndex) { final NumberParameterEditor input = beanManager.lookupBean(NumberParameterEditor.class).newInstance(); input.setValue(Double.parseDouble(paramList.get(paramIndex).toString())); input.setOnChangeCommand(new Command() { public void execute() { paramList.set(paramIndex, input.getValue()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createTextInputWidget(final List paramList, final int paramIndex) { final TextParameterEditor input = beanManager.lookupBean(TextParameterEditor.class).newInstance(); input.setValue((String) paramList.get(paramIndex)); input.setOnChangeCommand(new Command() { public void execute() { paramList.set(paramIndex, input.getValue()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createMultipleNumberInputWidget(final List paramList) { final MultipleNumberParameterEditor input = beanManager.lookupBean(MultipleNumberParameterEditor.class).newInstance(); input.setValues(paramList); input.setOnChangeCommand(new Command() { public void execute() { updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createMultipleTextInputWidget(final List paramList) { final MultipleTextParameterEditor input = beanManager.lookupBean(MultipleTextParameterEditor.class).newInstance(); input.setValues(paramList); input.setOnChangeCommand(new Command() { public void execute() { updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createTimeFrameWidget(final List paramList, final int paramIndex) { TimeFrame timeFrame = TimeFrame.parse((String) paramList.get(paramIndex)); final TimeFrameEditor input = beanManager.lookupBean(TimeFrameEditor.class).newInstance(); input.init(timeFrame, new Command() { public void execute() { paramList.set(paramIndex, input.getTimeFrame().toString()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createLikeToFunctionWidget(final CoreFunctionFilter coreFilter) { final LikeToFunctionEditor input = beanManager.lookupBean(LikeToFunctionEditor.class).newInstance(); final List paramList = coreFilter.getParameters(); String pattern = (String) paramList.get(0); boolean caseSensitive = paramList.size() < 2 || Boolean.parseBoolean(paramList.get(1).toString()); input.setCaseSensitive(caseSensitive); input.setPattern(pattern); input.setOnChangeCommand(new Command() { public void execute() { paramList.clear(); paramList.add(input.getPattern()); if (!input.isCaseSensitive()) { // Only add if disabled since case sensitive is enabled by default. paramList.add(input.isCaseSensitive()); } updateSelectedFilter(); } }); return input; } public String formatFilterFunction(CoreFunctionFilter filter) { String columnId = filter.getColumnId(); CoreFunctionType type = filter.getType(); List parameters = filter.getParameters(); StringBuilder out = new StringBuilder(); if (CoreFunctionType.BETWEEN.equals(type)) { out.append(columnId).append(" ["); formatParameters(out, parameters); out.append("]"); } else if (CoreFunctionType.GREATER_THAN.equals(type)) { out.append(columnId).append(" > "); formatParameters(out, parameters); } else if (CoreFunctionType.GREATER_OR_EQUALS_TO.equals(type)) { out.append(columnId).append(" >= "); formatParameters(out, parameters); } else if (CoreFunctionType.LOWER_THAN.equals(type)) { out.append(columnId).append(" < "); formatParameters(out, parameters); } else if (CoreFunctionType.LOWER_OR_EQUALS_TO.equals(type)) { out.append(columnId).append(" <= "); formatParameters(out, parameters); } else if (CoreFunctionType.EQUALS_TO.equals(type)) { out.append(columnId).append(" = "); formatParameters(out, parameters); } else if (CoreFunctionType.NOT_EQUALS_TO.equals(type)) { out.append(columnId).append(" != "); formatParameters(out, parameters); } else if (CoreFunctionType.LIKE_TO.equals(type)) { out.append(columnId).append(" like "); formatParameters(out, parameters); } else if (CoreFunctionType.IS_NULL.equals(type)) { out.append(columnId).append(" = null "); formatParameters(out, parameters); } else if (CoreFunctionType.NOT_NULL.equals(type)) { out.append(columnId).append(" != null "); formatParameters(out, parameters); } else if (CoreFunctionType.TIME_FRAME.equals(type)) { out.append(columnId).append(" = "); formatParameters(out, parameters); } else if (CoreFunctionType.IN.equals(type)) { out.append(columnId).append(" in ("); formatParameters(out, parameters); out.append(")"); } else if (CoreFunctionType.NOT_IN.equals(type)) { out.append(columnId).append(" not in ("); formatParameters(out, parameters); out.append(")"); } return out.toString(); } protected StringBuilder formatParameters(StringBuilder out, List parameters) { for (int i=0; i< parameters.size(); i++) { if (i > 0) out.append(" "); out.append(formatParameter(parameters.get(i))); } return out; } protected String formatParameter(Object p) { if (p == null) { return ""; } if (p instanceof Date) { Date d = (Date) p; return view.formatDate(d); } if (p instanceof Number) { Number n = (Number) p; return view.formatNumber(n); } return p.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/ColumnFilterEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Date; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.client.resources.i18n.CoreFunctionTypeConstants; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.ListBox; import org.gwtbootstrap3.client.ui.constants.IconType; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; public class ColumnFilterEditorView extends Composite implements ColumnFilterEditor.View { interface Binder extends UiBinder { } private static Binder uiBinder = GWT.create(Binder.class); ColumnFilterEditor presenter; boolean functionSelected = false; @UiField ListBox filterListBox; @UiField Button filterDeleteIcon; @UiField Button filterExpandIcon; @UiField Panel filterDetailsPanel; // View interface public void init(ColumnFilterEditor presenter) { this.presenter = checkNotNull("presenter", presenter); initWidget(uiBinder.createAndBindUi(this)); filterExpandIcon.addDomHandler(new ClickHandler() { public void onClick(ClickEvent event) { onExpandCollapseDetails(); } }, ClickEvent.getType()); filterDeleteIcon.addDomHandler(new ClickHandler() { public void onClick(ClickEvent event) { onDeleteFilter(); } }, ClickEvent.getType()); } @Override public void clearFunctionSelector() { filterListBox.clear(); functionSelected = false; } @Override public void addFunctionItem(CoreFunctionType ft) { String function = CoreFunctionTypeConstants.INSTANCE.getString(ft.name()); filterListBox.addItem(function); filterExpandIcon.setVisible(true); } @Override public void setFunctionSelected(String function) { filterListBox.insertItem(function, 0); filterListBox.setTitle(function); if (functionSelected) { filterListBox.removeItem(1); } functionSelected = true; } @Override public int getSelectedFunctionIndex() { return filterListBox.getSelectedIndex() - (functionSelected ? 1 : 0); } @Override public void showFilterConfig() { filterExpandIcon.setVisible(true); filterExpandIcon.setIcon(IconType.ANGLE_DOWN); filterExpandIcon.setTitle(CommonConstants.INSTANCE.collapse()); filterDetailsPanel.setVisible(true); } public void hideParamConfigWidgets() { filterDetailsPanel.setVisible(false); filterExpandIcon.setIcon(IconType.ANGLE_RIGHT); filterExpandIcon.setTitle(CommonConstants.INSTANCE.expand()); } @Override public void addFilterConfigWidget(IsWidget widget) { filterDetailsPanel.add(widget); filterExpandIcon.setVisible(true); } @Override public void clearFilterConfig() { filterDetailsPanel.clear(); filterDetailsPanel.setVisible(false); filterExpandIcon.setVisible(false); } // UI events @UiHandler(value = "filterListBox") public void onFilterSelected(ChangeEvent changeEvent) { presenter.onSelectFilterFunction(); } public void onExpandCollapseDetails() { if (filterDetailsPanel.isVisible()) { hideParamConfigWidgets(); } else { showFilterConfig(); } } protected void onDeleteFilter() { presenter.onDeleteFilter(); } // Internals DateTimeFormat _dateTimeFormat = DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_MEDIUM); NumberFormat _numberFormat = NumberFormat.getDecimalFormat(); @Override public String formatDate(Date date) { return _dateTimeFormat.format(date); } @Override public String formatNumber(Number number) { return _numberFormat.format(number); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/ColumnFilterEditorView.ui.xml ================================================ .filterDetailsPanel { width: 100%; padding: 5px; border-radius: 5px; } .filter-padding { padding-bottom: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/DataSetFilterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.displayer.client.events.ColumnFilterChangedEvent; import org.dashbuilder.displayer.client.events.ColumnFilterDeletedEvent; import org.dashbuilder.displayer.client.events.DataSetFilterChangedEvent; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberView; @Dependent public class DataSetFilterEditor implements IsWidget { public interface View extends UberView { void showNewFilterHome(); void clearColumnSelector(); void showColumnSelector(); void addColumn(String column); int getSelectedColumnIndex(); void resetSelectedColumn(); void clearColumnFilterEditors(); void addColumnFilterEditor(ColumnFilterEditor editor); void removeColumnFilterEditor(ColumnFilterEditor editor); } View view = null; DataSetFilter filter = null; DataSetMetadata metadata = null; SyncBeanManager beanManager; Event changeEvent; @Inject public DataSetFilterEditor(View view, SyncBeanManager beanManager, Event changeEvent) { this.view = view; this.beanManager = beanManager; this.changeEvent = changeEvent; view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public DataSetFilter getFilter() { return filter; } public void init(DataSetFilter filter, DataSetMetadata metadata) { this.filter = filter; this.metadata = metadata; view.showNewFilterHome(); view.clearColumnSelector(); if (metadata != null) { for (int i = 0; i < metadata.getNumberOfColumns(); i++) { view.addColumn(metadata.getColumnId(i)); } } view.clearColumnFilterEditors(); if (filter != null) { for (ColumnFilter columnFilter : filter.getColumnFilterList()) { ColumnFilterEditor columnFilterEditor = beanManager.lookupBean(ColumnFilterEditor.class).newInstance(); columnFilterEditor.init(metadata, columnFilter); view.addColumnFilterEditor(columnFilterEditor); } } } // View notifications public void onNewFilterStart() { view.showColumnSelector(); } public void onNewFilterCancel() { view.showNewFilterHome(); } public void onCreateFilter() { int selectedIdx = view.getSelectedColumnIndex(); String columnId = metadata.getColumnId(selectedIdx); ColumnType columnType = metadata.getColumnType(selectedIdx); CoreFunctionFilter columnFilter = FilterFactory.createCoreFunctionFilter( columnId, columnType, ColumnType.DATE.equals(columnType) ? CoreFunctionType.TIME_FRAME : CoreFunctionType.NOT_EQUALS_TO); if (filter == null) { filter = new DataSetFilter(); } filter.addFilterColumn(columnFilter); ColumnFilterEditor columnFilterEditor = beanManager.lookupBean(ColumnFilterEditor.class).newInstance(); columnFilterEditor.init(metadata, columnFilter); columnFilterEditor.expand(); view.addColumnFilterEditor(columnFilterEditor); view.resetSelectedColumn(); view.showNewFilterHome(); changeEvent.fire(new DataSetFilterChangedEvent(filter)); } // Column filter child component callbacks protected void onColumnFilterChanged(@Observes ColumnFilterChangedEvent event) { changeEvent.fire(new DataSetFilterChangedEvent(filter)); } protected void onColumnFilterDeleted(@Observes final ColumnFilterDeletedEvent event) { ColumnFilterEditor editor = event.getColumnFilterEditor(); ColumnFilter columnFilter = editor.getFilter(); filter.getColumnFilterList().remove(columnFilter); view.removeColumnFilterEditor(editor); view.showNewFilterHome(); beanManager.destroyBean(editor); changeEvent.fire(new DataSetFilterChangedEvent(filter)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/DataSetFilterEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.Icon; import org.gwtbootstrap3.client.ui.ListBox; public class DataSetFilterEditorView extends Composite implements DataSetFilterEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField ListBox newFilterListBox; @UiField Panel filterListPanel; @UiField Button addFilterButton; @UiField Panel addFilterPanel; @UiField Button filterDeleteIcon; DataSetFilterEditor presenter = null; public DataSetFilterEditorView() { initWidget(uiBinder.createAndBindUi(this)); filterDeleteIcon.addDomHandler(new ClickHandler() { public void onClick(ClickEvent event) { onNewFilterClosed(event); } }, ClickEvent.getType()); } @Override public void init(DataSetFilterEditor presenter) { this.presenter = presenter; } @Override public void showNewFilterHome() { addFilterButton.setVisible(true); addFilterPanel.setVisible(false); } @Override public void clearColumnSelector() { newFilterListBox.clear(); newFilterListBox.addItem(CommonConstants.INSTANCE.filter_editor_selectcolumn()); } @Override public void showColumnSelector() { addFilterButton.setVisible(false); addFilterPanel.setVisible(true); } @Override public void addColumn(String column) { newFilterListBox.addItem(column); } @Override public int getSelectedColumnIndex() { return newFilterListBox.getSelectedIndex() - 1; } @Override public void resetSelectedColumn() { newFilterListBox.setSelectedIndex(0); } @Override public void clearColumnFilterEditors() { filterListPanel.clear(); } @Override public void addColumnFilterEditor(ColumnFilterEditor editor) { filterListPanel.add(editor); } @Override public void removeColumnFilterEditor(ColumnFilterEditor editor) { filterListPanel.remove(editor); } // UI events @UiHandler(value = "addFilterButton") public void onAddFilterClicked(ClickEvent event) { presenter.onNewFilterStart(); } public void onNewFilterClosed(ClickEvent event) { presenter.onNewFilterCancel(); } @UiHandler(value = "newFilterListBox") public void onNewFilterSelected(ChangeEvent changeEvent) { presenter.onCreateFilter(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/DataSetFilterEditorView.ui.xml ================================================ .filter-editor-margin { margin-left: 35px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/DateParameterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Date; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.Widget; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class DateParameterEditor implements FunctionParameterEditor { public interface View extends UberView { Date getValue(); void setValue(Date value); void setWidth(int width); } Command onChangeCommand = () -> {}; Command onFocusCommand = () -> {}; Command onBlurCommand = () -> {}; View view; Date currentValue = null; @Inject public DateParameterEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void setOnChangeCommand(Command onChangeCommand) { this.onChangeCommand = onChangeCommand; } public void setOnFocusCommand(Command onFocusCommand) { this.onFocusCommand = onFocusCommand; } public void setOnBlurCommand(Command onBlurCommand) { this.onBlurCommand = onBlurCommand; } public Date getValue() { return view.getValue(); } public void setValue(Date value) { Command backup = onChangeCommand; this.currentValue = value; try { onChangeCommand = null; view.setValue(value); } finally { onChangeCommand = backup; } } public void setWidth(int width) { if (width > 0) { view.setWidth(width); } } @Override public void setFocus(boolean focus) { } void onChange() { if (onChangeCommand != null && !currentValue.equals(getValue())) { currentValue = getValue(); onChangeCommand.execute(); } } void onBlur() { if (onBlurCommand != null) { onBlurCommand.execute(); } } void onFocus() { if (onFocusCommand!= null) { onFocusCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/DateParameterEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Date; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Button; import org.uberfire.ext.widgets.common.client.common.DatePicker; @Dependent public class DateParameterEditorView extends Composite implements DateParameterEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); DateParameterEditor presenter; @UiField DatePicker input; @UiField Button icon; protected boolean show = false; public DateParameterEditorView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(final DateParameterEditor presenter) { this.presenter = presenter; input.addValueChangeHandler(e -> { presenter.onChange(); }); input.addBlurHandler(e -> { presenter.onBlur(); }); input.addShowHandler(e -> { presenter.onFocus(); show = true; }); input.addHideHandler(e -> { show = false; }); icon.addClickHandler(e -> { if (!show) { input.onShow(null); } }); } @Override public Date getValue() { return input.getValue(); } @Override public void setValue(Date value) { input.setValue(value); } @Override public void setWidth(int width) { input.asWidget().getElement().getStyle().setWidth(width, Style.Unit.PX); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/DateParameterEditorView.ui.xml ================================================ .datePicker { float: left; width: 275px; } .calendarIcon { margin-left: -1px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/FunctionParameterEditor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import com.google.gwt.user.client.ui.IsWidget; public interface FunctionParameterEditor extends IsWidget { void setFocus(boolean focus); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/LikeToFunctionEditor.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class LikeToFunctionEditor implements FunctionParameterEditor { public interface View extends UberView { void setPattern(String pattern); void setCaseSensitive(boolean caseSensitive); String getPattern(); boolean isCaseSensitive(); void setFocus(boolean focus); void error(); } Command onChangeCommand = new Command() { public void execute() {} }; String pattern; View view; @Inject public LikeToFunctionEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void setOnChangeCommand(Command onChangeCommand) { this.onChangeCommand = onChangeCommand; } public void setPattern(String pattern) { this.pattern = pattern; view.setPattern(pattern); } public void setCaseSensitive(boolean caseSensitive) { view.setCaseSensitive(caseSensitive); } public String getPattern() { return pattern; } public boolean isCaseSensitive() { return view.isCaseSensitive(); } @Override public void setFocus(boolean focus) { view.setFocus(focus); } void viewUpdated() { String s = view.getPattern(); if (s == null || s.trim().length() == 0) { view.error(); } else { pattern = s; onChangeCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/LikeToFunctionEditorView.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.CheckBox; import org.gwtbootstrap3.client.ui.FormGroup; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.constants.ValidationState; @Dependent public class LikeToFunctionEditorView extends Composite implements LikeToFunctionEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); LikeToFunctionEditor presenter; @UiField FormGroup form; @UiField TextBox searchPatternTextBox; @UiField CheckBox caseSensitiveCheckbox; public LikeToFunctionEditorView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(LikeToFunctionEditor presenter) { this.presenter = presenter; } @Override public void setPattern(String pattern) { form.setValidationState(ValidationState.NONE); searchPatternTextBox.setText(pattern); } @Override public void setCaseSensitive(boolean caseSensitive) { caseSensitiveCheckbox.setValue(caseSensitive); } @Override public String getPattern() { return searchPatternTextBox.getText(); } @Override public boolean isCaseSensitive() { return caseSensitiveCheckbox.getValue(); } @Override public void setFocus(final boolean focus) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { public void execute () { searchPatternTextBox.setFocus(focus); } }); } @UiHandler("searchPatternTextBox") public void onPatternChanged(ChangeEvent event) { presenter.viewUpdated(); form.setValidationState(ValidationState.NONE); } @UiHandler("caseSensitiveCheckbox") public void onCaseChanged(ClickEvent event) { presenter.viewUpdated(); } @Override public void error() { form.setValidationState(ValidationState.ERROR); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/LikeToFunctionEditorView.ui.xml ================================================ .labelFont { font-size: small; } .checkBox { margin-top: 0px; margin-bottom: 0px; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/MultipleNumberParameterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.StringUtils; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class MultipleNumberParameterEditor implements FunctionParameterEditor { public interface View extends UberView { String getValue(); void setValue(String value); void error(); void setFocus(boolean focus); } Command onChangeCommand = new Command() { public void execute() {} }; List values = new ArrayList(); View view; @Inject public MultipleNumberParameterEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void setOnChangeCommand(Command onChangeCommand) { this.onChangeCommand = onChangeCommand; } public List getValues() { return values; } public void setValues(List input) { values = input; view.setValue(format(input)); } @Override public void setFocus(boolean focus) { view.setFocus(focus); } void valueChanged() { try { List l = parse(view.getValue().trim()); if (l.isEmpty()) { view.error(); } else { values.clear(); values.addAll(l); onChangeCommand.execute(); } } catch (Exception e) { view.error(); } } public List parse(String s) throws Exception { List result = new ArrayList(); List tokens = s.contains("|") ? StringUtils.split(s, '|') : StringUtils.split(s, ','); for (String token : tokens) { result.add(Double.parseDouble(token.trim())); } return result; } public String format(List l) { StringBuilder out = new StringBuilder(); for (Object val : l) { if (out.length() > 0) { out.append(" | "); } out.append(val); } return out.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/MultipleNumberParameterEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.FormGroup; import org.gwtbootstrap3.client.ui.Icon; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.constants.ValidationState; @Dependent public class MultipleNumberParameterEditorView extends Composite implements MultipleNumberParameterEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); MultipleNumberParameterEditor presenter; @UiField FormGroup form; @UiField TextBox input; public MultipleNumberParameterEditorView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(final MultipleNumberParameterEditor presenter) { this.presenter = presenter; input.addValueChangeHandler(new ValueChangeHandler() { public void onValueChange(ValueChangeEvent event) { form.setValidationState(ValidationState.NONE); presenter.valueChanged(); } }); } @Override public String getValue() { return input.getValue(); } @Override public void setValue(String value) { input.setValue(value); form.setValidationState(ValidationState.NONE); } @Override public void setFocus(final boolean focus) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { public void execute () { input.setFocus(focus); } }); } @Override public void error() { form.setValidationState(ValidationState.ERROR); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/MultipleNumberParameterEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/MultipleTextParameterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.StringUtils; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class MultipleTextParameterEditor implements FunctionParameterEditor { public interface View extends UberView { String getValue(); void setValue(String value); void error(); void setFocus(boolean focus); } Command onChangeCommand = new Command() { public void execute() {} }; List values = new ArrayList(); View view; @Inject public MultipleTextParameterEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void setOnChangeCommand(Command onChangeCommand) { this.onChangeCommand = onChangeCommand; } public List getValues() { return values; } public void setValues(List input) { values = input; view.setValue(format(input)); } @Override public void setFocus(boolean focus) { view.setFocus(focus); } void valueChanged() { try { List l = parse(view.getValue().trim()); if (l.isEmpty()) { view.error(); } else { values.clear(); values.addAll(l); onChangeCommand.execute(); } } catch (Exception e) { view.error(); } } public List parse(String s) throws Exception { List result = new ArrayList(); List tokens = s.contains("|") ? StringUtils.split(s, '|') : StringUtils.split(s, ','); for (String token : tokens) { result.add(token.trim()); } return result; } public String format(List l) { StringBuilder out = new StringBuilder(); for (Object val : l) { if (out.length() > 0) { out.append(" | "); } out.append(val); } return out.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/MultipleTextParameterEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.FormGroup; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.constants.ValidationState; @Dependent public class MultipleTextParameterEditorView extends Composite implements MultipleTextParameterEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); MultipleTextParameterEditor presenter; @UiField FormGroup form; @UiField TextBox input; public MultipleTextParameterEditorView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(final MultipleTextParameterEditor presenter) { this.presenter = presenter; input.addValueChangeHandler(new ValueChangeHandler() { public void onValueChange(ValueChangeEvent event) { form.setValidationState(ValidationState.NONE); presenter.valueChanged(); } }); } @Override public String getValue() { return input.getValue(); } @Override public void setValue(String value) { input.setValue(value); form.setValidationState(ValidationState.NONE); } @Override public void setFocus(final boolean focus) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { public void execute () { input.setFocus(focus); } }); } @Override public void error() { form.setValidationState(ValidationState.ERROR); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/MultipleTextParameterEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/NumberParameterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class NumberParameterEditor implements FunctionParameterEditor { public interface View extends UberView { String getValue(); void setValue(String value); void setWidth(int width); void error(); void setFocus(boolean focus); } Command onChangeCommand = () -> {}; Number value; View view; @Inject public NumberParameterEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void setOnChangeCommand(Command onChangeCommand) { this.onChangeCommand = onChangeCommand; } public Number getValue() { return value; } public void setValue(Number input) { Command backup = onChangeCommand; try { onChangeCommand = null; value = input; view.setValue(format(value)); } finally { onChangeCommand = backup; } } public void setWidth(int width) { if (width > 0) { view.setWidth(width); } } @Override public void setFocus(boolean focus) { view.setFocus(focus); } void valueChanged() { try { Number n = parse(view.getValue()); if (n == null) { view.error(); } else { value = n; if (onChangeCommand != null) { onChangeCommand.execute(); } } } catch (Exception e) { view.error(); } } public Number parse(String s) throws Exception { if (s == null || s.trim().length() == 0) { return null; } return Double.parseDouble(s.trim()); } public String format(Number n) { return n.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/NumberParameterEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.Style; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.FormGroup; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.constants.ValidationState; @Dependent public class NumberParameterEditorView extends Composite implements NumberParameterEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); NumberParameterEditor presenter; @UiField FormGroup form; @UiField TextBox input; public NumberParameterEditorView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(final NumberParameterEditor presenter) { this.presenter = presenter; input.addValueChangeHandler(new ValueChangeHandler() { public void onValueChange(ValueChangeEvent event) { form.setValidationState(ValidationState.NONE); presenter.valueChanged(); } }); } @Override public String getValue() { return input.getValue(); } @Override public void setValue(String value) { input.setValue(value); form.setValidationState(ValidationState.NONE); } @Override public void setWidth(int width) { input.asWidget().getElement().getStyle().setWidth(width, Style.Unit.PX); } @Override public void setFocus(final boolean focus) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { public void execute () { input.setFocus(focus); } }); } @Override public void error() { form.setValidationState(ValidationState.ERROR); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/NumberParameterEditorView.ui.xml ================================================ .field-editor-margin { margin-bottom: 0px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TextParameterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class TextParameterEditor implements FunctionParameterEditor { public interface View extends UberView { String getValue(); void setValue(String value); void error(); void setFocus(boolean focus); } Command onChangeCommand = new Command() { public void execute() { } }; String value; View view; @Inject public TextParameterEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void setOnChangeCommand(Command onChangeCommand) { this.onChangeCommand = onChangeCommand; } public String getValue() { return value; } public void setValue(String input) { value = input; view.setValue(input); } @Override public void setFocus(boolean focus) { view.setFocus(focus); } void valueChanged() { String s = view.getValue(); if (s == null || s.trim().length() == 0) { view.error(); } else { value = s; onChangeCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TextParameterEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.FormGroup; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.constants.ValidationState; @Dependent public class TextParameterEditorView extends Composite implements TextParameterEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); TextParameterEditor presenter; @UiField FormGroup form; @UiField TextBox input; public TextParameterEditorView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(final TextParameterEditor presenter) { this.presenter = presenter; input.addValueChangeHandler(new ValueChangeHandler() { public void onValueChange(ValueChangeEvent event) { form.setValidationState(ValidationState.NONE); presenter.valueChanged(); } }); } @Override public String getValue() { return input.getValue(); } @Override public void setValue(String value) { input.setValue(value); form.setValidationState(ValidationState.NONE); } @Override public void setFocus(final boolean focus) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { public void execute () { input.setFocus(focus); } }); } @Override public void error() { form.setValidationState(ValidationState.ERROR); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TextParameterEditorView.ui.xml ================================================ .form-group-margin { margin-bottom: 0px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeAmountEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Arrays; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.dataset.date.TimeAmount; import org.dashbuilder.dataset.group.DateIntervalType; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class TimeAmountEditor implements IsWidget { public interface View extends UberView { void setQuantity(long quantity); long getQuantity(); void clearIntervalTypeSelector(); void addIntervalTypeItem(DateIntervalType type); void setSelectedTypeIndex(int typeIdx); int getSelectedTypeIndex(); } public static List INTERVAL_TYPES = Arrays.asList( DateIntervalType.SECOND, DateIntervalType.MINUTE, DateIntervalType.HOUR, DateIntervalType.DAY, DateIntervalType.WEEK, DateIntervalType.MONTH, DateIntervalType.QUARTER, DateIntervalType.YEAR, DateIntervalType.CENTURY); View view; TimeAmount timeAmount = null; Command onChangeCommand = new Command() { public void execute() {} }; @Inject public TimeAmountEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public TimeAmount getTimeAmount() { return timeAmount; } public void init(final TimeAmount ta, Command onChangeCommand) { this.onChangeCommand = onChangeCommand; this.timeAmount = ta != null ? ta : new TimeAmount(); view.setQuantity(timeAmount.getQuantity()); view.clearIntervalTypeSelector(); for (int i=0; i< INTERVAL_TYPES.size(); i++) { DateIntervalType type = INTERVAL_TYPES.get(i); view.addIntervalTypeItem(type); if (timeAmount != null && timeAmount.getType().equals(type)) { view.setSelectedTypeIndex(i); } } } public long getQuantity() { return timeAmount.getQuantity(); } public void decreaseQuantity() { long q = getQuantity()-1; changeQuantity(q); view.setQuantity(q); } public void increaseQuantity() { long q = getQuantity()+1; changeQuantity(q); view.setQuantity(q); } public void changeQuantity(String value) { if (StringUtils.isBlank(value)) { changeQuantity(0); } else { changeQuantity(Long.parseLong(value)); } } public void changeIntervalType() { DateIntervalType type = INTERVAL_TYPES.get(view.getSelectedTypeIndex()); timeAmount.setType(type); onChangeCommand.execute(); } protected void changeQuantity(long q) { if (timeAmount == null) { timeAmount = new TimeAmount(); DateIntervalType type = INTERVAL_TYPES.get(0); timeAmount.setType(type); } timeAmount.setQuantity(q); onChangeCommand.execute(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeAmountEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.client.resources.i18n.DateIntervalTypeConstants; import org.dashbuilder.dataset.group.DateIntervalType; import org.gwtbootstrap3.client.ui.InputGroupAddon; import org.gwtbootstrap3.client.ui.ListBox; import org.uberfire.ext.widgets.common.client.common.NumericLongTextBox; @Dependent public class TimeAmountEditorView extends Composite implements TimeAmountEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); TimeAmountEditor presenter = null; @UiField NumericLongTextBox input; @UiField InputGroupAddon minusIcon; @UiField InputGroupAddon plusIcon; @UiField ListBox typeList; @Override public void init(final TimeAmountEditor presenter) { this.presenter = presenter; initWidget(uiBinder.createAndBindUi(this)); plusIcon.addDomHandler(new ClickHandler() { public void onClick(ClickEvent event) { presenter.increaseQuantity(); } }, ClickEvent.getType()); minusIcon.addDomHandler(new ClickHandler() { public void onClick(ClickEvent event) { presenter.decreaseQuantity(); } }, ClickEvent.getType()); input.addValueChangeHandler(new ValueChangeHandler() { public void onValueChange(ValueChangeEvent event) { presenter.changeQuantity(event.getValue()); } }); } @Override public void setQuantity(long quantity) { input.setValue(Long.toString(quantity)); } @Override public long getQuantity() { return Long.valueOf(input.getValue()); } @Override public void clearIntervalTypeSelector() { typeList.clear(); } @Override public void addIntervalTypeItem(DateIntervalType type) { String typeName = DateIntervalTypeConstants.INSTANCE.getString(type.name()); typeList.addItem(typeName); } @Override public void setSelectedTypeIndex(int idx) { typeList.setSelectedIndex(idx); } @Override public int getSelectedTypeIndex() { return typeList.getSelectedIndex(); } // UI events @UiHandler(value = "typeList") public void onFilterSelected(ChangeEvent changeEvent) { presenter.changeIntervalType(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeAmountEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeFrameEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.date.TimeFrame; import org.dashbuilder.dataset.date.TimeInstant; import org.dashbuilder.dataset.group.DateIntervalType; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class TimeFrameEditor implements FunctionParameterEditor { public interface View extends UberView { void hideFirstMonthSelector(); void showFirstMonthSelector(); void clearFirstMonthSelector(); void addFirstMonthItem(Month month); void setSelectedFirstMonthIndex(int index); int getSelectedFirstMonthIndex(); } View view; SyncBeanManager beanManager; TimeFrame timeFrame = null; TimeInstantEditor fromEditor; TimeInstantEditor toEditor; Command onChangeCommand = new Command() { public void execute() {} }; @Inject public TimeFrameEditor(View view, SyncBeanManager beanManager) { this.view = view; this.beanManager = beanManager; } @Override public Widget asWidget() { return view.asWidget(); } public TimeFrame getTimeFrame() { return timeFrame; } public TimeInstantEditor getFromEditor() { return fromEditor; } public TimeInstantEditor getToEditor() { return toEditor; } public void init(TimeFrame tf, Command onChangeCommand) { this.onChangeCommand = onChangeCommand; this.timeFrame = tf != null ? tf : TimeFrame.parse("begin[year] till end[year]"); this.fromEditor = beanManager.lookupBean(TimeInstantEditor.class).newInstance(); this.fromEditor.init(timeFrame.getFrom(), new Command() { public void execute() { fromEditor.getTimeInstant().setFirstMonthOfYear(getFirstMonthOfYear()); timeFrame.setFrom(fromEditor.getTimeInstant()); changeFirstMonthAvailability(); fireChanges(); } }); this.toEditor = beanManager.lookupBean(TimeInstantEditor.class).newInstance(); this.toEditor.init(timeFrame.getTo(), new Command() { public void execute() { toEditor.getTimeInstant().setFirstMonthOfYear(getFirstMonthOfYear()); timeFrame.setTo(toEditor.getTimeInstant()); changeFirstMonthAvailability(); fireChanges(); } }); view.init(this); initFirstMonthSelector(); changeFirstMonthAvailability(); } protected void initFirstMonthSelector() { view.clearFirstMonthSelector(); Month current = getFirstMonthOfYear(); Month[] entries = Month.values(); for (int i = 0; i < entries.length; i++) { Month entry = entries[i]; view.addFirstMonthItem(entry); if (current != null && current.equals(entry)) { view.setSelectedFirstMonthIndex(i); } } } protected void changeFirstMonthAvailability() { view.hideFirstMonthSelector(); if (isFirstMonthAvailable()) { view.showFirstMonthSelector(); } } public boolean isFirstMonthAvailable() { TimeInstant instantFrom = timeFrame.getFrom(); TimeInstant.TimeMode modeFrom = instantFrom.getTimeMode(); if (modeFrom != null && !modeFrom.equals(TimeInstant.TimeMode.NOW)) { DateIntervalType intervalType = instantFrom.getIntervalType(); if (intervalType != null && intervalType.getIndex() > DateIntervalType.MONTH.getIndex()) { return true; } } TimeInstant instantTo = timeFrame.getTo(); TimeInstant.TimeMode modeTo = instantTo.getTimeMode(); if (modeTo != null && !modeTo.equals(TimeInstant.TimeMode.NOW)) { DateIntervalType intervalType = instantTo.getIntervalType(); if (intervalType != null && intervalType.getIndex() > DateIntervalType.MONTH.getIndex()) { return true; } } return false; } public Month getFirstMonthOfYear() { TimeInstant instantFrom = timeFrame.getFrom(); TimeInstant.TimeMode modeFrom = instantFrom.getTimeMode(); if (modeFrom != null && !modeFrom.equals(TimeInstant.TimeMode.NOW)) { DateIntervalType intervalType = instantFrom.getIntervalType(); if (intervalType != null && intervalType.getIndex() > DateIntervalType.MONTH.getIndex()) { return instantFrom.getFirstMonthOfYear(); } } TimeInstant instantTo = timeFrame.getTo(); TimeInstant.TimeMode modeTo = instantTo.getTimeMode(); if (modeTo != null && !modeTo.equals(TimeInstant.TimeMode.NOW)) { DateIntervalType intervalType = instantTo.getIntervalType(); if (intervalType != null && intervalType.getIndex() > DateIntervalType.MONTH.getIndex()) { return instantTo.getFirstMonthOfYear(); } } return null; } public void setFirstMonthOfYear(Month month) { TimeInstant instantFrom = timeFrame.getFrom(); TimeInstant.TimeMode modeFrom = instantFrom.getTimeMode(); if (modeFrom != null && !modeFrom.equals(TimeInstant.TimeMode.NOW)) { DateIntervalType intervalType = instantFrom.getIntervalType(); if (intervalType != null && intervalType.getIndex() > DateIntervalType.MONTH.getIndex()) { instantFrom.setFirstMonthOfYear(month); } } TimeInstant instantTo = timeFrame.getTo(); TimeInstant.TimeMode modeTo = instantTo.getTimeMode(); if (modeTo != null && !modeTo.equals(TimeInstant.TimeMode.NOW)) { DateIntervalType intervalType = instantTo.getIntervalType(); if (intervalType != null && intervalType.getIndex() > DateIntervalType.MONTH.getIndex()) { instantTo.setFirstMonthOfYear(month); } } } @Override public void setFocus(boolean focus) { } public void changeFirstMonth() { int selectedIdx = view.getSelectedFirstMonthIndex(); Month month = Month.getByIndex(selectedIdx + 1); setFirstMonthOfYear(month); fireChanges(); } protected void fireChanges() { onChangeCommand.execute(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeFrameEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.client.resources.i18n.MonthConstants; import org.dashbuilder.dataset.date.Month; import org.gwtbootstrap3.client.ui.ListBox; @Dependent public class TimeFrameEditorView extends Composite implements TimeFrameEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField(provided = true) TimeInstantEditor fromEditor; @UiField(provided = true) TimeInstantEditor toEditor; @UiField Label firstMonthLabel; @UiField ListBox firstMonthList; TimeFrameEditor presenter = null; @Override public void init(TimeFrameEditor presenter) { this.presenter = presenter; fromEditor = presenter.getFromEditor(); toEditor = presenter.getToEditor(); initWidget(uiBinder.createAndBindUi(this)); } @Override public void hideFirstMonthSelector() { firstMonthLabel.setVisible(false); firstMonthList.setVisible(false); } @Override public void showFirstMonthSelector() { firstMonthLabel.setVisible(true); firstMonthList.setVisible(true); } @Override public void clearFirstMonthSelector() { firstMonthList.clear(); } @Override public void addFirstMonthItem(Month month) { firstMonthList.addItem(MonthConstants.INSTANCE.getString(month.name())); } @Override public void setSelectedFirstMonthIndex(int index) { firstMonthList.setSelectedIndex(index); } @Override public int getSelectedFirstMonthIndex() { return firstMonthList.getSelectedIndex(); } // UI events @UiHandler(value = "firstMonthList") public void onFirstMonthSelected(ChangeEvent changeEvent) { presenter.changeFirstMonth(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeFrameEditorView.ui.xml ================================================ .labelFont { font-size: small; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeInstantEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Arrays; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.date.TimeAmount; import org.dashbuilder.dataset.date.TimeInstant; import org.dashbuilder.dataset.group.DateIntervalType; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class TimeInstantEditor implements IsWidget { public interface View extends UberView { void clearTimeModeSelector(); void addTimeModeItem(TimeInstant.TimeMode timeMode); void setSelectedTimeModeIndex(int index); int getTimeModeSelectedIndex(); void enableIntervalTypeSelector(); void disableIntervalTypeSelector(); void clearIntervalTypeSelector(); void addIntervalTypeItem(DateIntervalType type); void setSelectedIntervalTypeIndex(int index); int getSelectedIntervalTypeIndex(); } static List INTERVAL_TYPES = Arrays.asList( DateIntervalType.MINUTE, DateIntervalType.HOUR, DateIntervalType.DAY, DateIntervalType.MONTH, DateIntervalType.QUARTER, DateIntervalType.YEAR, DateIntervalType.CENTURY, DateIntervalType.MILLENIUM); View view; TimeInstant timeInstant = null; TimeAmountEditor timeAmountEditor = null; Command onChangeCommand = new Command() { public void execute() {} }; @Inject public TimeInstantEditor(View view, TimeAmountEditor timeAmountEditor) { this.timeAmountEditor = timeAmountEditor; this.timeInstant = new TimeInstant(); this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public TimeInstant getTimeInstant() { return timeInstant; } public void init(final TimeInstant ti, final Command onChangeCommand) { this.timeInstant = ti != null ? ti : new TimeInstant(); this.onChangeCommand = onChangeCommand; this.timeAmountEditor.init(timeInstant.getTimeAmount(), new Command() { public void execute() { timeInstant.setTimeAmount(timeAmountEditor.getTimeAmount()); onChangeCommand.execute(); } }); initTimeModeSelector(); initIntervalTypeSelector(); } public TimeAmountEditor getTimeAmountEditor() { return timeAmountEditor; } protected void initTimeModeSelector() { view.clearTimeModeSelector(); TimeInstant.TimeMode current = timeInstant.getTimeMode(); TimeInstant.TimeMode[] modes = TimeInstant.TimeMode.values(); for (int i=0; i {} private static Binder uiBinder = GWT.create(Binder.class); @UiField ListBox timeModeList; @UiField ListBox intervalTypeList; @UiField(provided = true) TimeAmountEditor timeAmountEditor; TimeInstantEditor presenter = null; @Override public void init(TimeInstantEditor presenter) { this.presenter = presenter; this.timeAmountEditor = presenter.getTimeAmountEditor(); initWidget(uiBinder.createAndBindUi(this)); } @Override public void clearTimeModeSelector() { timeModeList.clear(); } @Override public void addTimeModeItem(TimeInstant.TimeMode mode) { timeModeList.addItem(TimeModeConstants.INSTANCE.getString(mode.name())); } @Override public void setSelectedTimeModeIndex(int index) { timeModeList.setSelectedIndex(index); } @Override public void enableIntervalTypeSelector() { intervalTypeList.setVisible(true); } @Override public void disableIntervalTypeSelector() { intervalTypeList.setVisible(false); } @Override public void clearIntervalTypeSelector() { intervalTypeList.clear(); } @Override public void addIntervalTypeItem(DateIntervalType type) { intervalTypeList.addItem(DateIntervalTypeConstants.INSTANCE.getString(type.name())); } @Override public void setSelectedIntervalTypeIndex(int index) { intervalTypeList.setSelectedIndex(index); } @Override public int getTimeModeSelectedIndex() { return timeModeList.getSelectedIndex(); } @Override public int getSelectedIntervalTypeIndex() { return intervalTypeList.getSelectedIndex(); } // UI events @UiHandler(value = "timeModeList") public void onTimeModeSelected(ChangeEvent changeEvent) { presenter.changeTimeMode(); } @UiHandler(value = "intervalTypeList") public void onIntervalTypeSelected(ChangeEvent changeEvent) { presenter.changeIntervalType(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/filter/TimeInstantEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/ColumnDetailsEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.displayer.client.events.ColumnDetailsChangedEvent; import org.uberfire.client.mvp.UberView; @Dependent public class ColumnDetailsEditor implements IsWidget { public interface View extends UberView { void setColumnId(String columnId); String getColumnId(); } View view = null; GroupFunction column = null; DataSetMetadata metadata = null; Event changedEvent = null; @Inject public ColumnDetailsEditor(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public GroupFunction getColumn() { return column; } public void init(DataSetMetadata metadata, GroupFunction groupFunction) { this.column = groupFunction; this.metadata = metadata; if (StringUtils.isBlank(column.getColumnId())) { view.setColumnId(column.getSourceId()); } else { view.setColumnId(column.getColumnId()); } } void onColumnNameChanged() { String text = view.getColumnId(); if (!StringUtils.isBlank(text)) { column.setColumnId(text); changedEvent.fire(new ColumnDetailsChangedEvent(column)); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/ColumnDetailsEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.TextBox; @Dependent public class ColumnDetailsEditorView extends Composite implements ColumnDetailsEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField Label columnIdLabel; @UiField TextBox columnIdTextBox; ColumnDetailsEditor presenter; @Override public void init(ColumnDetailsEditor columnDetailsEditor) { this.presenter = columnDetailsEditor; initWidget(uiBinder.createAndBindUi(this)); } @Override public void setColumnId(String columnId) { columnIdTextBox.setText(columnId); } @Override public String getColumnId() { return columnIdTextBox.getText(); } // UI events @UiHandler(value = "columnIdTextBox") public void onColumnNameChanged(ChangeEvent changeEvent) { presenter.onColumnNameChanged(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/ColumnDetailsEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/ColumnFunctionEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import java.util.List; import java.util.ArrayList; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.displayer.client.events.GroupFunctionChangedEvent; import org.dashbuilder.displayer.client.events.GroupFunctionDeletedEvent; import org.uberfire.client.mvp.UberView; @Dependent public class ColumnFunctionEditor implements IsWidget { public interface View extends UberView { void setDeleteOptionEnabled(boolean enabled); void setColumnSelectorTitle(String title); void clearColumnSelector(); void addColumnItem(String columnId); void setSelectedColumnIndex(int i); String getSelectedColumnId(); void setFunctionSelectorEnabled(boolean enabled); void clearFunctionSelector(); void setVoidFunctionEnabled(boolean enabled); void addFunctionItem(AggregateFunctionType functionType); void setSelectedFunctionIndex(int i); int getSelectedFunctionIndex(); } View view = null; GroupFunction groupFunction = null; ColumnType targetType = null; boolean functionsEnabled = false; DataSetMetadata metadata = null; ColumnDetailsEditor columnDetailsEditor = null; Event changeEvent = null; Event deleteEvent = null; @Inject public ColumnFunctionEditor(View view, ColumnDetailsEditor columnDetailsEditor, Event changeEvent, Event deleteEvent) { this.view = view; this.columnDetailsEditor = columnDetailsEditor; this.changeEvent = changeEvent; this.deleteEvent = deleteEvent; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public GroupFunction getGroupFunction() { return groupFunction; } public ColumnType getTargetType() { return targetType; } public ColumnDetailsEditor getColumnDetailsEditor() { return columnDetailsEditor; } public void init(DataSetMetadata metadata, GroupFunction groupFunction, ColumnType targetType, String columnTitle, boolean functionsEnabled, boolean canDelete) { this.groupFunction = groupFunction; this.targetType = targetType; this.metadata = metadata; this.functionsEnabled = functionsEnabled; columnDetailsEditor.init(metadata, this.groupFunction); view.setColumnSelectorTitle(columnTitle); view.setDeleteOptionEnabled(canDelete); initColumnListBox(); if (functionsEnabled && (targetType == null || isColumnNumeric())) { view.setFunctionSelectorEnabled(true); initFunctionListBox(); } else { view.setFunctionSelectorEnabled(false); } } public void delete() { deleteEvent.fire(new GroupFunctionDeletedEvent(groupFunction)); } void onColumnSelected() { groupFunction.setSourceId(view.getSelectedColumnId()); if (!isColumnNumeric()) { groupFunction.setFunction(null); } else { groupFunction.setFunction(getSupportedFunctionTypes().get(0)); } initFunctionListBox(); changeEvent.fire(new GroupFunctionChangedEvent(groupFunction)); } void onFunctionSelected() { AggregateFunctionType selected = null; int i = view.getSelectedFunctionIndex(); if (i >= 0) { List supportedFunctions = getSupportedFunctionTypes(); selected = supportedFunctions.get(i); } groupFunction.setFunction(selected); changeEvent.fire(new GroupFunctionChangedEvent(groupFunction)); } protected boolean isColumnNumeric() { return targetType != null && targetType.equals(ColumnType.NUMBER) && functionsEnabled; } protected void initColumnListBox() { view.clearColumnSelector(); for (int i=0; i supportedFunctions = getSupportedFunctionTypes(); for (int i=0; i getSupportedFunctionTypes() { ColumnType columnType = metadata.getColumnType(groupFunction.getSourceId()); return getSupportedFunctionTypes(columnType); } public List getSupportedFunctionTypes(ColumnType columnType) { List result = new ArrayList(); for (AggregateFunctionType function : AggregateFunctionType.values()) { if (function.supportType(columnType)) { result.add(function); } } return result; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/ColumnFunctionEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.client.resources.i18n.AggregateFunctionTypeConstants; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.gwtbootstrap3.client.ui.Icon; import org.gwtbootstrap3.client.ui.ListBox; import org.gwtbootstrap3.client.ui.constants.IconType; @Dependent public class ColumnFunctionEditorView extends Composite implements ColumnFunctionEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField ListBox columnListBox; @UiField ListBox functionListBox; @UiField Icon columnDeleteIcon; @UiField Icon columnExpandIcon; @UiField Panel columnDetailsPanel; @UiField(provided = true) ColumnDetailsEditor columnDetailsEditor; ColumnFunctionEditor presenter = null; boolean voidFunctionEnabled = false; @Override public void init(final ColumnFunctionEditor presenter) { this.presenter = presenter; this.columnDetailsEditor = presenter.getColumnDetailsEditor(); initWidget(uiBinder.createAndBindUi(this)); columnExpandIcon.addDomHandler(new ClickHandler() { public void onClick(ClickEvent event) { expandOrCollapse(); } }, ClickEvent.getType()); columnDeleteIcon.addDomHandler(new ClickHandler() { public void onClick(ClickEvent event) { presenter.delete(); } }, ClickEvent.getType()); } @Override public void setDeleteOptionEnabled(boolean enabled) { columnDeleteIcon.setVisible(enabled); } @Override public void setColumnSelectorTitle(String title) { columnListBox.setTitle(title); } @Override public void clearColumnSelector() { columnListBox.clear(); } @Override public void addColumnItem(String columnId) { columnListBox.addItem(columnId); } @Override public void setSelectedColumnIndex(int i) { columnListBox.setSelectedIndex(i); } @Override public String getSelectedColumnId() { return columnListBox.getValue(columnListBox.getSelectedIndex()); } @Override public void setFunctionSelectorEnabled(boolean enabled) { if (enabled) { functionListBox.setVisible(true); columnListBox.setWidth("120px"); } else { functionListBox.setVisible(false); columnListBox.setWidth("200px"); } } @Override public void clearFunctionSelector() { functionListBox.clear(); } @Override public void setVoidFunctionEnabled(boolean enabled) { voidFunctionEnabled = enabled; if (enabled) { functionListBox.addItem("---"); } } @Override public void addFunctionItem(AggregateFunctionType functionType) { String functionName = AggregateFunctionTypeConstants.INSTANCE.getString(functionType.name()); functionListBox.addItem(functionName); } @Override public void setSelectedFunctionIndex(int i) { functionListBox.setSelectedIndex(voidFunctionEnabled ? i+1 : i); } @Override public int getSelectedFunctionIndex() { int i = functionListBox.getSelectedIndex(); return voidFunctionEnabled ? i-1 : i; } // UI events protected void expandOrCollapse() { if (columnDetailsPanel.isVisible()) { collapse(); } else { expand(); } } protected void expand() { columnDetailsPanel.setVisible(true); columnExpandIcon.setType(IconType.ARROW_UP); } protected void collapse() { columnDetailsPanel.setVisible(false); columnExpandIcon.setType(IconType.ARROW_DOWN); } @UiHandler(value = "columnListBox") protected void onColumnSelected(ChangeEvent changeEvent) { presenter.onColumnSelected(); } @UiHandler(value = "functionListBox") protected void onFunctionSelected(ChangeEvent changeEvent) { presenter.onFunctionSelected(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/ColumnFunctionEditorView.ui.xml ================================================ .columnDetailsPanel { width: 200px; padding: 5px; background: #dddddd; border-radius: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/DataSetGroupDateEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import java.util.Arrays; import java.util.List; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.GroupStrategy; import org.dashbuilder.displayer.client.events.DataSetGroupDateChanged; import org.uberfire.client.mvp.UberView; @Dependent public class DataSetGroupDateEditor implements IsWidget { public interface View extends UberView { void setFixedModeValue(boolean enabled); boolean getFixedModeValue(); void clearIntervalTypeSelector(); void addIntervalTypeItem(DateIntervalType entry); void setSelectedIntervalTypeIndex(int index); int getSelectedIntervalTypeIndex(); void setFirstDayVisibility(boolean visible); void clearFirstDaySelector(); void addFirstDaySelectorItem(DayOfWeek entry); void setSelectedFirstDayIndex(int index); int getSelectedFirstDayIndex(); void setFirstMonthVisibility(boolean visible); void clearFirstMonthSelector(); void addFirstMonthSelectorItem(Month entry); void setSelectedFirstMonthIndex(int index); int getSelectedFirstMonthIndex(); void setEmptyIntervalsValue(boolean enabled); boolean getEmptyIntervalsValue(); void setMaxIntervalsVisibility(boolean visible); void setMaxIntervalsValue(String max); String getMaxIntervalsValue(); } View view = null; ColumnGroup columnGroup = null; Event changeEvent = null; @Inject public DataSetGroupDateEditor(View view, Event changeEvent) { this.view = view; this.changeEvent = changeEvent; view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public ColumnGroup getColumnGroup() { return columnGroup; } public void init(ColumnGroup columnGroup) { this.columnGroup = columnGroup; if (columnGroup != null) { if (isFixedStrategy()) { gotoFixedMode(); } else { gotoDynamicMode(); } } } public boolean isFixedStrategy() { return GroupStrategy.FIXED.equals(columnGroup.getStrategy()); } protected void initIntervalTypeSelector() { view.clearIntervalTypeSelector(); DateIntervalType current = DateIntervalType.getByName(columnGroup.getIntervalSize()); List entries = getListOfIntervalTypes(); for (int i = 0; i < entries.size(); i++) { DateIntervalType entry = entries.get(i); view.addIntervalTypeItem(entry); if (current != null && current.equals(entry)) { view.setSelectedIntervalTypeIndex(i); } } } public List getListOfIntervalTypes() { if (isFixedStrategy()) { return DateIntervalType.FIXED_INTERVALS_SUPPORTED; } return Arrays.asList(DateIntervalType.values()); } protected void initFirstDayListBox() { view.setFirstDayVisibility(true); view.clearFirstDaySelector(); DayOfWeek current = columnGroup.getFirstDayOfWeek(); DayOfWeek[] entries = DayOfWeek.values(); for (int i = 0; i < entries.length; i++) { DayOfWeek entry = entries[i]; view.addFirstDaySelectorItem(entry); if (current != null && current.equals(entry)) { view.setSelectedFirstDayIndex(i); } } } protected void initFirstMonthListBox() { view.setFirstMonthVisibility(true); view.clearFirstMonthSelector(); Month current = columnGroup.getFirstMonthOfYear(); Month[] entries = Month.values(); for (int i = 0; i < entries.length; i++) { Month entry = entries[i]; view.addFirstMonthSelectorItem(entry); if (current != null && current.equals(entry)) { view.setSelectedFirstMonthIndex(i); } } } protected void initMaxIntervalsTextBox() { view.setMaxIntervalsVisibility(true); view.setMaxIntervalsValue(Integer.toString(columnGroup.getMaxIntervals())); } protected void initEmptyIntervalsFlag() { view.setEmptyIntervalsValue(columnGroup.areEmptyIntervalsAllowed()); } protected void resetCommon() { view.setFixedModeValue(isFixedStrategy()); view.setMaxIntervalsVisibility(false); view.setFirstDayVisibility(false); view.setFirstMonthVisibility(false); initIntervalTypeSelector(); initEmptyIntervalsFlag(); } public void gotoDynamicMode() { resetCommon(); initMaxIntervalsTextBox(); } public void gotoFixedMode() { resetCommon(); DateIntervalType current = DateIntervalType.getByName(columnGroup.getIntervalSize()); if (DateIntervalType.DAY_OF_WEEK.equals(current)) { initFirstDayListBox(); } else if (DateIntervalType.MONTH.equals(current)) { initFirstMonthListBox(); } } public void onFixedStrategyChanged() { columnGroup.setFirstMonthOfYear(null); columnGroup.setFirstDayOfWeek(null); if (view.getFixedModeValue()) { // Reset current interval type selected if not allowed. DateIntervalType intervalType = DateIntervalType.getByIndex(view.getSelectedIntervalTypeIndex()); if (!DateIntervalType.FIXED_INTERVALS_SUPPORTED.contains(intervalType)) { view.setSelectedIntervalTypeIndex(DateIntervalType.MONTH.getIndex()); columnGroup.setIntervalSize(DateIntervalType.MONTH.name()); } columnGroup.setStrategy(GroupStrategy.FIXED); gotoFixedMode(); } else { columnGroup.setStrategy(GroupStrategy.DYNAMIC); gotoDynamicMode(); } changeEvent.fire(new DataSetGroupDateChanged(columnGroup)); } void onIntervalTypeSelected() { DateIntervalType intervalType = DateIntervalType.getByIndex(view.getSelectedIntervalTypeIndex()); if (isFixedStrategy()) { intervalType = DateIntervalType.FIXED_INTERVALS_SUPPORTED.get(view.getSelectedIntervalTypeIndex()); } columnGroup.setIntervalSize(intervalType.name()); columnGroup.setFirstMonthOfYear(null); columnGroup.setFirstDayOfWeek(null); view.setFirstMonthVisibility(false); view.setFirstDayVisibility(false); if (GroupStrategy.FIXED.equals(columnGroup.getStrategy())) { if (DateIntervalType.MONTH.equals(DateIntervalType.getByName(columnGroup.getIntervalSize()))) { view.setFirstMonthVisibility(true); initFirstMonthListBox(); } else if (DateIntervalType.DAY_OF_WEEK.equals(DateIntervalType.getByName(columnGroup.getIntervalSize()))) { view.setFirstDayVisibility(true); initFirstDayListBox(); } } changeEvent.fire(new DataSetGroupDateChanged(columnGroup)); } void onEmptyIntervalsChanged() { columnGroup.setEmptyIntervalsAllowed(view.getEmptyIntervalsValue()); changeEvent.fire(new DataSetGroupDateChanged(columnGroup)); } void onMaxIntervalsChanged() { try { columnGroup.setMaxIntervals(Integer.parseInt(view.getMaxIntervalsValue())); changeEvent.fire(new DataSetGroupDateChanged(columnGroup)); } catch (Exception e) { // Just ignore } } void onFirstDaySelected() { DayOfWeek dayOfWeek = DayOfWeek.getByIndex(view.getSelectedFirstDayIndex()+1); columnGroup.setFirstDayOfWeek(dayOfWeek); changeEvent.fire(new DataSetGroupDateChanged(columnGroup)); } void onFirstMonthSelected() { Month month = Month.getByIndex(view.getSelectedFirstMonthIndex()+1); columnGroup.setFirstMonthOfYear(month); changeEvent.fire(new DataSetGroupDateChanged(columnGroup)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/DataSetGroupDateEditorView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.client.resources.i18n.DateIntervalTypeConstants; import org.dashbuilder.dataset.client.resources.i18n.DayOfWeekConstants; import org.dashbuilder.dataset.client.resources.i18n.MonthConstants; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.group.DateIntervalType; import org.gwtbootstrap3.client.ui.CheckBox; import org.gwtbootstrap3.client.ui.ListBox; import org.gwtbootstrap3.client.ui.TextBox; @Dependent public class DataSetGroupDateEditorView extends Composite implements DataSetGroupDateEditor.View { interface Binder extends UiBinder {} private static Binder uiBinder = GWT.create(Binder.class); @UiField CheckBox fixedStrategyCheckBox; @UiField ListBox intervalTypeListBox; @UiField Panel maxIntervalsGroup; @UiField Panel firstDayPanel; @UiField Panel firstMonthPanel; @UiField TextBox maxIntervalsTextBox; @UiField CheckBox emptyIntervalsCheckBox; @UiField ListBox firstDayListBox; @UiField ListBox firstMonthListBox; DataSetGroupDateEditor presenter; @Override public void init(DataSetGroupDateEditor presenter) { this.presenter = presenter; initWidget(uiBinder.createAndBindUi(this)); } @Override public void setFixedModeValue(boolean enabled) { fixedStrategyCheckBox.setValue(enabled); } @Override public boolean getFixedModeValue() { return fixedStrategyCheckBox.getValue(); } @Override public void clearIntervalTypeSelector() { intervalTypeListBox.clear(); } @Override public void addIntervalTypeItem(DateIntervalType entry) { intervalTypeListBox.addItem(DateIntervalTypeConstants.INSTANCE.getString(entry.name())); } @Override public void setSelectedIntervalTypeIndex(int index) { intervalTypeListBox.setSelectedIndex(index); } @Override public int getSelectedIntervalTypeIndex() { return intervalTypeListBox.getSelectedIndex(); } @Override public void setFirstDayVisibility(boolean visible) { firstDayPanel.setVisible(visible); } @Override public void clearFirstDaySelector() { firstDayListBox.clear(); } @Override public void addFirstDaySelectorItem(DayOfWeek entry) { firstDayListBox.addItem(DayOfWeekConstants.INSTANCE.getString(entry.name())); } @Override public void setSelectedFirstDayIndex(int index) { firstDayListBox.setSelectedIndex(index); } @Override public int getSelectedFirstDayIndex() { return firstDayListBox.getSelectedIndex(); } @Override public void setFirstMonthVisibility(boolean visible) { firstMonthPanel.setVisible(visible); } @Override public void clearFirstMonthSelector() { firstMonthListBox.clear(); } @Override public void addFirstMonthSelectorItem(Month entry) { firstMonthListBox.addItem(MonthConstants.INSTANCE.getString(entry.name())); } @Override public void setSelectedFirstMonthIndex(int index) { firstMonthListBox.setSelectedIndex(index); } @Override public int getSelectedFirstMonthIndex() { return firstMonthListBox.getSelectedIndex(); } @Override public void setEmptyIntervalsValue(boolean enabled) { emptyIntervalsCheckBox.setValue(enabled); } @Override public boolean getEmptyIntervalsValue() { return emptyIntervalsCheckBox.getValue(); } @Override public void setMaxIntervalsVisibility(boolean visible) { maxIntervalsGroup.setVisible(visible); } @Override public void setMaxIntervalsValue(String max) { maxIntervalsTextBox.setText(max); } @Override public String getMaxIntervalsValue() { return maxIntervalsTextBox.getText(); } // UI events @UiHandler(value = "fixedStrategyCheckBox") public void onFixedModeSelected(ClickEvent clickEvent) { presenter.onFixedStrategyChanged(); } @UiHandler(value = "intervalTypeListBox") public void onIntervalTypeSelected(ChangeEvent changeEvent) { presenter.onIntervalTypeSelected(); } @UiHandler(value = "emptyIntervalsCheckBox") public void onEmptyIntervalsChanged(ClickEvent clickEvent) { presenter.onEmptyIntervalsChanged(); } @UiHandler(value = "maxIntervalsTextBox") public void onMaxIntervalsChanged(ChangeEvent changeEvent) { presenter.onMaxIntervalsChanged(); } @UiHandler(value = "firstDayListBox") public void onFirstDaySelected(ChangeEvent changeEvent) { presenter.onFirstDaySelected(); } @UiHandler(value = "firstMonthListBox") public void onFirstMonthSelected(ChangeEvent changeEvent) { presenter.onFirstMonthSelected(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/group/DataSetGroupDateEditorView.ui.xml ================================================ .labelFont { font-size: small; } .checkBox { margin-top: 0px; margin-bottom: 0px; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/DefaultHtmlValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import javax.enterprise.context.Dependent; import com.google.gwt.xml.client.XMLParser; @Dependent public class DefaultHtmlValidator implements HtmlValidator { public String validate(String code) { try { XMLParser.parse(code); return null; } catch (Exception e) { return e.getMessage(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/DefaultJsEvaluator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import javax.enterprise.context.Dependent; @Dependent public class DefaultJsEvaluator implements JsEvaluator { @Override public void evaluate(String js) throws Exception { _evalJs(js); } protected native void _evalJs(String js) /*-{ eval(js) + ''; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/DefaultJsValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import java.util.Collection; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.StringTemplateBuilder; import org.dashbuilder.displayer.client.resources.i18n.SourceCodeValidatorConstants; @Dependent public class DefaultJsValidator implements JsValidator { public static final String[] _jsMalicious = {"document.", "window.", "eval(", "eval ", "eval\t", "eval\n", ".innerHTML"}; protected JsEvaluator jsEvaluator; protected StringTemplateBuilder codeBuilder; protected StringTemplateBuilder restoreBuilder; Map _variables; @Inject public DefaultJsValidator(JsEvaluator jsEvaluator) { this.jsEvaluator = jsEvaluator; codeBuilder = new StringTemplateBuilder(); restoreBuilder = new StringTemplateBuilder("__", "__"); _variables = new HashMap<>(); } @Override public String validate(String jsTemplate, Collection allowedVariables) { // Ban some JS keywords that could lead to potential XSS attacks for (String keyword : _jsMalicious) { int idx = jsTemplate.toLowerCase().indexOf(keyword.toLowerCase()); if (idx >= 0) { int end = jsTemplate.indexOf("\n", idx); end = (end != -1 && end-idx < 30) ? end : idx + 30; String expr = jsTemplate.substring(idx, end >= jsTemplate.length() ? jsTemplate.length() : end); return SourceCodeValidatorConstants.INSTANCE.js_keyword_not_allowed(expr); } } try { // Ensure all the variables in the template match the allowed ones codeBuilder.setTemplate(jsTemplate); for (String key : codeBuilder.keys()) { String var = codeBuilder.asVar(key); if (allowedVariables != null && !allowedVariables.contains(var)) { return SourceCodeValidatorConstants.INSTANCE.js_variable_not_found(var); } } // Mock the variables in the template and evaluate the whole script String js = replaceVariables(jsTemplate); jsEvaluator.evaluate(js); // Evaluate each line individually js = isolateLines(js); jsEvaluator.evaluate(js); return null; } catch (Exception e) { // Replace back the original variables into the error message String error = e.getMessage(); return restoreVariables(error); } } public String replaceVariables(String code) { StringBuilder header = new StringBuilder(); header.append("function __alert(msg) {};\n"); codeBuilder.setTemplate(code.replace("alert", "__alert")); _variables.clear(); int idx = 0; for (String key : codeBuilder.keys()) { String var = "var" + idx++; _variables.put(var, key); header.append("var __" + var + "__ = document.createElement(\"div\");\n"); codeBuilder.replace(key, "__" + var + "__"); } String body = codeBuilder.build(); return header + body; } public String restoreVariables(String code) { restoreBuilder.setTemplate(code); for (String var : _variables.keySet()) { restoreBuilder.replace(var, codeBuilder.getKeyPrefix() + _variables.get(var) + codeBuilder.getKeySufix()); } return restoreBuilder.build(); } public String isolateLines(String code) { StringBuilder out = new StringBuilder(); String[] lines = code.split("\n"); for (String line : lines) { line = line.trim(); line = line.contains("else ") ? line.replace("else ", "") : line; if (line.startsWith("{") && !line.endsWith("}") && occurrences(line, "{") > occurrences(line, "}")) { line = line.substring(1); } if (!line.startsWith("{") && line.endsWith("}") && occurrences(line, "{") < occurrences(line, "}")) { line = line.substring(0, line.length()-1); } if (line.endsWith("{")) { line = line + "}"; } if (line.startsWith("}")) { line = "{" + line; } if (line.equals("") || line.equals("{}") || line.equals("{};")) { continue; } out.append(line).append("\n"); } return out.toString(); } public int occurrences(String str, String target) { int idx = 0; int count = 0; while (idx != -1 && idx < str.length()) { idx = str.indexOf(target, idx); if (idx != -1) { count++; idx += target.length(); } } return count; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/HasHtmlTemplate.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import java.util.Map; public interface HasHtmlTemplate { String getHtmlTemplate(); Map getHtmlVariableMap(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/HasJsTemplate.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import java.util.Map; public interface HasJsTemplate { String getJsTemplate(); Map getJsVariableMap(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/HtmlValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; public interface HtmlValidator { /** * Check if the the given HTML fragment has no syntax errors. * * @param html the HTML to validate * @return An error message in case an error exists, or null if everything is ok. */ String validate(String html); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/JsEvaluator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; public interface JsEvaluator { void evaluate(String js) throws Exception; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/JsValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import java.util.Collection; public interface JsValidator { /** * Check if the the given javascript fragment has no syntax errors. * * @param jsTemplate The javascript template to validate. * @param allowedVariables The only set of variables that can be referenced from the JS body * @return An error message in case an error exists, or null if everything is ok. */ String validate(String jsTemplate, Collection allowedVariables); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/SourceCodeEditor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; /** * Source code editor supporting the HTML and Javascript languages. * *

(Check out the {@link SourceCodeType} interface which contains the list of supported languages)

*/ @Dependent public class SourceCodeEditor implements IsWidget { public interface View extends UberView { void clearAll(); void edit(SourceCodeType type, String code); void declareVariable(String var, String description); void injectVariable(String var); void focus(); void error(String error); void clearError(); } View view; SourceCodeType type; String code; Command onSourceCodeChanged; HtmlValidator htmlValidator; JsValidator jsValidator; boolean hasErrors = false; Map varMap; @Inject public SourceCodeEditor(View view, HtmlValidator htmlValidator, JsValidator jsValidator) { this.view = view; this.htmlValidator = htmlValidator; this.jsValidator = jsValidator; view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public String getCode() { return code; } public boolean hasErrors() { return hasErrors; } public void init(SourceCodeType type, String code, Map varMap, Command onSourceCodeChanged) { this.type = type; this.code = code; this.varMap = varMap == null ? new HashMap<>() : varMap; this.hasErrors = false; this.onSourceCodeChanged = onSourceCodeChanged; view.clearAll(); view.edit(type, code); view.focus(); for (String var : varMap.keySet()) { view.declareVariable(var, varMap.get(var)); } String error = validateSourceCode(code); if (error != null) { hasErrors = true; view.error(error); } } public void focus() { view.focus(); } public String validateSourceCode(String newCode) { if (newCode != null && newCode.length() > 0) { switch (type) { case JAVASCRIPT: return jsValidator.validate(newCode, varMap.keySet()); case HTML: return htmlValidator.validate(newCode); } } return null; } public void onVariableSelected(String var) { view.injectVariable(var); view.focus(); } public boolean onSourceCodeChanged(String newCode) { String error = validateSourceCode(newCode); if (error != null) { hasErrors = true; view.error(error); view.focus(); return false; } else { code = newCode; hasErrors = false; view.clearError(); onSourceCodeChanged.execute(); return true; } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/SourceCodeEditorView.css ================================================ .sce-error { font-size: smaller; } .sce-variable-menu { height: 300px; overflow: auto; position: absolute; top: 5px; margin-right: 40px; } .sce-variable-button { position: absolute; top: 0px; right: 20px; z-index: 1; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/SourceCodeEditorView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/java/org/dashbuilder/displayer/client/widgets/sourcecode/SourceCodeEditorView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.SpanElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Composite; import org.dashbuilder.displayer.client.resources.i18n.SourceCodeEditorConstants; import org.jboss.errai.common.client.dom.Button; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.NodeList; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.widgets.common.client.ace.AceEditor; import org.uberfire.ext.widgets.common.client.ace.AceEditorMode; import org.uberfire.ext.widgets.common.client.ace.AceEditorTheme; @Dependent @Templated public class SourceCodeEditorView extends Composite implements SourceCodeEditor.View { SourceCodeEditor presenter; boolean eventsEnabled = true; @Inject @DataField Div mainDiv; @Inject @DataField AceEditor aceEditor; @Inject @DataField Span errorLabel; @Inject @DataField Button addVariableButton; @Inject @DataField UnorderedList variablesMenu; @Override public void init(SourceCodeEditor presenter) { this.presenter = presenter; aceEditor.startEditor(); aceEditor.setTheme(AceEditorTheme.CHROME); aceEditor.setReadOnly(false); aceEditor.addOnChangeHandler(this::onEditorChange); aceEditor.setAutocompleteEnabled(true); addVariableButton.setTitle(SourceCodeEditorConstants.INSTANCE.add_variable()); } protected void onEditorChange(JavaScriptObject obj) { if (eventsEnabled && !presenter.onSourceCodeChanged(aceEditor.getText())) { aceEditor.setFocus(); } } @Override public void clearAll() { clearError(); removeAllChildren(variablesMenu); aceEditor.setFocus(); } @Override public void edit(SourceCodeType type, String code) { switch (type) { case HTML: aceEditor.setMode(AceEditorMode.HTML); break; case JAVASCRIPT: aceEditor.setMode(AceEditorMode.JAVASCRIPT); break; } eventsEnabled = false; aceEditor.setText(code != null ? code : ""); aceEditor.setFocus(); eventsEnabled = true; } @Override public void focus() { aceEditor.setFocus(); } @Override public void error(String error) { mainDiv.setClassName("form-group has-error"); errorLabel.setInnerHTML(error); } @Override public void clearError() { mainDiv.setClassName("form-group"); errorLabel.setInnerHTML(""); } @Override public void declareVariable(String var, String description) { SpanElement span = Document.get().createSpanElement(); span.setInnerText(var); AnchorElement anchor = Document.get().createAnchorElement(); anchor.setTitle(description); anchor.appendChild(span); LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); variablesMenu.appendChild((Node) li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if(Event.ONCLICK == event.getTypeInt()) { presenter.onVariableSelected(var); } }); } @Override public void injectVariable(String var) { aceEditor.insertAtCursor(var); } private void removeAllChildren(org.jboss.errai.common.client.dom.Element element) { NodeList nodeList = element.getChildNodes(); int lenght = nodeList.getLength(); for (int i=0; i ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/DisplayerClient.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ok=Ok cancel=Cancel error=Error: cause=Cause: # Position enum literals POSITION_BOTTOM=Bottom POSITION_TOP=Top POSITION_LEFT=Left POSITION_RIGHT=Right POSITION_IN=In # MapColorScheme enum literals COLOR_SCHEME_RED=Red COLOR_SCHEME_BLUE=Blue COLOR_SCHEME_GREEN=Green # Common settings editor literals dataset_editor_notfound=Data set not found common_dropdown_select=- Select - common_button_addnew=Add New settingsEditor_caption=Displayer Settings Editor settingsJsonSource_caption=Displayer Settings Json Source View common_group=General common_showTitle=Visible common_title=Title common_title_placeholder=Insert the chart''s title common_export=Export common_allowCSV=CSV common_allowExcel=Excel common_renderer=Renderer common_columns=Columns columns_name=Column columns_expression=Expression columns_pattern=Pattern columns_emptyvalue=Empty common_columns_placeholder=Insert the displayer''s columns, separated by commas chart_group=Chart chart_width=Width chart_height=Height chart_resizable=Automatic Resize chart_bgColor=Background color chart_marginGroup=Margins chart_topMargin=Top margin chart_bottomMargin=Bottom margin chart_leftMargin=Left margin chart_rightMargin=Right margin chart_legendGroup=Legend chart_legendShow=Visible chart_legendPosition=Position chart_3d=3D table_group=Table table_pageSize=Page size table_width=Width table_sortEnabled=Sort enabled table_sortColumn=Sort by default table_sortColumn_placeholder=Insert the default sort column id table_sortOrder=Sort order table_ascSortOrder=Ascending table_descSortOrder=Descending table_columnPicker=Column picker axis_group=Axis xaxis_showLabels=X axis labels visible xaxis_angle=X axis labels angle xaxis_title=X axis title xaxis_title_placeholder=Insert the X axis title yaxis_showLabels=Y axis label visible yaxis_angle=Y axis labels angle yaxis_title=Y axis title yaxis_title_placeholder=Insert the Y axis title meter_group=Meter meter_start=Start meter_warning=Warning level meter_critical=Critical level meter_end=End map_group=Map color_scheme=Color Scheme refresh_group=Refresh refresh_interval=Refresh (seconds) refresh_stale_data=Refresh stale data # Filter filter_group=Filter filter_enabled=Enabled filter_self=Self apply filter_listening=Listen to others filter_notifications=Notify others selector_group=Selector selector_width=Width selector_multiple=Multiple selector_show_inputs=Show inputs filter_editor_selectcolumn=- Select column - timeframe_from=From timeframe_to=To timeframe_first_month_year=First month of year case_sensitive=Case sensitive like_to_pattern_instructions=''%'' means zero or more characters while ''_'' means a single character multiple_input_descriptions=Multiple values are supported. Either ''|'' or '','' can be used as a separator dataset_groupdate_fixed_intervals=Fixed intervals dataset_groupdate_empty_intervals=Empty intervals dataset_groupdate_interval_type=Interval type dataset_groupdate_max_intervals=Max. intervals dataset_groupdate_firstday=First Day dataset_groupdate_firstmonth=First Month settings_validation_integer=Value must be an integer number. settings_validation_double=Value must be a double. settings_validation_meter_unknown=Unknown settings_validation_meter_higher=Must be higher than the {0} value. settings_validation_meter_lower=Must be lower than the {0} value. settings_validation_meter_invalid=Invalid value # DataSetLookup literals dataset_dataset=Data Set dataset_filters=Filters dataset_rows=Rows dataset_columns=Columns group_columnid_label=Column Id. dataset_lookup_group_columns_all=- No grouping - dataset_lookup_dataset_notfound=Data set {0} not found dataset_lookup_init_error=Initialization error # DisplayerEditor literals displayer_editor_title=Displayer Editor displayer_editor_new=New Displayer displayer_editor_dataset_notfound=Selected data set not found. displayer_editor_datasetmetadata_fetcherror=Error fetching the data set metadata. displayer_editor_dataset_nolookuprequest=It is not possible to create a data lookup request for the selected data set. displayer_editor_incompatible_settings=Data settings are not compatible. The current settings will be lost. Continue? displayer_editor_tab_type=Type displayer_editor_tab_data=Data displayer_editor_tab_display=Display displayer_editor_view_as_table=View as table renderer_selector_title=Renderer selector displayerlocator_default_renderer_undeclared={0} displayer default renderer not declared. displayerlocator_unsupported_displayer_renderer={0} displayer not supported in the {1} renderer. rendererliblocator_renderer_not_found={0} renderer not found. rendererliblocator_multiple_renderers_found=Multiple renderer implementations found for: {0} renderermanager_renderer_not_available=No renderer is available for type: {0}. displayerviewer_displayer_not_created=It was not possible to create the displayer expand=Expand collapse=Collapse removeFilter=Remove filter DisplayerErrorWidget.displayerErrorTitle=Unexpected Error DisplayerErrorWidget.errorDetails=Details ExternalComponentView.configurationIssueTitle=Modify Configuration ExternalComponentView.configurationIssueDescription=Component does not support the current configuration. loadingComponent=Loading Component componentEditor=Component Editor componentNotFound=Component Not Found noPropertiesComponent=This component has no properties. componentConfigDefaultMessage=Read the component configuration to find which columns it supports. mandatoryHelpHeader=Mandatory mandatoryHelpText=This field is mandatory. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants_de.properties ================================================ ok=Ok cancel=Abbrechen error=Fehler\: cause=Ursache\: POSITION_BOTTOM=Unten POSITION_TOP=Oben POSITION_LEFT=Links POSITION_RIGHT=Rechts POSITION_IN=In dataset_editor_notfound=Datensatz nicht gefunden common_dropdown_select=- Auswählen - common_button_addnew=Neu hinzufügen settingsEditor_caption=Displayer-Einstellungen-Editor. settingsJsonSource_caption=Displayer-Einstellungen Json-Quellen-Anzeige common_group=Allgemein common_showTitle=Sichtbar common_title=Titel common_title_placeholder=Diagrammtitel einfügen common_renderer=Renderer common_columns=Spalten columns_name=Spalte columns_expression=Ausdruck columns_pattern=Muster columns_emptyvalue=Leer common_columns_placeholder=Displayer-Spalten einfügen, getrennt durch Kommas chart_group=Diagramm chart_width=Breite chart_height=Höhe chart_bgColor=Hintergrundfarbe chart_marginGroup=Ränder chart_topMargin=Oberer Rand chart_bottomMargin=Unterer Rand chart_leftMargin=Linker Rand chart_rightMargin=Rechter Rand chart_legendGroup=Legende chart_legendShow=Sichtbar chart_legendPosition=Position chart_3d=3D table_group=Tabelle table_pageSize=Seitengröße table_width=Breite table_sortEnabled=Sortierung aktiviert table_sortColumn=Standardsortierung table_sortColumn_placeholder=Standardsortierung-Spalten-ID einfügen table_sortOrder=Sortierreihenfolge table_ascSortOrder=Aufsteigend table_descSortOrder=Absteigend axis_group=Achse xaxis_showLabels=X-Achsenbezeichnungen sichtbar xaxis_angle=X-Achsenbezeichnungen Winkel xaxis_title=X-Achsen-Titel xaxis_title_placeholder=X-Achsen-Titel einfügen yaxis_showLabels=Y-Achsenbezeichnung sichtbar yaxis_angle=Y-Achsenbezeichnungen Winkel yaxis_title=Y-Achsen-Titel yaxis_title_placeholder=Y-Achsen-Titel einfügen meter_group=Meter meter_start=Start meter_warning=Warnebene meter_critical=Kritische Ebene meter_end=Ende refresh_group=Aktualisieren refresh_interval=Aktualisieren (Sekunden) refresh_stale_data=Veraltete Daten aktualisieren filter_group=Filter filter_enabled=Aktiviert filter_self=Selbst anwenden filter_listening=Auf andere horchen filter_notifications=Andere benachrichtigen filter_editor_selectcolumn=- Spalte auswählen - timeframe_from=Von timeframe_to=Bis timeframe_first_month_year=Erster Monat des Jahres case_sensitive=Groß- und Kleinschreibung beachten\: like_to_pattern_instructions=''%'' bedeutet Null oder mehr Zeichen, ''_'' hingegen bedeutet ein einzelnes Zeichen multiple_input_descriptions=Mehrere Werte werden unterstützt. Entweder ''|'' oder '','' kann als Trennzeichen verwendet werden dataset_groupdate_fixed_intervals=Feste Intervalle dataset_groupdate_empty_intervals=Leere Intervalle dataset_groupdate_interval_type=Intervalltyp dataset_groupdate_max_intervals=Max. Intervalle dataset_groupdate_firstday=Erster Tag dataset_groupdate_firstmonth=Erster Monat settings_validation_integer=Wert muss eine ganze Zahl sein. settings_validation_double=Wert muss doppelt sein settings_validation_meter_unknown=Unbekannt settings_validation_meter_higher=Muss höher als der {0} Wert sein. settings_validation_meter_lower=Muss niedriger als der {0} Wert sein. settings_validation_meter_invalid=Ungültiger Wert dataset_dataset=Datensatz dataset_filters=Filter dataset_rows=Reihen dataset_columns=Spalten group_columnid_label=Spalten-ID. dataset_lookup_dataset_notfound=Datensatz {0} nicht gefunden dataset_lookup_init_error=Initialisierungsfehler displayer_editor_title=Displayer-Editor displayer_editor_new=Neuer Displayer displayer_editor_dataset_notfound=Ausgewählter Datensatz nicht gefunden. displayer_editor_datasetmetadata_fetcherror=Fehler beim Abruf von Datensatz-Metadaten. displayer_editor_dataset_nolookuprequest=Es ist nicht möglich, eine Daten-Lookup-Anfrage für den ausgewählten Datensatz zu erstellen. displayer_editor_incompatible_settings=Dateneinstellungen sind nicht kompatibel. Die aktuellen Einstellungen gehen verloren. Fortfahren? displayer_editor_tab_type=Typ displayer_editor_tab_data=Daten displayer_editor_tab_display=Anzeige displayer_editor_view_as_table=Als Tabelle anzeigen renderer_selector_title=Renderer-Selektor displayerlocator_default_renderer_undeclared={0} Displayer-Standardrenderer nicht deklariert. displayerlocator_unsupported_displayer_renderer={0} Displayer im {1} Renderer nicht unterstützt. rendererliblocator_renderer_not_found={0} Renderer nicht gefunden. rendererliblocator_multiple_renderers_found=Mehrere Renderer-Implementierungen gefunden für\: {0} # translation auto-copied from project KIE Workbench - Common, version 6.0.0, document org.kie.workbench.widgets/kie-wb-common-ui/org/kie/workbench/common/widgets/client/resources/i18n/CollapseExpandConstants, author jdimanos collapse=Reduzieren ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ok=Aceptar cancel=Cancelar error=Error: cause=Motivo: # Position enum literals POSITION_BOTTOM=Inferior POSITION_TOP=Superior POSITION_LEFT=Izquierda POSITION_RIGHT=Derecha POSITION_IN=En # MapColorScheme enum literals COLOR_SCHEME_RED=Rojo COLOR_SCHEME_BLUE=Azul COLOR_SCHEME_GREEN=Verde # Common settings editor literals dataset_editor_notfound=No se encuentra el conjunto de datos common_dropdown_select=- Seleccionar - common_button_addnew=Agregar nuevo settingsEditor_caption=Editor de ajustes de visualizador settingsJsonSource_caption=Vista de fuente Json de ajustes de visualizador common_group=General common_showTitle=Visible common_title=Título common_title_placeholder=Insertar el título del gráfico common_export=Exportar common_allowCSV=CSV common_allowExcel=Excel common_renderer=Renderizador common_columns=Columnas columns_name=Columna columns_expression=Expresión columns_pattern=Patrón columns_emptyvalue=Vacío common_columns_placeholder=Insertar las columnas del visualizador, separadas por comas chart_group=Gráfico chart_width=Ancho chart_height=Altura chart_resizable=Redimensionamiento automático chart_bgColor=Color de fondo chart_marginGroup=Márgenes chart_topMargin=Margen superior chart_bottomMargin=Margen inferior chart_leftMargin=Margen izquierdo chart_rightMargin=Margen derecho chart_legendGroup=Leyenda chart_legendShow=Visible chart_legendPosition=Posición chart_3d=3D table_group=Tabla table_pageSize=Tamaño de la página table_width=Ancho table_sortEnabled=Clasificación habilitada table_sortColumn=Valor predeterminado de clasificación table_sortColumn_placeholder=Insertar la ID de columna de clasificación predeterminada table_sortOrder=Orden de clasificación table_ascSortOrder=Ascendente table_descSortOrder=Descendente table_columnPicker=Selector de columna axis_group=Eje xaxis_showLabels=Visibilidad de etiquetas del eje X xaxis_angle=Ángulo de etiquetas del eje X xaxis_title=Título del eje X xaxis_title_placeholder=Insertar el título del eje X yaxis_showLabels=Visibilidad de etiquetas del eje Y yaxis_angle=Ángulo de etiquetas del eje Y yaxis_title=Título del eje Y yaxis_title_placeholder=Insertar el título del eje Y meter_group=Medidor meter_start=Inicio meter_warning=Nivel de advertencia meter_critical=Nivel crítico meter_end=Fin map_group=Mapa color_scheme=Esquema de colores refresh_group=Actualizar refresh_interval=Actualizar (segundos) refresh_stale_data=Actualizar datos obsoletos # Filter filter_group=Filtro filter_enabled=Habilitado filter_self=Se aplica solo filter_listening=Escuchar a otros filter_notifications=Notificar a otros selector_group=Selector selector_width=Ancho selector_multiple=Múltiple selector_show_inputs=Mostrar entradas filter_editor_selectcolumn=- Seleccionar columna - timeframe_from=Desde timeframe_to=Hasta timeframe_first_month_year=El primer mes del año case_sensitive=Distingue entre mayúsculas y minúsculas like_to_pattern_instructions=''%'' significa cero o más caracteres mientras que ''_'' significa un solo carácter multiple_input_descriptions=Se admiten múltiples valores. Se puede usar “|” o “,” como separador dataset_groupdate_fixed_intervals=Intervalos fijos dataset_groupdate_empty_intervals=Intervalos vacíos dataset_groupdate_interval_type=Tipo de intervalo dataset_groupdate_max_intervals=Intervalos máximos dataset_groupdate_firstday=Primer día dataset_groupdate_firstmonth=Primer mes settings_validation_integer=El valor debe ser un número entero. settings_validation_double=El valor debe ser el doble. settings_validation_meter_unknown=Desconocido settings_validation_meter_higher=Debe ser más alto que el valor {0}. settings_validation_meter_lower=Debe ser más bajo que el valor {0}. settings_validation_meter_invalid=Valor no válido # DataSetLookup literals dataset_dataset=Conjunto de datos dataset_filters=Filtros dataset_rows=Filas dataset_columns=Columnas group_columnid_label=ID de columna dataset_lookup_group_columns_all=- Sin agrupación - dataset_lookup_dataset_notfound=No se encuentra el conjunto de datos {0} dataset_lookup_init_error=Error de inicialización # DisplayerEditor literals displayer_editor_title=Editor de visualizador displayer_editor_new=Nuevo visualizador displayer_editor_dataset_notfound=No se encuentra el conjunto de datos seleccionado. displayer_editor_datasetmetadata_fetcherror=Error al extraer los metadatos del conjunto de datos. displayer_editor_dataset_nolookuprequest=No se puede crear una solicitud de búsqueda de datos para el conjunto de datos seleccionado. displayer_editor_incompatible_settings=Los ajustes de los datos no son compatibles. Se perderán los ajustes actuales. ¿Continuar? displayer_editor_tab_type=Tipo displayer_editor_tab_data=Datos displayer_editor_tab_display=Pantalla displayer_editor_view_as_table=Ver como tabla renderer_selector_title=Selector de renderizador displayerlocator_default_renderer_undeclared=No se declaró el renderizador predeterminado del visualizador {0}. displayerlocator_unsupported_displayer_renderer=El visualizador {0} no cuenta con soporte en el renderizador {1}. rendererliblocator_renderer_not_found=No se encuentra el renderizador {0}. rendererliblocator_multiple_renderers_found=Se encontraron múltiples implementaciones de renderizador para: {0} renderermanager_renderer_not_available=No hay renderizador disponible para el tipo: {0}. displayerviewer_displayer_not_created=No se pudo crear el visualizador expand=Ampliar collapse=Contraer removeFilter=Quitar filtro DisplayerErrorWidget.displayerErrorTitle=Se produjo un error inesperado: {0} DisplayerErrorWidget.errorDetails=Detalles ExternalComponentView.configurationIssueTitle=Configuración de fases ExternalComponentView.configurationIssueDescription=El componente no es compatible con la configuración actual. loadingComponent=Componente de carga componentEditor=Editor de componentes componentNotFound=Componente no encontrado noPropertiesComponent=Este componente no tiene propiedades. componentConfigDefaultMessage=Lea la configuración del componente para saber qué columnas admite. mandatoryHelpHeader=Campo obligatorio mandatoryHelpText=Este campo es obligatorio ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ok=OK cancel=Annuler error=Erreur : cause=Cause : # Position enum literals POSITION_BOTTOM=Bas POSITION_TOP=Haut POSITION_LEFT=Gauche POSITION_RIGHT=Droite POSITION_IN=Dans # MapColorScheme enum literals COLOR_SCHEME_RED=Rouge COLOR_SCHEME_BLUE=Bleu COLOR_SCHEME_GREEN=Vert # Common settings editor literals dataset_editor_notfound=Ensemble de données introuvable common_dropdown_select=- Sélectionner - common_button_addnew=Ajouter settingsEditor_caption=Éditeur de paramètres de l''afficheur settingsJsonSource_caption=Vue de source Json des paramètres de l''afficheur common_group=Général common_showTitle=Visible common_title=Titre common_title_placeholder=Insérer le titre du graphique common_export=Exporter common_allowCSV=CSV common_allowExcel=Excel common_renderer=Moteur de rendu common_columns=Colonnes columns_name=Colonne columns_expression=Expression columns_pattern=Modèle columns_emptyvalue=Vide common_columns_placeholder=Insérer les colonnes de l''afficheur, séparées par des virgules chart_group=Graphique chart_width=Largeur chart_height=Hauteur chart_resizable=Redimensionnement automatique chart_bgColor=Couleur d''arrière-plan chart_marginGroup=Marges chart_topMargin=Marge supérieure chart_bottomMargin=Marge inférieure chart_leftMargin=Marge gauche chart_rightMargin=Marge droite chart_legendGroup=Légende chart_legendShow=Visible chart_legendPosition=Position chart_3d=3D table_group=Tableau table_pageSize=Taille de la page table_width=Largeur table_sortEnabled=Tri activé table_sortColumn=Tri par défaut table_sortColumn_placeholder=Insérer l''ID de la colonne de tri par défaut table_sortOrder=Ordre de tri table_ascSortOrder=Croissant table_descSortOrder=Décroissant table_columnPicker=Sélecteur de colonne axis_group=Axe xaxis_showLabels=Étiquettes de l''axe X visibles xaxis_angle=Angle des étiquettes de l''axe X xaxis_title=Titre de l''axe X xaxis_title_placeholder=Insérer le titre de l''axe X yaxis_showLabels=Étiquettes de l''axe Y visibles yaxis_angle=Angle des étiquettes de l''axe Y yaxis_title=Titre de l''axe Y yaxis_title_placeholder=Insérer le titre de l''axe Y meter_group=Compteur meter_start=Démarrer meter_warning=Niveau d''avertissement meter_critical=Niveau critique meter_end=Fin map_group=Carte color_scheme=Schéma de couleurs refresh_group=Rafraîchir refresh_interval=Rafraîchir (secondes) refresh_stale_data=Rafraîchir les données périmées # Filter filter_group=Filtrer filter_enabled=Activé filter_self=Applique automatiquement filter_listening=Écouter les autres filter_notifications=Informer les autres selector_group=Sélecteur selector_width=Largeur selector_multiple=Multiple selector_show_inputs=Afficher les entrées filter_editor_selectcolumn=- Sélectionner une colonne - timeframe_from=De timeframe_to=À timeframe_first_month_year=Premier mois de l''année case_sensitive=Respect de la casse like_to_pattern_instructions="%" signifie zéro ou plusieurs caractères, tandis que "_" signifie un seul caractère multiple_input_descriptions=Les valeurs multiples sont prises en charge. "|" ou "," peut être utilisé comme séparateur dataset_groupdate_fixed_intervals=Intervalles fixes dataset_groupdate_empty_intervals=Intervalles vides dataset_groupdate_interval_type=Type d''intervalle dataset_groupdate_max_intervals=Nombre max. d''intervalles dataset_groupdate_firstday=Premier jour dataset_groupdate_firstmonth=Premier mois settings_validation_integer=La valeur doit être un nombre entier. settings_validation_double=La valeur doit être un double. settings_validation_meter_unknown=Inconnu settings_validation_meter_higher=Doit être supérieur à la valeur {0}. settings_validation_meter_lower=Doit être inférieur à la valeur {0}. settings_validation_meter_invalid=Valeur incorrecte # DataSetLookup literals dataset_dataset=Ensemble de données dataset_filters=Filtres dataset_rows=Lignes dataset_columns=Colonnes group_columnid_label=ID de colonne dataset_lookup_group_columns_all=- Pas de regroupement - dataset_lookup_dataset_notfound=Ensemble de données {0} introuvable dataset_lookup_init_error=Erreur d''initialisation # DisplayerEditor literals displayer_editor_title=Éditeur de l''afficheur displayer_editor_new=Nouvel afficheur displayer_editor_dataset_notfound=Ensemble de données sélectionné introuvable. displayer_editor_datasetmetadata_fetcherror=Erreur lors de l''extraction des métadonnées de l''ensemble de données. displayer_editor_dataset_nolookuprequest=Il n''est pas possible de créer une demande de recherche de données pour l''ensemble de données sélectionné. displayer_editor_incompatible_settings=Les paramètres des données ne sont pas compatibles. Les paramètres actuels seront perdus. Continuer ? displayer_editor_tab_type=Type displayer_editor_tab_data=Données displayer_editor_tab_display=Afficher displayer_editor_view_as_table=Afficher sous la forme d''un tableau renderer_selector_title=Sélecteur de rendu displayerlocator_default_renderer_undeclared=Moteur de rendu par défaut de l''afficheur {0} non déclaré. displayerlocator_unsupported_displayer_renderer=Afficheur {0} non pris en charge dans le moteur de rendu {1}. rendererliblocator_renderer_not_found={0} Le moteur de rendu est introuvable. rendererliblocator_multiple_renderers_found=Plusieurs implémentations du moteur de rendu ont été trouvées pour : {0} renderermanager_renderer_not_available=Aucun moteur de rendu pour le type : {0}. displayerviewer_displayer_not_created=L''afficheur n''a pas pu être créé expand=Développer collapse=Réduire removeFilter=Supprimer le filtre DisplayerErrorWidget.displayerErrorTitle=Erreur inattendue DisplayerErrorWidget.errorDetails=Détails ExternalComponentView.configurationIssueTitle=Modifier la configuration ExternalComponentView.configurationIssueDescription=Le composant ne prend pas en charge la configuration actuelle. loadingComponent=Chargement du composant componentEditor=Éditeur du composant componentNotFound=Composant non trouvé noPropertiesComponent=Ce composant n''a pas de propriétés. componentConfigDefaultMessage=Lisez la configuration du composant pour savoir quelles colonnes il prend en charge. mandatoryHelpHeader=Obligatoire mandatoryHelpText=Ce champ est obligatoire. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ok=Ok cancel=Annulla error=Errore: cause=Causa: # Position enum literals POSITION_BOTTOM=Inferiore POSITION_TOP=Superiore POSITION_LEFT=Sinistra POSITION_RIGHT=Destra POSITION_IN=Interno # MapColorScheme enum literals COLOR_SCHEME_RED=Rosso COLOR_SCHEME_BLUE=Blu COLOR_SCHEME_GREEN=Verde # Common settings editor literals dataset_editor_notfound=Set di dati non trovato common_dropdown_select=- Seleziona - common_button_addnew=Aggiungi Nuovo settingsEditor_caption=Editor Impostazioni Displayer settingsJsonSource_caption=Visualizzazione Sorgente JSON Impostazioni Displayer common_group=Generale common_showTitle=Visibile common_title=Titolo common_title_placeholder=Inserisci il titolo del grafico common_export=Esporta common_allowCSV=CSV common_allowExcel=Excel common_renderer=Renderer common_columns=Colonne columns_name=Colonna columns_expression=Espressione columns_pattern=Pattern columns_emptyvalue=Vuoto common_columns_placeholder=Inserisci le colonne del displayer, separate da virgole chart_group=Grafico chart_width=Larghezza chart_height=Altezza chart_resizable=Ridimensionamento Automatico chart_bgColor=Colore di sfondo chart_marginGroup=Margini chart_topMargin=Margine superiore chart_bottomMargin=Margine inferiore chart_leftMargin=Margine sinistro chart_rightMargin=Margine destro chart_legendGroup=Legenda chart_legendShow=Visibile chart_legendPosition=Posizione chart_3d=3D table_group=Tabella table_pageSize=Dimensione pagina table_width=Larghezza table_sortEnabled=Ordinamento abilitato table_sortColumn=Ordina per default table_sortColumn_placeholder=Inserisci l''ID della colonna di ordinamento predefinito table_sortOrder=Ordine di ordinamento table_ascSortOrder=Crescente table_descSortOrder=Decrescente table_columnPicker=Selettore di colonne axis_group=Asse xaxis_showLabels=Etichette asse X visibili xaxis_angle=Angolo etichette asse X xaxis_title=Titolo asse X xaxis_title_placeholder=Inserisci il titolo dell''asse X yaxis_showLabels=Etichette asse Y visibili yaxis_angle=Angolo etichette asse Y yaxis_title=Titolo asse Y yaxis_title_placeholder=Inserisci il titolo dell''asse Y meter_group=Misuratore meter_start=Inizio meter_warning=Livello di avviso meter_critical=Livello critico meter_end=Fine map_group=Mappa color_scheme=Schema di colori refresh_group=Aggiorna refresh_interval=Aggiorna (secondi) refresh_stale_data=Aggiorna dati obsoleti # Filter filter_group=Filtro filter_enabled=Abilitato filter_self=Applica a se stesso filter_listening=Ascolta altri filter_notifications=Notifica altri selector_group=Selettore selector_width=Larghezza selector_multiple=Multiplo selector_show_inputs=Mostra input filter_editor_selectcolumn=- Seleziona colonna - timeframe_from=Da timeframe_to=A timeframe_first_month_year=Primo mese dell''anno case_sensitive=Maiuscole/minuscole like_to_pattern_instructions=''%'' significa zero o più caratteri mentre ''_'' significa un singolo carattere multiple_input_descriptions=Sono supportati valori multipli. Può essere utilizzato ''|'' o '','' come separatore dataset_groupdate_fixed_intervals=Intervalli fissi dataset_groupdate_empty_intervals=Intervalli vuoti dataset_groupdate_interval_type=Tipo di intervallo dataset_groupdate_max_intervals=Max. intervalli dataset_groupdate_firstday=Primo giorno dataset_groupdate_firstmonth=Primo mese settings_validation_integer=Il valore deve essere un numero intero. settings_validation_double=Il valore deve essere un numero decimale. settings_validation_meter_unknown=Sconosciuto settings_validation_meter_higher=Deve essere superiore al valore {0}. settings_validation_meter_lower=Deve essere inferiore al valore {0}. settings_validation_meter_invalid=Valore non valido # DataSetLookup literals dataset_dataset=Set di dati dataset_filters=Filtri dataset_rows=Righe dataset_columns=Colonne group_columnid_label=ID Colonna. dataset_lookup_group_columns_all=- Nessun raggruppamento - dataset_lookup_dataset_notfound=Set di dati {0} non trovato dataset_lookup_init_error=Errore di inizializzazione # DisplayerEditor literals displayer_editor_title=Editor Displayer displayer_editor_new=Nuovo Displayer displayer_editor_dataset_notfound=Set di dati selezionato non trovato. displayer_editor_datasetmetadata_fetcherror=Errore durante il recupero dei metadati del set di dati. displayer_editor_dataset_nolookuprequest=Non è possibile creare una richiesta di ricerca dati per il set di dati selezionato. displayer_editor_incompatible_settings=Le impostazioni dei dati non sono compatibili. Le impostazioni correnti verranno perse. Continuare? displayer_editor_tab_type=Tipo displayer_editor_tab_data=Dati displayer_editor_tab_display=Visualizzazione displayer_editor_view_as_table=Visualizza come tabella renderer_selector_title=Selettore Renderer displayerlocator_default_renderer_undeclared=Renderer predefinito per il displayer {0} non dichiarato. displayerlocator_unsupported_displayer_renderer=Displayer {0} non supportato nel renderer {1}. rendererliblocator_renderer_not_found=Renderer {0} non trovato. rendererliblocator_multiple_renderers_found=Trovate più implementazioni del renderer per: {0} renderermanager_renderer_not_available=Nessun renderer disponibile per il tipo: {0}. displayerviewer_displayer_not_created=Impossibile creare il displayer expand=Espandi collapse=Comprimi removeFilter=Rimuovi filtro DisplayerErrorWidget.displayerErrorTitle=Errore Imprevisto DisplayerErrorWidget.errorDetails=Dettagli ExternalComponentView.configurationIssueTitle=Modifica Configurazione ExternalComponentView.configurationIssueDescription=Il componente non supporta la configurazione corrente. loadingComponent=Caricamento Componente componentEditor=Editor Componente componentNotFound=Componente Non Trovato noPropertiesComponent=Questo componente non ha proprietà. componentConfigDefaultMessage=Leggere la configurazione del componente per trovare quali colonne supporta. mandatoryHelpHeader=Obbligatorio mandatoryHelpText=Questo campo è obbligatorio. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ok=OK cancel=キャンセル error=エラー: cause=原因: # Position enum literals POSITION_BOTTOM=下揃え POSITION_TOP=上揃え POSITION_LEFT=左揃え POSITION_RIGHT=右揃え POSITION_IN=In # MapColorScheme enum literals COLOR_SCHEME_RED=赤 COLOR_SCHEME_BLUE=青 COLOR_SCHEME_GREEN=緑 # Common settings editor literals dataset_editor_notfound=データセットが見つかりません common_dropdown_select=- 選択 - common_button_addnew=新規の追加 settingsEditor_caption=ディスプレイヤー設定エディター settingsJsonSource_caption=ディスプレイヤー設定 JSON ソースビュー common_group=全般 common_showTitle=可視 common_title=タイトル common_title_placeholder=チャートのタイトルの挿入 common_export=エクスポート common_allowCSV=CSV common_allowExcel=Excel common_renderer=レンダラー common_columns=カラム columns_name=カラム columns_expression=式 columns_pattern=パターン columns_emptyvalue=空 common_columns_placeholder=ディスプレイヤーの列をカンマで区切って挿入 chart_group=チャート chart_width=幅 chart_height=高さ chart_resizable=自動のサイズ変更 chart_bgColor=背景色 chart_marginGroup=余白 chart_topMargin=上余白 chart_bottomMargin=下余白 chart_leftMargin=左余白 chart_rightMargin=右余白 chart_legendGroup=凡例 chart_legendShow=可視 chart_legendPosition=ポジション chart_3d=3D table_group=テーブル table_pageSize=ページサイズ table_width=幅 table_sortEnabled=ソートが有効化 table_sortColumn=デフォルトでソート table_sortColumn_placeholder=デフォルトソート列 ID の挿入 table_sortOrder=ソート順序 table_ascSortOrder=昇順 table_descSortOrder=降順 table_columnPicker=列取得 axis_group=軸 xaxis_showLabels=X 軸ラベルを表示 xaxis_angle=X 軸ラベルの角度 xaxis_title=X 軸タイトル xaxis_title_placeholder=X 軸タイトルの挿入 yaxis_showLabels=Y 軸ラベルを表示 yaxis_angle=Y 軸ラベルの角度 yaxis_title=Y 軸タイトル yaxis_title_placeholder=Y 軸タイトルの挿入 meter_group=メーター meter_start=開始 meter_warning=警告レベル meter_critical=重大レベル meter_end=終了 map_group=マップ color_scheme=カラースキーム refresh_group=更新 refresh_interval=更新 (秒) refresh_stale_data=古いデータの更新 # Filter filter_group=フィルター filter_enabled=有効 filter_self=自己適用 filter_listening=他のコンポーネントをリッスン filter_notifications=他のコンポーネントに通知 selector_group=セレクター selector_width=幅 selector_multiple=複数 selector_show_inputs=入力を表示 filter_editor_selectcolumn=- 列の選択 - timeframe_from=から timeframe_to=終了 timeframe_first_month_year=年度開始月 case_sensitive=大文字と小文字を区別します like_to_pattern_instructions=''%'' は 0 以上の文字数で ''_'' は 1 文字になります multiple_input_descriptions=複数の値がサポートされています。セパレーターには、''|'' または '','' を使用できます。 dataset_groupdate_fixed_intervals=固定された間隔 dataset_groupdate_empty_intervals=空の間隔 dataset_groupdate_interval_type=間隔タイプ dataset_groupdate_max_intervals=最大間隔 dataset_groupdate_firstday=開始日 dataset_groupdate_firstmonth=開始月 settings_validation_integer=値は整数でなければなりません。 settings_validation_double=値は倍精度形式でなければなりません。 settings_validation_meter_unknown=不明 settings_validation_meter_higher={0} 値よりも大きい必要があります。 settings_validation_meter_lower={0} 値よりも小さい必要があります。 settings_validation_meter_invalid=無効値 # DataSetLookup literals dataset_dataset=データセット dataset_filters=フィルター dataset_rows=行 dataset_columns=カラム group_columnid_label=列 ID dataset_lookup_group_columns_all=グループ化無し dataset_lookup_dataset_notfound=データセット {0} が見つかりません dataset_lookup_init_error=初期化エラー # DisplayerEditor literals displayer_editor_title=ディスプレイヤーエディター displayer_editor_new=新規ディスプレイヤー displayer_editor_dataset_notfound=選択されたデータセットが見つかりません。 displayer_editor_datasetmetadata_fetcherror=データセットメタデータのフェッチ中にエラがー発生しました。 displayer_editor_dataset_nolookuprequest=選択されたデータセットに対してデータルックアップ要求を作成できません。 displayer_editor_incompatible_settings=データ設定には互換性がありません。現在の設定は失われます。続行しますか? displayer_editor_tab_type=タイプ displayer_editor_tab_data=データ displayer_editor_tab_display=表示 displayer_editor_view_as_table=テーブルとして表示 renderer_selector_title=レンダラーセレクター displayerlocator_default_renderer_undeclared={0} ディスプレイヤーのデフォルトレンダラーが宣言されていません。 displayerlocator_unsupported_displayer_renderer={0} ディスプレイヤーは {1} レンダラーでサポートされていません。 rendererliblocator_renderer_not_found={0} レンダラーが見つかりません。 rendererliblocator_multiple_renderers_found=複数のレンダラー実装が見つかりました: {0} renderermanager_renderer_not_available=タイプ: {0} で利用可能なレンダラーがありません。 displayerviewer_displayer_not_created=ディスプレイヤーを作成できませんでした。 expand=展開 collapse=折りたたむ removeFilter=フィルターの削除 DisplayerErrorWidget.displayerErrorTitle=予期しないエラー DisplayerErrorWidget.errorDetails=詳細 ExternalComponentView.configurationIssueTitle=設定の変更 ExternalComponentView.configurationIssueDescription=コンポーネントは現在の設定をサポートしていません。 loadingComponent=コンポーネントのロード componentEditor=コンポーネントエディター componentNotFound=コンポーネントが見つかりません noPropertiesComponent=このコンポーネントにはプロパティーがありません。 componentConfigDefaultMessage=コンポーネント設定を読んで、サポートする列を見つけてください。 mandatoryHelpHeader=必須 mandatoryHelpText=このフィールドは必須です。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants_pt_BR.properties ================================================ ok=Ok cancel=Cancelar error=Erro cause=Causa POSITION_BOTTOM=Inferior POSITION_TOP=Superior POSITION_LEFT=Esquerda POSITION_RIGHT=Direita POSITION_IN=em dataset_editor_notfound=Definição de Data não foi encontrada common_dropdown_select=- Selecionar - common_button_addnew=Adicionar Novo settingsEditor_caption=Editor de Configurações de Exibição settingsJsonSource_caption=Visualização da Fonte Json Configurações de Exibidor common_group=Geral common_showTitle=Visível common_title=Título common_title_placeholder=Ensira o títolo do gráfico common_renderer=Renderizador common_columns=Colunas columns_name=Coluna columns_expression=Expressão columns_pattern=Modelo columns_emptyvalue=Vazio common_columns_placeholder=Ensira as colunas do exibidor, separado por vírgulas chart_group=Gráfico chart_width=Largura chart_height=Altura chart_bgColor=Cor de fundo chart_marginGroup=Margens chart_topMargin=Margem Superior chart_bottomMargin=Margem Inferior chart_leftMargin=Margem esquerda chart_rightMargin=Margem Direita chart_legendGroup=Legenda chart_legendShow=Visível chart_legendPosition=Posição chart_3d=3D table_group=Tabela table_pageSize=Tamanho da Página table_width=Largura table_sortEnabled=Organizar pos habilitados table_sortColumn=Organizar por default table_sortColumn_placeholder=Inserir o id da coluna de organizar default table_sortOrder=Organizar por ordem table_ascSortOrder=Ascendente table_descSortOrder=Descendente axis_group=Axis xaxis_showLabels=rótulos X axis visíveis xaxis_angle=ângulo dos rótulos X axis xaxis_title=título do X axis xaxis_title_placeholder=Inserir título do X axis yaxis_showLabels=rótulos Y axis visíveis yaxis_angle=ângulo dos rótulos Y axis yaxis_title=título do Y axis yaxis_title_placeholder=Inserir título do Y axis meter_group=Metro meter_start=Iniciar meter_warning=Nível do Aviso meter_critical=Nível Crítico meter_end=Fim refresh_group=Atualizar refresh_interval=Atualizar (segundos) refresh_stale_data=Atualizar dados interrompidos filter_group=Flitro filter_enabled=Ativado filter_self=Auto Aplicar filter_listening=Ouvir Outros filter_notifications=Notificar Outros filter_editor_selectcolumn=- Selecionar Coluna - timeframe_from=A partir de timeframe_to=Até timeframe_first_month_year=Primeiro mês do ano case_sensitive=Diferencia letras maiúsculas de minúsculas like_to_pattern_instructions=''%'' significa zero ou mais caracteres enquanto ''_'' significa um único caractere multiple_input_descriptions=Múltiplos valores possuem suporte. Tanto ''|'' como '','' podem ser usados como um separador dataset_groupdate_fixed_intervals=Intervalos fixos dataset_groupdate_empty_intervals=Intervalos Vazios dataset_groupdate_interval_type=Tipo de Intervalo dataset_groupdate_max_intervals=Max. de intervalos dataset_groupdate_firstday=Primeiro Dia dataset_groupdate_firstmonth=Primeiro Mês settings_validation_integer=Valor deve ser um número inteiro settings_validation_double=Valor deve ser um dobro. settings_validation_meter_unknown=Desconhecido settings_validation_meter_higher=Deve ser maior do que o valor {0} settings_validation_meter_lower=Deve ser menor do que o valor {0} settings_validation_meter_invalid=Valor inválido dataset_dataset=Data Set dataset_filters=Filtros dataset_rows=Linhas dataset_columns=Colunas group_columnid_label=Id de Coluna dataset_lookup_dataset_notfound=Data set {0} não foi encontrado dataset_lookup_init_error=Erro de inicialização displayer_editor_title=Editor de exibição displayer_editor_new=Novo Exibidor displayer_editor_dataset_notfound=Data set selecionados não foram encontrados. displayer_editor_datasetmetadata_fetcherror=Erro ao buscar o metadado do data set. displayer_editor_dataset_nolookuprequest=Não é possível criar uma requisição de procura de dados para data set selecionado. displayer_editor_incompatible_settings=Configurações de dados não são compatíveis. As configurações atuais serão perdidas. Você deseja continuar? displayer_editor_tab_type=Tipo displayer_editor_tab_data=Dados displayer_editor_tab_display=Display displayer_editor_view_as_table=Vsualizar como Tabela renderer_selector_title=Selecionador de renderizador displayerlocator_default_renderer_undeclared={0} renderizador default do exibidor não foi declarado. displayerlocator_unsupported_displayer_renderer={0} exibidor não é suportado no renderizador {1}. rendererliblocator_renderer_not_found={0} renderizador não foi encontrado. rendererliblocator_multiple_renderers_found=Implementações de renderizadores múltiplos encontrados para\: {0} # translation auto-copied from project KIE Workbench - Common, version 6.0.0, document org.kie.workbench.widgets/kie-wb-common-ui/org/kie/workbench/common/widgets/client/resources/i18n/CollapseExpandConstants, author ldelima@redhat.com collapse=Recolher ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/CommonConstants_zh_CN.properties ================================================ ok=确认 cancel=取消 error=错误: cause=原因: POSITION_BOTTOM=底部 POSITION_TOP=顶部 POSITION_LEFT=左 POSITION_RIGHT=右 POSITION_IN=里面 dataset_editor_notfound=未找到数据集。 common_dropdown_select=- 选择 - common_button_addnew=添加新显示屏 settingsEditor_caption=显示屏设置编辑器 settingsJsonSource_caption=显示屏设置的 JSON 源视图 common_group=普通 common_showTitle=可见的 common_title=标题 common_title_placeholder=插入图表的标题 common_renderer=渲染器 common_columns=列 columns_name=列 columns_expression=表达式 columns_pattern=模式 columns_emptyvalue=空的 common_columns_placeholder=插入显示屏的列,有逗号隔开。 chart_group=图表 chart_width=宽 chart_height=高 chart_bgColor=背景色 chart_marginGroup=边距 chart_topMargin=顶边距 chart_bottomMargin=底边距 chart_leftMargin=左边距 chart_rightMargin=右边距 chart_legendGroup=图例 chart_legendShow=可见的 chart_legendPosition=位置 chart_3d=3D table_group=表 table_pageSize=页面大小 table_width=宽 table_sortEnabled=启用排序 table_sortColumn=默认排序 table_sortColumn_placeholder=插入默认的排序列 ID table_sortOrder=排列顺序 table_ascSortOrder=升序排列 table_descSortOrder=降序排列 axis_group=轴 xaxis_showLabels=X 轴标签可见 xaxis_angle=X 轴标签角度 xaxis_title=X 轴标题 xaxis_title_placeholder=插入 X 轴标题 yaxis_showLabels=Y 轴标签可见 yaxis_angle=Y 轴标签角度 yaxis_title=Y 轴标题 yaxis_title_placeholder=插入 Y 轴标题 meter_group=计量 meter_start=开始 meter_warning=警告级别 meter_critical=关键级别 meter_end=结束 refresh_group=刷新 refresh_interval=刷新(秒) refresh_stale_data=刷新过时数据 filter_group=过滤器 filter_enabled=已启用的 filter_self=自适用 filter_listening=侦听其他 filter_notifications=通知其他 filter_editor_selectcolumn=- 选择列 - timeframe_from=从 timeframe_to=到 timeframe_first_month_year=年度的第一个月 case_sensitive=区分大小 like_to_pattern_instructions=''%'' 代表 0 或多个字符,而 ''_'' 代表单一字符。 multiple_input_descriptions=不支持多个值。可使用 ''|'' 或者 '','' 作为分隔符。 dataset_groupdate_fixed_intervals=固定间隔 dataset_groupdate_empty_intervals=空间隔 dataset_groupdate_interval_type=间隔类型 dataset_groupdate_max_intervals=最大间隔 dataset_groupdate_firstday=第一天 dataset_groupdate_firstmonth=第一个月 settings_validation_integer=值必须为整数。 settings_validation_double=值必须为实数。 settings_validation_meter_unknown=未知的 settings_validation_meter_higher=必须大于 {0} 值。 settings_validation_meter_lower=必须小于 {0} 值。 settings_validation_meter_invalid=无效值 dataset_dataset=数据集 dataset_filters=过滤器 dataset_rows=行 dataset_columns=列 group_columnid_label=列 ID。 dataset_lookup_dataset_notfound=未找到数据集 {0} 。 dataset_lookup_init_error=初始化错误 displayer_editor_title=显示屏编辑器 displayer_editor_new=新建显示屏 displayer_editor_dataset_notfound=未找到所选的数据集。 displayer_editor_datasetmetadata_fetcherror=获取数据集元数据出错。 displayer_editor_dataset_nolookuprequest=为所选的数据集创建数据查找请求是不可能的。 displayer_editor_incompatible_settings=数据设置不兼容。当前的设置将会丢失。要继续吗? displayer_editor_tab_type=类型 displayer_editor_tab_data=数据 displayer_editor_tab_display=显示 displayer_editor_view_as_table=表视图 renderer_selector_title=渲染器选择器 displayerlocator_default_renderer_undeclared=没有声明 {0} 显示屏的默认渲染器。 displayerlocator_unsupported_displayer_renderer={1} 渲染器不支持 {0} 显示屏。 rendererliblocator_renderer_not_found=未找到 {0} 渲染器 rendererliblocator_multiple_renderers_found=找到了 {0} 的多个渲染器实现 # translation auto-copied from project KIE Workbench - Common, version 6.0.0, document org.kie.workbench.widgets/kie-wb-common-ui/org/kie/workbench/common/widgets/client/resources/i18n/CollapseExpandConstants, author xi.huang collapse=收缩 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # initializing=Initializing ... error=ERROR: error_settings_unset=DisplayerSettings property not set error_handler_unset=DataSetHandler property not set error_dataset_notfound=Data set not found displayer_keyword_not_allowed=Not allowed ( {0} ) displayer_expr_invalid_syntax=Invalid syntax ( {0} ) userDefinedVariableDescription=User defined HTML identifier (see the HTML template) valueRawVariableDescription=The value without applying any formatting valueStartVariableDescription=The start value setting (see the ''Display'' section) valueWarningVariableDescription=The warning value setting (see the ''Display'' section) valueCriticalVariableDescription=The critical value setting (see the ''Display'' section) valueEndVariableDescription=The end value setting (see the ''Display'' section) valueVariableDescription=The formatted value titleVariableDescription=The title setting (see the ''Display'' section) widthVariableDescription=The width setting (see the ''Display'' section) heightVariableDescription=The height setting (see the ''Display'' section) marginTopVariableDescription=The margin top setting (see the ''Display'' section) marginBottomVariableDescription=The margin bottom setting (see the ''Display'' section) marginRightVariableDescription=The margin right setting (see the ''Display'' section) marginLeftVariableDescription=The margin left setting (see the ''Display'' section) bgColorVariableDescription=The background color setting (see the ''Display'' section) isFilterEnabledVariableDescription=Returns true when both the displayer supports filtering and the filter setting is enabled (see the ''Display'' section) isFilterOnVariableDescription=Returns true when a filter is active isEmptyVariableDescription=Returns true when the underlying data set returns no data doFilterVariableDescription=Function to notify and force other displayers in the same page to update according the filters defined by this displayer (if any) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants_de.properties ================================================ initializing=Initialisiere... error=FEHLER\: error_settings_unset=DisplayerSettings-Eigenschaft nicht eingestellt. error_handler_unset=DataSetHandler-Eigenschaft nicht eingestellt. error_dataset_notfound=Datensatz nicht gefunden displayer_keyword_not_allowed=Nicht erlaubt ( {0} ) displayer_expr_invalid_syntax=Ungültige Syntax ( {0} ) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # initializing=Iniciando… error=ERROR: error_settings_unset=La propiedad DisplayerSettings no está establecida error_handler_unset=La propiedad DataSetHandler no está establecida error_dataset_notfound=No se encuentra el conjunto de datos displayer_keyword_not_allowed=No está permitido ( {0} ) displayer_expr_invalid_syntax=Sintaxis no válida ( {0} ) userDefinedVariableDescription=Identificador HTML definido por el usuario (consultar la plantilla HTML) valueRawVariableDescription=El valor sin aplicar ningún formato valueStartVariableDescription=El ajuste del valor inicial (consultar la sección “Pantalla”) valueWarningVariableDescription=El ajuste del valor de advertencia (consultar la sección “Pantalla”) valueCriticalVariableDescription=El ajuste del valor crítico (consultar la sección “Pantalla”) valueEndVariableDescription=El ajuste del valor final (consultar la sección “Pantalla”) valueVariableDescription=El valor con formato titleVariableDescription=El ajuste del título (consultar la sección “Pantalla”) widthVariableDescription=El ajuste del ancho (consultar la sección “Pantalla”) heightVariableDescription=El ajuste de la altura (consultar la sección “Pantalla”) marginTopVariableDescription=El ajuste de la parte superior (consultar la sección “Pantalla”) marginBottomVariableDescription=El ajuste de la parte inferior (consultar la sección “Pantalla”) marginRightVariableDescription=El ajuste del margen derecho (consultar la sección “Pantalla”) marginLeftVariableDescription=El ajuste del margen izquierdo (consultar la sección “Pantalla”) bgColorVariableDescription=El ajuste del color de fondo (consultar la sección “Pantalla”) isFilterEnabledVariableDescription=Indica verdadero cuando el visualizador admite el filtrado y el ajuste del filtro está habilitado (consultar la sección “Pantalla”) isFilterOnVariableDescription=Indica verdadero cuando un filtro está activo isEmptyVariableDescription=Indica verdadero cuando el conjunto de datos subyacente no devuelve datos doFilterVariableDescription=Función para notificar y forzar a otros visualizadores en la misma página a actualizar en función de los filtros definidos por este visualizador (si los hay) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # initializing=Initialisation… error=ERREUR : error_settings_unset=Propriété DisplayerSettings non définie error_handler_unset=Propriété DataSetHandler non définie error_dataset_notfound=Ensemble de données introuvable displayer_keyword_not_allowed=Non autorisé ( {0} ) displayer_expr_invalid_syntax=Syntaxe non valide ( {0} ) userDefinedVariableDescription=Identificateur HTML défini par l''utilisateur (voir le modèle HTML) valueRawVariableDescription=Valeur sans application de formatage valueStartVariableDescription=Définition de la valeur de début (voir la section ''Affichage'') valueWarningVariableDescription=Définition de la valeur d''avertissement (voir la section ''Affichage'') valueCriticalVariableDescription=Définition de la valeur critique (voir la section ''Affichage'') valueEndVariableDescription=Définition de la valeur de fin (voir la section ''Affichage'') valueVariableDescription=Valeur formatée titleVariableDescription=Paramètre de titre (voir la section ''Affichage'') widthVariableDescription=Paramètre de largeur (voir la section ''Affichage'') heightVariableDescription=Paramètre de hauteur (voir la section ''Affichage'') marginTopVariableDescription=Paramètre de marge supérieure (voir la section ''Affichage'') marginBottomVariableDescription=Paramètre de marge inférieure (voir la section ''Affichage'') marginRightVariableDescription=Paramètre de marge droite (voir la section ''Affichage'') marginLeftVariableDescription=Paramètre de marge de gauche (voir la section ''Affichage'') bgColorVariableDescription=Paramètre de couleur d''arrière-plan (voir la section ''Affichage'') isFilterEnabledVariableDescription=Renvoie la valeur ''vrai'' lorsque l''afficheur prend en charge le filtrage et que le paramètre de filtrage est activé (voir la section ''Affichage'') isFilterOnVariableDescription=Renvoie la valeur ''vrai'' lorsqu''un filtre est actif isEmptyVariableDescription=Renvoie la valeur ''vrai'' lorsque l''ensemble de données sous-jacent ne renvoie aucune donnée doFilterVariableDescription=Fonction permettant de notifier et de forcer les autres afficheurs de la même page à se mettre à jour en fonction des filtres définis par cet afficheur (le cas échéant) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # initializing=Inizializzazione ... error=ERRORE: error_settings_unset=Proprietà DisplayerSettings non impostata error_handler_unset=Proprietà DataSetHandler non impostata error_dataset_notfound=Set di dati non trovato displayer_keyword_not_allowed=Non consentito ( {0} ) displayer_expr_invalid_syntax=Sintassi non valida ( {0} ) userDefinedVariableDescription=Identificatore HTML definito dall''utente (vedi il template HTML) valueRawVariableDescription=Il valore senza applicare alcun formato valueStartVariableDescription=L''impostazione del valore iniziale (vedi la sezione ''Visualizzazione'') valueWarningVariableDescription=L''impostazione del valore di avviso (vedi la sezione ''Visualizzazione'') valueCriticalVariableDescription=L''impostazione del valore critico (vedi la sezione ''Visualizzazione'') valueEndVariableDescription=L''impostazione del valore finale (vedi la sezione ''Visualizzazione'') valueVariableDescription=Il valore formattato titleVariableDescription=L''impostazione del titolo (vedi la sezione ''Visualizzazione'') widthVariableDescription=L''impostazione della larghezza (vedi la sezione ''Visualizzazione'') heightVariableDescription=L''impostazione dell''altezza (vedi la sezione ''Visualizzazione'') marginTopVariableDescription=L''impostazione del margine superiore (vedi la sezione ''Visualizzazione'') marginBottomVariableDescription=L''impostazione del margine inferiore (vedi la sezione ''Visualizzazione'') marginRightVariableDescription=L''impostazione del margine destro (vedi la sezione ''Visualizzazione'') marginLeftVariableDescription=L''impostazione del margine sinistro (vedi la sezione ''Visualizzazione'') bgColorVariableDescription=L''impostazione del colore di sfondo (vedi la sezione ''Visualizzazione'') isFilterEnabledVariableDescription=Restituisce true quando sia il displayer supporta il filtraggio che l''impostazione del filtro è abilitata (vedi la sezione ''Visualizzazione'') isFilterOnVariableDescription=Restituisce true quando è attivo un filtro isEmptyVariableDescription=Restituisce true quando il set di dati sottostante non restituisce dati doFilterVariableDescription=Funzione per notificare e forzare altri displayers nella stessa pagina ad aggiornarsi in base ai filtri definiti da questo displayer (se presenti) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # initializing=初期化中 ... error=エラー: error_settings_unset=DisplayerSettings プロパティーが設定されていません error_handler_unset=DataSetHandler プロパティーが設定されていません error_dataset_notfound=データセットが見つかりません displayer_keyword_not_allowed=使用できません ( {0} ) displayer_expr_invalid_syntax=無効な構文 ( {0} ) userDefinedVariableDescription=ユーザ定義のHTML識別子(HTMLテンプレート参照) valueRawVariableDescription=フォーマットを適用しない値 valueStartVariableDescription=開始値設定(”ディスプレイ"の項 を参照) valueWarningVariableDescription=警告値設定(”ディスプレイ"の項を参照) valueCriticalVariableDescription=重大値設定(”ディスプレイ"の項を参照) valueEndVariableDescription=終了値設定(”ディスプレイ"の項を参照) valueVariableDescription=フォーマットされた値 titleVariableDescription=タイトル設定(”ディスプレイ"の項を参照) widthVariableDescription=幅設定(”ディスプレイ"の項を参照) heightVariableDescription=高さ設定(”ディスプレイ"の項を参照) marginTopVariableDescription=上余白設定(”ディスプレイ"の項を参照) marginBottomVariableDescription=下余白設定(”ディスプレイ"の項を参照) marginRightVariableDescription=右余白設定(”ディスプレイ"の項を参照) marginLeftVariableDescription=左余白設定(”ディスプレイ"の項を参照) bgColorVariableDescription=背景色設定(”ディスプレイ"の項を参照) isFilterEnabledVariableDescription=ディスプレイヤーがフィルタリングとフィルタ設定の両方が有効化をサポートしている場合にtrueを返す (”ディスプレイ"の項を参照) isFilterOnVariableDescription=フィルターがアクティブな場合にtrueを返す isEmptyVariableDescription=基礎的データが何も返さないように設定されている場合はtrueを返す doFilterVariableDescription=このディスプレイヤーによって定義されたフィルター(もし設定されていれば)に従い同じページの別のディスプレイヤーに更新を通知及び強制する機能 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants_pt_BR.properties ================================================ initializing=Inicializando... error=ERRO\: error_settings_unset=Propriedade DisplayerSettings não definida error_handler_unset=Propriedade DataSetHandler não definida error_dataset_notfound=Conjunto de dados não encontrado displayer_keyword_not_allowed=( {0} ) não permitido(a) displayer_expr_invalid_syntax=( {0} ) sintaxe inválida ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerConstants_zh_CN.properties ================================================ initializing=正在初始化...... error=错误: error_settings_unset=没有设置 DisplayerSettings 属性 error_handler_unset=没有设置 DataSetHandler 属性 error_dataset_notfound=未找到数据集 displayer_keyword_not_allowed=不允许({0}) displayer_expr_invalid_syntax=无效语法({0}) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerHtmlConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_html_preview_link=Preview displayer_source_code_html=HTML displayer_source_code_javascript=Javascript ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerHtmlConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_html_preview_link=Vista previa displayer_source_code_html=HTML displayer_source_code_javascript=Javascript ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerHtmlConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_html_preview_link=Aperçu displayer_source_code_html=HTML displayer_source_code_javascript=JavaScript ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerHtmlConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_html_preview_link=プレビュー displayer_source_code_html=HTML displayer_source_code_javascript=Javascript ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_type_selector_tab_bar=Bar displayer_type_selector_tab_pie=Pie displayer_type_selector_tab_line=Line displayer_type_selector_tab_area=Area displayer_type_selector_tab_bubble=Bubble displayer_type_selector_tab_meter=Meter displayer_type_selector_tab_metric=Metric displayer_type_selector_tab_map=Map displayer_type_selector_tab_table=Table displayer_type_selector_tab_selector=Selector # Subtype enum literals DISPLAYER_SUBTYPE_LINE=Line DISPLAYER_SUBTYPE_SMOOTH=Smooth DISPLAYER_SUBTYPE_AREA=Area DISPLAYER_SUBTYPE_STACKED=Stacked DISPLAYER_SUBTYPE_STEPPED=Stepped DISPLAYER_SUBTYPE_BAR=Bar DISPLAYER_SUBTYPE_BAR_STACKED=Bar Stacked DISPLAYER_SUBTYPE_COLUMN=Column DISPLAYER_SUBTYPE_COLUMN_STACKED=Column Stacked DISPLAYER_SUBTYPE_HISTOGRAM=Histogram DISPLAYER_SUBTYPE_PIE=Pie DISPLAYER_SUBTYPE_PIE_3D=3D Pie DISPLAYER_SUBTYPE_DONUT=Donut DISPLAYER_SUBTYPE_MAP_REGIONS=Map (Regions) DISPLAYER_SUBTYPE_MAP_MARKERS=Map (Markers) DISPLAYER_SUBTYPE_METRIC_CARD=Metric Card DISPLAYER_SUBTYPE_METRIC_CARD2=Metric Card 2 DISPLAYER_SUBTYPE_METRIC_QUOTA=Metric Quota DISPLAYER_SUBTYPE_METRIC_PLAIN_TEXT=Metric Text DISPLAYER_SUBTYPE_SELECTOR_DROPDOWN=Drop Down DISPLAYER_SUBTYPE_SELECTOR_LABELS=Label Set DISPLAYER_SUBTYPE_SELECTOR_SLIDER=Slider # Subtype selector tooltips BARCHART_BAR_tt=Bar Chart BARCHART_BAR_STACKED_tt=Stacked Bar Chart BARCHART_COLUMN_tt=Column Chart BARCHART_COLUMN_STACKED_tt=Stacked Column Chart PIECHART_PIE_tt=Pie Chart PIECHART_PIE_3D_tt=3D Pie Chart PIECHART_DONUT_tt=Pie Chart (donut) AREACHART_AREA_tt=Area Chart AREACHART_AREA_STACKED_tt=Stacked Area Chart LINECHART_LINE_tt=Line Chart LINECHART_SMOOTH_tt=Smooth Line Chart MAP_MAP_REGIONS_tt=Map Chart (regions) MAP_MAP_MARKERS_tt=Map Chart (markers) BUBBLECHART_default_tt=Bubble Chart METERCHART_default_tt=Meter Chart METRIC_METRIC_CARD_tt=Metric Card METRIC_METRIC_CARD2_tt=Metric Card 2 METRIC_METRIC_QUOTA_tt=Metric Quota METRIC_METRIC_PLAIN_TEXT_tt=Metric Text TABLE_default_tt=Table EXTERNAL_COMPONENT_default_tt=External Component SELECTOR_SELECTOR_DROPDOWN_tt=Drop Down SELECTOR_SELECTOR_LABELS_tt=Label Set SELECTOR_SELECTOR_SLIDER_tt=Slider ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants_de.properties ================================================ displayer_type_selector_tab_bar=Balken displayer_type_selector_tab_pie=Kreis displayer_type_selector_tab_line=Linie displayer_type_selector_tab_area=Fläche displayer_type_selector_tab_bubble=Blase displayer_type_selector_tab_meter=Messung displayer_type_selector_tab_metric=Metrisch displayer_type_selector_tab_map=Karte displayer_type_selector_tab_table=Tabelle DISPLAYER_SUBTYPE_LINE=Linie DISPLAYER_SUBTYPE_SMOOTH=Geglättet DISPLAYER_SUBTYPE_AREA=Bereich DISPLAYER_SUBTYPE_STACKED=Gestapelt DISPLAYER_SUBTYPE_STEPPED=Abgestuft DISPLAYER_SUBTYPE_BAR=Balken DISPLAYER_SUBTYPE_BAR_STACKED=Balken-gestapelt DISPLAYER_SUBTYPE_COLUMN=Säule DISPLAYER_SUBTYPE_COLUMN_STACKED=Säulen-gestapelt DISPLAYER_SUBTYPE_HISTOGRAM=Histogram DISPLAYER_SUBTYPE_PIE=Kreis DISPLAYER_SUBTYPE_PIE_3D=3D Kreis DISPLAYER_SUBTYPE_DONUT=Ring DISPLAYER_SUBTYPE_MAP_REGIONS=Karte (Regionen) DISPLAYER_SUBTYPE_MAP_MARKERS=Karte (Marker) BARCHART_BAR_tt=Balkendiagramm BARCHART_BAR_STACKED_tt=Gestapeltes Balkendiagramm BARCHART_COLUMN_tt=Säulendiagramm BARCHART_COLUMN_STACKED_tt=Gestapeltes Säulendiagramm PIECHART_PIE_tt=Kreisdiagramm PIECHART_PIE_3D_tt=3D Kreisdiagramm PIECHART_DONUT_tt=Ringdiagramm AREACHART_AREA_tt=Flächendiagramm AREACHART_AREA_STACKED_tt=Gestapeltes Flächendiagramm LINECHART_LINE_tt=Liniendiagramm LINECHART_SMOOTH_tt=Geglättetes Liniendiagramm MAP_MAP_REGIONS_tt=Kartendiagramm (Regionen) MAP_MAP_MARKERS_tt=Kartendiagramm (Marker) BUBBLECHART_default_tt=Blasendiagramm METERCHART_default_tt=Meter-Diagramm TABLE_default_tt=Tabelle ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_type_selector_tab_bar=Barra displayer_type_selector_tab_pie=Circular displayer_type_selector_tab_line=Línea displayer_type_selector_tab_area=Área displayer_type_selector_tab_bubble=Burbuja displayer_type_selector_tab_meter=Medidor displayer_type_selector_tab_metric=Métrica displayer_type_selector_tab_map=Mapa displayer_type_selector_tab_table=Tabla displayer_type_selector_tab_selector=Selector # Subtype enum literals DISPLAYER_SUBTYPE_LINE=Línea DISPLAYER_SUBTYPE_SMOOTH=Suave DISPLAYER_SUBTYPE_AREA=Área DISPLAYER_SUBTYPE_STACKED=Apilado DISPLAYER_SUBTYPE_STEPPED=Escalonado DISPLAYER_SUBTYPE_BAR=Barra DISPLAYER_SUBTYPE_BAR_STACKED=Barra apilada DISPLAYER_SUBTYPE_COLUMN=Columna DISPLAYER_SUBTYPE_COLUMN_STACKED=Columna apilada DISPLAYER_SUBTYPE_HISTOGRAM=Histograma DISPLAYER_SUBTYPE_PIE=Circular DISPLAYER_SUBTYPE_PIE_3D=Circular 3D DISPLAYER_SUBTYPE_DONUT=Dona DISPLAYER_SUBTYPE_MAP_REGIONS=Mapa (Regiones) DISPLAYER_SUBTYPE_MAP_MARKERS=Mapa (Marcadores) DISPLAYER_SUBTYPE_METRIC_CARD=Tarjeta de métrica DISPLAYER_SUBTYPE_METRIC_CARD2=Tarjeta de métrica 2 DISPLAYER_SUBTYPE_METRIC_QUOTA=Cuota de métrica DISPLAYER_SUBTYPE_METRIC_PLAIN_TEXT=Texto de métrica DISPLAYER_SUBTYPE_SELECTOR_DROPDOWN=Desplegar DISPLAYER_SUBTYPE_SELECTOR_LABELS=Conjunto de etiquetas DISPLAYER_SUBTYPE_SELECTOR_SLIDER=Control deslizante # Subtype selector tooltips BARCHART_BAR_tt=Gráfico de barras BARCHART_BAR_STACKED_tt=Gráfico de barras apiladas BARCHART_COLUMN_tt=Gráfico de columnas BARCHART_COLUMN_STACKED_tt=Gráfico de columnas apiladas PIECHART_PIE_tt=Gráfico circular PIECHART_PIE_3D_tt=Gráfico circular 3D PIECHART_DONUT_tt=Gráfico circular (dona) AREACHART_AREA_tt=Gráfico de área AREACHART_AREA_STACKED_tt=Gráfico de área apilada LINECHART_LINE_tt=Gráfico de líneas LINECHART_SMOOTH_tt=Gráfico de líneas suaves MAP_MAP_REGIONS_tt=Cuadro de mapa (regiones) MAP_MAP_MARKERS_tt=Cuadro de mapa (marcadores) BUBBLECHART_default_tt=Gráfico de burbujas METERCHART_default_tt=Gráfico de medidor METRIC_METRIC_CARD_tt=Tarjeta de métrica METRIC_METRIC_CARD2_tt=Tarjeta de métrica 2 METRIC_METRIC_QUOTA_tt=Cuota de métrica METRIC_METRIC_PLAIN_TEXT_tt=Texto de métrica TABLE_default_tt=Tabla EXTERNAL_COMPONENT_default_tt=Componente externo SELECTOR_SELECTOR_DROPDOWN_tt=Desplegar SELECTOR_SELECTOR_LABELS_tt=Conjunto de etiquetas SELECTOR_SELECTOR_SLIDER_tt=Control deslizante ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_type_selector_tab_bar=Barres displayer_type_selector_tab_pie=Secteurs displayer_type_selector_tab_line=Ligne displayer_type_selector_tab_area=Aires displayer_type_selector_tab_bubble=Bulles displayer_type_selector_tab_meter=Compteur displayer_type_selector_tab_metric=Métrique displayer_type_selector_tab_map=Carte displayer_type_selector_tab_table=Tableau displayer_type_selector_tab_selector=Sélecteur # Subtype enum literals DISPLAYER_SUBTYPE_LINE=Ligne DISPLAYER_SUBTYPE_SMOOTH=Lisse DISPLAYER_SUBTYPE_AREA=Aires DISPLAYER_SUBTYPE_STACKED=Empilé DISPLAYER_SUBTYPE_STEPPED=Paliers DISPLAYER_SUBTYPE_BAR=Barres DISPLAYER_SUBTYPE_BAR_STACKED=Barres empilées DISPLAYER_SUBTYPE_COLUMN=Colonne DISPLAYER_SUBTYPE_COLUMN_STACKED=Colonnes empilées DISPLAYER_SUBTYPE_HISTOGRAM=Histogramme DISPLAYER_SUBTYPE_PIE=Secteurs DISPLAYER_SUBTYPE_PIE_3D=Secteurs 3D DISPLAYER_SUBTYPE_DONUT=Anneau DISPLAYER_SUBTYPE_MAP_REGIONS=Carte (régions) DISPLAYER_SUBTYPE_MAP_MARKERS=Carte (marqueurs) DISPLAYER_SUBTYPE_METRIC_CARD=Carte métrique DISPLAYER_SUBTYPE_METRIC_CARD2=Carte métrique 2 DISPLAYER_SUBTYPE_METRIC_QUOTA=Quota métrique DISPLAYER_SUBTYPE_METRIC_PLAIN_TEXT=Texte métrique DISPLAYER_SUBTYPE_SELECTOR_DROPDOWN=Liste déroulante DISPLAYER_SUBTYPE_SELECTOR_LABELS=Jeu d''étiquettes DISPLAYER_SUBTYPE_SELECTOR_SLIDER=Curseur # Subtype selector tooltips BARCHART_BAR_tt=Graphique à barres BARCHART_BAR_STACKED_tt=Graphique à barres empilées BARCHART_COLUMN_tt=Histogramme BARCHART_COLUMN_STACKED_tt=Histogramme empilé PIECHART_PIE_tt=Graphique en secteurs PIECHART_PIE_3D_tt=Graphique en secteurs 3D PIECHART_DONUT_tt=Graphique en secteurs (anneau) AREACHART_AREA_tt=Graphique en aires AREACHART_AREA_STACKED_tt=Graphique en aires empilées LINECHART_LINE_tt=Graphique en courbes LINECHART_SMOOTH_tt=Graphique en courbes lisses MAP_MAP_REGIONS_tt=Graphique de carte (régions) MAP_MAP_MARKERS_tt=Graphique de carte (marqueurs) BUBBLECHART_default_tt=Graphique en bulles METERCHART_default_tt=Graphique de mesure METRIC_METRIC_CARD_tt=Carte métrique METRIC_METRIC_CARD2_tt=Carte métrique 2 METRIC_METRIC_QUOTA_tt=Quota métrique METRIC_METRIC_PLAIN_TEXT_tt=Texte métrique TABLE_default_tt=Tableau EXTERNAL_COMPONENT_default_tt=Composant externe SELECTOR_SELECTOR_DROPDOWN_tt=Liste déroulante SELECTOR_SELECTOR_LABELS_tt=Jeu d''étiquettes SELECTOR_SELECTOR_SLIDER_tt=Curseur ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_type_selector_tab_bar=Barra displayer_type_selector_tab_pie=Torta displayer_type_selector_tab_line=Linea displayer_type_selector_tab_area=Area displayer_type_selector_tab_bubble=Bolla displayer_type_selector_tab_meter=Contatore displayer_type_selector_tab_metric=Metrica displayer_type_selector_tab_map=Mappa displayer_type_selector_tab_table=Tabella displayer_type_selector_tab_selector=Selettore # Subtype enum literals DISPLAYER_SUBTYPE_LINE=Linea DISPLAYER_SUBTYPE_SMOOTH=Linea Smussata DISPLAYER_SUBTYPE_AREA=Area DISPLAYER_SUBTYPE_STACKED=Sovrapposta DISPLAYER_SUBTYPE_STEPPED=A tratti DISPLAYER_SUBTYPE_BAR=Barra DISPLAYER_SUBTYPE_BAR_STACKED=Barra Sovrapposta DISPLAYER_SUBTYPE_COLUMN=Colonna DISPLAYER_SUBTYPE_COLUMN_STACKED=Colonna Sovrapposta DISPLAYER_SUBTYPE_HISTOGRAM=Istogramma DISPLAYER_SUBTYPE_PIE=Torta DISPLAYER_SUBTYPE_PIE_3D=Torta 3D DISPLAYER_SUBTYPE_DONUT=Ciambella DISPLAYER_SUBTYPE_MAP_REGIONS=Mappa (Regioni) DISPLAYER_SUBTYPE_MAP_MARKERS=Mappa (Marcatori) DISPLAYER_SUBTYPE_METRIC_CARD=Scheda Metrica DISPLAYER_SUBTYPE_METRIC_CARD2=Scheda Metrica 2 DISPLAYER_SUBTYPE_METRIC_QUOTA=Quota Metrica DISPLAYER_SUBTYPE_METRIC_PLAIN_TEXT=Testo Metrica DISPLAYER_SUBTYPE_SELECTOR_DROPDOWN=Menu a Tendina DISPLAYER_SUBTYPE_SELECTOR_LABELS=Set di Etichette DISPLAYER_SUBTYPE_SELECTOR_SLIDER=Slider # Subtype selector tooltips BARCHART_BAR_tt=Grafico a Barre BARCHART_BAR_STACKED_tt=Grafico a Barre Sovrapposte BARCHART_COLUMN_tt=Grafico a Colonne BARCHART_COLUMN_STACKED_tt=Grafico a Colonne Sovrapposte PIECHART_PIE_tt=Grafico a Torta PIECHART_PIE_3D_tt=Grafico a Torta 3D PIECHART_DONUT_tt=Grafico a Torta (ciambella) AREACHART_AREA_tt=Grafico ad Area AREACHART_AREA_STACKED_tt=Grafico ad Area Sovrapposta LINECHART_LINE_tt=Grafico a Linee LINECHART_SMOOTH_tt=Grafico a Linee Smussate MAP_MAP_REGIONS_tt=Grafico Mappa (Regioni) MAP_MAP_MARKERS_tt=Grafico Mappa (Marcatori) BUBBLECHART_default_tt=Grafico a Bolle METERCHART_default_tt=Grafico Contatore METRIC_METRIC_CARD_tt=Scheda Metrica METRIC_METRIC_CARD2_tt=Scheda Metrica 2 METRIC_METRIC_QUOTA_tt=Quota Metrica METRIC_METRIC_PLAIN_TEXT_tt=Testo Metrica TABLE_default_tt=Tabella EXTERNAL_COMPONENT_default_tt=Componente Esterno SELECTOR_SELECTOR_DROPDOWN_tt=Menu a Tendina SELECTOR_SELECTOR_LABELS_tt=Set di Etichette SELECTOR_SELECTOR_SLIDER_tt=Slider ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_type_selector_tab_bar=バー displayer_type_selector_tab_pie=円 (パイ) displayer_type_selector_tab_line=Line displayer_type_selector_tab_area=エリア displayer_type_selector_tab_bubble=バブル displayer_type_selector_tab_meter=メーター displayer_type_selector_tab_metric=メトリック displayer_type_selector_tab_map=マップ displayer_type_selector_tab_table=テーブル displayer_type_selector_tab_selector=セレクター # Subtype enum literals DISPLAYER_SUBTYPE_LINE=Line DISPLAYER_SUBTYPE_SMOOTH=スムーズ DISPLAYER_SUBTYPE_AREA=エリア DISPLAYER_SUBTYPE_STACKED=スタック DISPLAYER_SUBTYPE_STEPPED=階段状 DISPLAYER_SUBTYPE_BAR=バー DISPLAYER_SUBTYPE_BAR_STACKED=スタックされたのバー DISPLAYER_SUBTYPE_COLUMN=カラム DISPLAYER_SUBTYPE_COLUMN_STACKED=スタックされた列 DISPLAYER_SUBTYPE_HISTOGRAM=ヒストグラム DISPLAYER_SUBTYPE_PIE=円 (パイ) DISPLAYER_SUBTYPE_PIE_3D=3D の円 (パイ) DISPLAYER_SUBTYPE_DONUT=ドーナツ DISPLAYER_SUBTYPE_MAP_REGIONS=マップ (リージョン) DISPLAYER_SUBTYPE_MAP_MARKERS=マップ (マーカー) DISPLAYER_SUBTYPE_METRIC_CARD=メトリックカード DISPLAYER_SUBTYPE_METRIC_CARD2=メトリックカード 2 DISPLAYER_SUBTYPE_METRIC_QUOTA=メトリッククォータ DISPLAYER_SUBTYPE_METRIC_PLAIN_TEXT=メトリックテキスト DISPLAYER_SUBTYPE_SELECTOR_DROPDOWN=ドロップダウン DISPLAYER_SUBTYPE_SELECTOR_LABELS=ラベルセット DISPLAYER_SUBTYPE_SELECTOR_SLIDER=スライダー # Subtype selector tooltips BARCHART_BAR_tt=棒グラフ BARCHART_BAR_STACKED_tt=スタック状の棒グラフ BARCHART_COLUMN_tt=コラムチャート BARCHART_COLUMN_STACKED_tt=スタック状のコラムチャート PIECHART_PIE_tt=円グラフ PIECHART_PIE_3D_tt=3D の円グラフ PIECHART_DONUT_tt=円グラフ (ドーナツ型) AREACHART_AREA_tt=エリアチャート AREACHART_AREA_STACKED_tt=スタック状のエリアチャート LINECHART_LINE_tt=折れ線グラフ LINECHART_SMOOTH_tt=平滑線グラフ MAP_MAP_REGIONS_tt=マップチャート (リージョン) MAP_MAP_MARKERS_tt=マップチャート (マーカー) BUBBLECHART_default_tt=バブルチャート METERCHART_default_tt=メーターチャート METRIC_METRIC_CARD_tt=メトリックカード METRIC_METRIC_CARD2_tt=メトリックカード 2 METRIC_METRIC_QUOTA_tt=メトリッククォータ METRIC_METRIC_PLAIN_TEXT_tt=メトリックテキスト TABLE_default_tt=テーブル EXTERNAL_COMPONENT_default_tt=外部コンポーネント SELECTOR_SELECTOR_DROPDOWN_tt=ドロップダウン SELECTOR_SELECTOR_LABELS_tt=ラベルセット SELECTOR_SELECTOR_SLIDER_tt=スライダー ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants_pt_BR.properties ================================================ displayer_type_selector_tab_bar=Barra displayer_type_selector_tab_pie=Setor displayer_type_selector_tab_line=Linha displayer_type_selector_tab_area=Área displayer_type_selector_tab_bubble=Bolha displayer_type_selector_tab_meter=Medidor displayer_type_selector_tab_metric=Métrica displayer_type_selector_tab_map=Mapa displayer_type_selector_tab_table=Tabela DISPLAYER_SUBTYPE_LINE=Linha DISPLAYER_SUBTYPE_SMOOTH=Suave DISPLAYER_SUBTYPE_AREA=Área DISPLAYER_SUBTYPE_STACKED=Empilhada DISPLAYER_SUBTYPE_STEPPED=Nìvel DISPLAYER_SUBTYPE_BAR=Barra DISPLAYER_SUBTYPE_BAR_STACKED=Barra Empilhada DISPLAYER_SUBTYPE_COLUMN=Coluna DISPLAYER_SUBTYPE_COLUMN_STACKED=Coluna Empilhada DISPLAYER_SUBTYPE_HISTOGRAM=Histograma DISPLAYER_SUBTYPE_PIE=Setor DISPLAYER_SUBTYPE_PIE_3D=Setor 3D DISPLAYER_SUBTYPE_DONUT=Rosca DISPLAYER_SUBTYPE_MAP_REGIONS=Mapa (Regiões) DISPLAYER_SUBTYPE_MAP_MARKERS=Mapa (Marcadores) BARCHART_BAR_tt=Gráfico de Barra BARCHART_BAR_STACKED_tt=Gráfico de Barra Empilhada BARCHART_COLUMN_tt=Gráfico de Coluna BARCHART_COLUMN_STACKED_tt=Gráfico de Coluna Empilhada PIECHART_PIE_tt=Gráfico de Setor PIECHART_PIE_3D_tt=Gráfico de Setor 3D PIECHART_DONUT_tt=Gráfico de Setor (rosca) AREACHART_AREA_tt=Gráfico de Área AREACHART_AREA_STACKED_tt=Gráfico de Área Empilhada LINECHART_LINE_tt=Gráfico de Linha LINECHART_SMOOTH_tt=Gráfico de Linha Suave MAP_MAP_REGIONS_tt=Gráfico de Mapa (regiões) MAP_MAP_MARKERS_tt=Gráfico de Mapa (marcadores) BUBBLECHART_default_tt=Gráfico de Bolha METERCHART_default_tt=Gráfico de Medidor TABLE_default_tt=Tabela ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/DisplayerTypeConstants_zh_CN.properties ================================================ displayer_type_selector_tab_bar=条形 displayer_type_selector_tab_pie=饼 displayer_type_selector_tab_line=折线 displayer_type_selector_tab_area=面积 displayer_type_selector_tab_bubble=气泡 displayer_type_selector_tab_meter=仪表 displayer_type_selector_tab_metric=度量 displayer_type_selector_tab_map=映射 displayer_type_selector_tab_table=图表 DISPLAYER_SUBTYPE_LINE=折线 DISPLAYER_SUBTYPE_SMOOTH=平滑 DISPLAYER_SUBTYPE_AREA=面积 DISPLAYER_SUBTYPE_STACKED=堆叠图 DISPLAYER_SUBTYPE_STEPPED=递阶 DISPLAYER_SUBTYPE_BAR=条形 DISPLAYER_SUBTYPE_BAR_STACKED=条形堆叠图 DISPLAYER_SUBTYPE_COLUMN=柱 DISPLAYER_SUBTYPE_COLUMN_STACKED=柱状堆叠图 DISPLAYER_SUBTYPE_HISTOGRAM=直方图 DISPLAYER_SUBTYPE_PIE=饼状图 DISPLAYER_SUBTYPE_PIE_3D=3D 饼状图 DISPLAYER_SUBTYPE_DONUT=圈图 DISPLAYER_SUBTYPE_MAP_REGIONS=映射(区域) DISPLAYER_SUBTYPE_MAP_MARKERS=映射(标记) BARCHART_BAR_tt=条形图 BARCHART_BAR_STACKED_tt=堆叠条形图 BARCHART_COLUMN_tt=柱状图 BARCHART_COLUMN_STACKED_tt=堆叠柱状图 PIECHART_PIE_tt=饼状图 PIECHART_PIE_3D_tt=3D 饼状图 PIECHART_DONUT_tt=饼状图(圈状) AREACHART_AREA_tt=面积图 AREACHART_AREA_STACKED_tt=堆叠面积图 LINECHART_LINE_tt=折线图 LINECHART_SMOOTH_tt=平滑折线图 MAP_MAP_REGIONS_tt=映射图(区域) MAP_MAP_MARKERS_tt=映射图(标记) BUBBLECHART_default_tt=气泡图 METERCHART_default_tt=仪表图 TABLE_default_tt=图表 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/MapColorSchemeConstants.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # MapColorScheme enum literals COLOR_SCHEME_RED=Red COLOR_SCHEME_BLUE=Blue COLOR_SCHEME_GREEN=Green ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/MapColorSchemeConstants_es.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # MapColorScheme enum literals COLOR_SCHEME_RED=Rojo COLOR_SCHEME_BLUE=Azul COLOR_SCHEME_GREEN=Verde ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/MapColorSchemeConstants_fr.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # MapColorScheme enum literals COLOR_SCHEME_RED=Rouge COLOR_SCHEME_BLUE=Bleu COLOR_SCHEME_GREEN=Vert ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/MapColorSchemeConstants_it.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # MapColorScheme enum literals COLOR_SCHEME_RED=Rosso COLOR_SCHEME_BLUE=Blu COLOR_SCHEME_GREEN=Verde ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/MapColorSchemeConstants_ja.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # MapColorScheme enum literals COLOR_SCHEME_RED=赤 COLOR_SCHEME_BLUE=青 COLOR_SCHEME_GREEN=緑 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Position enum literals POSITION_BOTTOM=Bottom POSITION_TOP=Top POSITION_LEFT=Left POSITION_RIGHT=Right POSITION_IN=In ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants_de.properties ================================================ POSITION_BOTTOM=Unten POSITION_TOP=Oben POSITION_LEFT=Links POSITION_RIGHT=Rechts POSITION_IN=In ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants_es.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Position enum literals POSITION_BOTTOM=Inferior POSITION_TOP=Superior POSITION_LEFT=Izquierda POSITION_RIGHT=Derecha POSITION_IN=En ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants_fr.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Position enum literals POSITION_BOTTOM=Bas POSITION_TOP=Haut POSITION_LEFT=Gauche POSITION_RIGHT=Droite POSITION_IN=Dans ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants_it.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Position enum literals POSITION_BOTTOM=Fondo POSITION_TOP=Superiore POSITION_LEFT=Sinistra POSITION_RIGHT=Destra POSITION_IN=Interno ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants_ja.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Position enum literals POSITION_BOTTOM=下揃え POSITION_TOP=上揃え POSITION_LEFT=左揃え POSITION_RIGHT=右揃え POSITION_IN=In ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants_pt_BR.properties ================================================ POSITION_BOTTOM=Inferior POSITION_TOP=Superior POSITION_LEFT=Esquerda POSITION_RIGHT=Direita POSITION_IN=Dentro ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/PositionConstants_zh_CN.properties ================================================ POSITION_BOTTOM=底部 POSITION_TOP=顶部 POSITION_LEFT=左 POSITION_RIGHT=右 POSITION_IN=内 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeEditorConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # add_variable=Add variable ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeEditorConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # add_variable=Agregar variable ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeEditorConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # add_variable=Ajouter une variable ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeEditorConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # add_variable=Aggiungi una variabile ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeEditorConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # add_variable=変数を追加 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeValidatorConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # js_keyword_not_allowed=Not allowed: "{0}" js_variable_not_found=The variable {0} is not defined ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeValidatorConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # js_keyword_not_allowed=No está permitido: "{0}" js_variable_not_found=La variable {0} no está definida ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeValidatorConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # js_keyword_not_allowed=Non autorisé : "{0}" js_variable_not_found=La variable {0} n''est pas définie ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeValidatorConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # js_keyword_not_allowed=Non consentito: "{0}" js_variable_not_found=La variabile {0} non è definita ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/SourceCodeValidatorConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # js_keyword_not_allowed=許可されていません:''{0}'' js_variable_not_found=変数 {0}は設定されていません ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/AbstractDisplayerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyListOf; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.Date; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.List; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.client.AbstractDataSetTest; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.impl.DataColumnImpl; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.formatter.ValueFormatterRegistry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.Silent.class) public class AbstractDisplayerTest extends AbstractDataSetTest { @Mock protected RendererManager rendererManager; @Mock protected RendererLibrary rendererLibrary; @Mock protected ValueFormatterRegistry formatterRegistry; protected DisplayerLocator displayerLocator; @Before public void init() throws Exception { super.init(); displayerLocator = new DisplayerLocator(clientServices, clientDataSetManager, rendererManager, formatterRegistry); when(rendererManager.getRendererForDisplayer(any(DisplayerSettings.class))).thenReturn(rendererLibrary); doAnswer(mock -> createNewDisplayer((DisplayerSettings) mock.getArguments()[0])) .when(rendererLibrary).lookupDisplayer(any(DisplayerSettings.class)); doAnswer(mock -> createNewDisplayer((DisplayerSettings) mock.getArguments()[0])) .when(rendererLibrary).lookupDisplayer(any(DisplayerSettings.class)); doAnswer(mock -> { List displayerList = (List) mock.getArguments()[0]; for (Displayer displayer : displayerList) { displayer.draw(); } return null; }).when(rendererLibrary).draw(anyListOf(Displayer.class)); } public AbstractDisplayer createNewDisplayer(DisplayerSettings settings) { return initDisplayer(new DisplayerMock(mock(AbstractDisplayer.View.class), null), settings); } public AbstractDisplayer createNewDisplayer(DisplayerSettings settings, boolean ignoreError) { return initDisplayer(new DisplayerMock(mock(AbstractDisplayer.View.class), null, ignoreError), settings); } public D initDisplayer(D displayer, DisplayerSettings settings) { displayer.setEvaluator(new DisplayerEvaluatorMock()); displayer.setFormatter(new DisplayerFormatterMock()); displayer.addListener(new AbstractDisplayerListener() { public void onError(Displayer displayer, ClientRuntimeError error) { throw new RuntimeException(error.getRootCause()); } }); if (settings != null) { displayer.setDisplayerSettings(settings); displayer.setDataSetHandler(new DataSetHandlerImpl(clientServices, settings.getDataSetLookup())); } return displayer; } @Test public void callbackOnErrorTest() throws Exception { DataSetHandler dataSetHandler = mock(DataSetHandler.class); DisplayerSettings simpleSettings = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filterOn(true, false, true) .buildSettings(); AbstractDisplayer simpleDisplayer = createNewDisplayer(simpleSettings, true); simpleDisplayer.listenerList = java.util.Collections.emptyList(); simpleDisplayer.setDataSetHandler(dataSetHandler); simpleDisplayer.redraw(); assertTrue(simpleDisplayer.isDrawn()); doAnswer((InvocationOnMock invocation) -> { DataSetReadyCallback callback = (DataSetReadyCallback) invocation.getArguments()[0]; callback.onError(new ClientRuntimeError("test")); return null; }).when(dataSetHandler).lookupDataSet(any()); simpleDisplayer.redraw(); assertTrue(!simpleDisplayer.isDrawn()); } @Test public void testFormatValue() throws Exception { DisplayerSettings simpleSettings = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filterOn(true, false, true) .buildSettings(); AbstractDisplayer simpleDisplayer = createNewDisplayer(simpleSettings, true); DataColumn dateColumn = new DataColumnImpl(); dateColumn.setId("proceesedDate"); dateColumn.setColumnType(ColumnType.DATE); Date date1= new SimpleDateFormat("dd/MM/yyyy") .parse("28/10/2020"); dateColumn.setValues(Arrays.asList(date1)); assertEquals("Oct 28, 2020 00:00", simpleDisplayer.formatValue(date1, dateColumn)); DataColumn column = new DataColumnImpl(); column.setId("slaCompliance"); column.setColumnType(ColumnType.NUMBER); column.setValues(Arrays.asList(0)); assertEquals("0.00", simpleDisplayer.formatValue(0, column)); DataColumn numberColumn = new DataColumnImpl(); numberColumn.setId("slaCompliance"); numberColumn.setColumnType(ColumnType.NUMBER); numberColumn.setValues(Arrays.asList("0")); assertEquals("0.00", simpleDisplayer.formatValue("0", numberColumn)); DataColumn emptyNumberColumn = new DataColumnImpl(); emptyNumberColumn.setId("dataId"); emptyNumberColumn.setColumnType(ColumnType.NUMBER); emptyNumberColumn.setValues(Arrays.asList("")); assertEquals("", simpleDisplayer.formatValue("", emptyNumberColumn)); DataColumn textColumn = new DataColumnImpl(); textColumn.setId("dataId"); textColumn.setColumnType(ColumnType.TEXT); textColumn.setValues(Arrays.asList("test")); assertEquals("test", simpleDisplayer.formatValue("test", textColumn)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerCoordinatorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.Date; import java.util.List; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class DisplayerCoordinatorTest extends AbstractDisplayerTest { DisplayerSettings byDepartment = DisplayerSettingsFactory.newPieChartSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_AMOUNT, SUM) .sort(COLUMN_DEPARTMENT, SortOrder.ASCENDING) .filterOn(false, true, true) .buildSettings(); DisplayerSettings byDepartmentSelector = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_AMOUNT, SUM) .sort(COLUMN_DEPARTMENT, SortOrder.ASCENDING) .filterOn(false, true, false) .buildSettings(); DisplayerSettings byYear = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE).dynamic(DateIntervalType.YEAR, true) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .filterOn(false, true, true) .sort(COLUMN_DATE, SortOrder.ASCENDING) .buildSettings(); DisplayerSettings byQuarter = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.equalsTo(1)) .group(COLUMN_DATE).fixed(DateIntervalType.QUARTER, false) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .filterOn(false, true, true) .sort(COLUMN_DATE, SortOrder.ASCENDING) .buildSettings(); DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .column(COLUMN_DEPARTMENT) .column(COLUMN_CITY) .column(COLUMN_EMPLOYEE) .column(COLUMN_AMOUNT) .column(COLUMN_DATE) .filterOn(true, false, true) .buildSettings(); DisplayerCoordinator displayerCoordinator; AbstractDisplayer allRowsTable; AbstractDisplayer deptPieChart; AbstractDisplayer deptSelector; AbstractDisplayer yearBarChart; AbstractDisplayer quarterPieChart; @Mock DisplayerListener listener; @Before public void init() throws Exception { super.init(); allRowsTable = createNewDisplayer(allRows); deptPieChart = createNewDisplayer(byDepartment); deptSelector = createNewDisplayer(byDepartmentSelector); yearBarChart = createNewDisplayer(byYear); quarterPieChart = createNewDisplayer(byQuarter); displayerCoordinator = new DisplayerCoordinator(rendererManager); displayerCoordinator.addDisplayers(allRowsTable, deptPieChart, deptSelector, yearBarChart, quarterPieChart); displayerCoordinator.addListener(listener); } @Test public void testDrawAll() { displayerCoordinator.drawAll(); verify(listener, times(5)).onDataLookup(any(Displayer.class)); verify(listener, times(5)).onDraw(any(Displayer.class)); } @Test public void testFilterPropagations() { displayerCoordinator.drawAll(); // Click on the "Engineering" slice reset(listener); deptPieChart.filterUpdate(COLUMN_DEPARTMENT, 0); // Check the allRowsTable receives the filter request DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 19); verify(listener).onDataLookup(allRowsTable); verify(listener).onRedraw(allRowsTable); } @Test public void testFilterReset() { displayerCoordinator.drawAll(); // Click on a slice deptPieChart.filterUpdate(COLUMN_DEPARTMENT, 0); List deptIntervalList = deptPieChart.filterIntervals(COLUMN_DEPARTMENT); assertEquals(deptIntervalList.size(), 1); Interval deptInterval = deptIntervalList.get(0); // Click on a selector entry different from the slice selected above deptSelector.filterUpdate(COLUMN_DEPARTMENT, 1); // Check the pie chart receives the selector filter request DataSet dataSet = deptPieChart.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 1); assertEquals(deptPieChart.filterIndexes(COLUMN_DEPARTMENT).size(), 1); // Reset the pie chart filter deptPieChart.filterUpdate(COLUMN_DEPARTMENT, deptInterval.getIndex()); deptIntervalList = deptPieChart.filterIntervals(COLUMN_DEPARTMENT); assertEquals(deptIntervalList.size(), 0); } @Test public void testQuarterFilter() { displayerCoordinator.drawAll(); // Click on the "Q4" slice reset(listener); quarterPieChart.filterUpdate(COLUMN_DATE, 0); // Check the allRowsTable receives the filter request DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 10); for (int i = 0; i < dataSet.getRowCount(); i++) { Date d = (Date) dataSet.getValueAt(i, COLUMN_DATE); assertTrue(d.getMonth() > 8); } verify(listener).onDataLookup(allRowsTable); verify(listener).onRedraw(allRowsTable); } @Test public void testYearFilter() { displayerCoordinator.drawAll(); // Click on the "2014" slice reset(listener); yearBarChart.filterUpdate(COLUMN_DATE, 2); // Check the allRowsTable receives the filter request DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 11); for (int i = 0; i < dataSet.getRowCount(); i++) { Date d = (Date) dataSet.getValueAt(i, COLUMN_DATE); assertEquals(d.getYear(), 114); } verify(listener).onDataLookup(allRowsTable); verify(listener).onRedraw(allRowsTable); } @Test public void testMultipleFilter() { displayerCoordinator.drawAll(); // Click on the "2014" slice yearBarChart.filterUpdate(COLUMN_DATE, 2); // Click on the "Sales" slice deptPieChart.filterUpdate(COLUMN_DEPARTMENT, 1); // Check the allRowsTable receives all the filter requests DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 2); } @Test public void testFilterUpdates() { displayerCoordinator.drawAll(); // Filter by amount DataSetFilter filterOp = new DataSetFilter(); CoreFunctionFilter columnFilter = new CoreFunctionFilter(COLUMN_AMOUNT, CoreFunctionType.BETWEEN, 1d, 1.2d); filterOp.addFilterColumn(columnFilter); yearBarChart.filterUpdate(filterOp); DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 1); // Filter by a different range filterOp = new DataSetFilter(); columnFilter = new CoreFunctionFilter(COLUMN_AMOUNT, CoreFunctionType.BETWEEN, 1000d, 2000d); filterOp.addFilterColumn(columnFilter); DisplayerListener listener = mock(DisplayerListener.class); allRowsTable.addListener(listener); yearBarChart.filterUpdate(filterOp); verify(listener).onRedraw(allRowsTable); dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 2); } @Test public void testFilterWithNull() { // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DEPARTMENT)); expensesDataSet.setValueAt(0, column, null); // Draw the charts displayerCoordinator.drawAll(); // Click on the "Engineering" slice reset(listener); deptPieChart.filterUpdate(COLUMN_DEPARTMENT, 1); // Check the allRowsTable receives the filter request DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); verify(listener, never()).onError(any(Displayer.class), any(ClientRuntimeError.class)); verify(listener).onDataLookup(allRowsTable); verify(listener).onRedraw(allRowsTable); assertEquals(dataSet.getRowCount(), 18); } /** * Avoid IndexOutOfBoundsException caused when a filter is notified to * a table consuming the whole data set (no data lookup columns set). */ @Test public void testFullTableFilterEvent() { AbstractDisplayer tableNoColumns = createNewDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filterOn(true, false, true) .buildSettings()); displayerCoordinator = new DisplayerCoordinator(rendererManager); displayerCoordinator.addDisplayers(deptPieChart, tableNoColumns); displayerCoordinator.addListener(listener); displayerCoordinator.drawAll(); // Click on the "Engineering" slice reset(listener); deptPieChart.filterUpdate(COLUMN_DEPARTMENT, 0); // Check the allRowsTable receives the filter request DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 19); verify(listener).onDataLookup(allRowsTable); verify(listener).onRedraw(tableNoColumns); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerEvaluatorMock.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; public class DisplayerEvaluatorMock implements AbstractDisplayer.ExpressionEval { @Override public String evalExpression(String value, String expression) { return value; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerExportTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.export.ExportCallback; import org.dashbuilder.displayer.client.export.ExportFormat; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.Silent.class) public class DisplayerExportTest extends AbstractDisplayerTest { DisplayerSettings EMPTY = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filter(COLUMN_CITY, FilterFactory.isNull()) .buildSettings(); DisplayerSettings ALLROWS = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .buildSettings(); DisplayerSettings CUSTOM_NAMES = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .column(COLUMN_DEPARTMENT).format("Dept") .column(COLUMN_EMPLOYEE).format("Emp") .column(COLUMN_CITY).format("City") .column(COLUMN_DATE).format("Date") .column(COLUMN_AMOUNT).format("$") .buildSettings(); @Mock ExportCallback exportCallback; @Test public void testExportDisplayer() { Displayer displayer = displayerLocator.lookupDisplayer(ALLROWS); displayer.draw(); displayer.export(ExportFormat.CSV, -1, exportCallback); verify(exportCallback).exportFileUrl(any()); } @Test public void testExportNonDrawnDisplayer() { Displayer displayer = displayerLocator.lookupDisplayer(ALLROWS); displayer.export(ExportFormat.CSV, -1, exportCallback); verify(exportCallback).noData(); } @Test public void testExportEmptyDisplayer() { Displayer displayer = displayerLocator.lookupDisplayer(EMPTY); displayer.draw(); displayer.export(ExportFormat.CSV, -1, exportCallback); verify(exportCallback).noData(); } @Test public void testExportLimitExceeded() { Displayer displayer = displayerLocator.lookupDisplayer(ALLROWS); displayer.draw(); displayer.export(ExportFormat.CSV, 10, exportCallback); verify(exportCallback).tooManyRows(50); } @Test public void testExportLimitRuledOut() { Displayer displayer = displayerLocator.lookupDisplayer(ALLROWS); displayer.draw(); displayer.export(ExportFormat.CSV, 0, exportCallback); verify(exportCallback, never()).tooManyRows(anyInt()); verify(exportCallback).exportFileUrl(any()); } @Test public void testDefaultNamesCsv() throws Exception { testDefaultNames(ExportFormat.CSV); } @Test public void testCustomNamesCsv() throws Exception { testCustomNames(ExportFormat.CSV); } @Test public void testDefaultNamesXls() throws Exception { testDefaultNames(ExportFormat.XLS); } @Test public void testCustomNamesXls() throws Exception { testCustomNames(ExportFormat.XLS); } public void testDefaultNames(ExportFormat format) throws Exception { Displayer displayer = displayerLocator.lookupDisplayer(ALLROWS); displayer.draw(); displayer.export(format, 0, exportCallback); ArgumentCaptor dataSetCaptor = ArgumentCaptor.forClass(DataSet.class); if (ExportFormat.CSV.equals(format)) { verify(dataSetExportServices).exportDataSetCSV(dataSetCaptor.capture()); } else { verify(dataSetExportServices).exportDataSetExcel(dataSetCaptor.capture()); } DataSet dataSet = dataSetCaptor.getValue(); assertEquals(dataSet.getColumns().size(), 6); assertEquals(dataSet.getColumns().get(0).getId(), COLUMN_ID); assertEquals(dataSet.getColumns().get(1).getId(), COLUMN_CITY); assertEquals(dataSet.getColumns().get(2).getId(), COLUMN_DEPARTMENT); assertEquals(dataSet.getColumns().get(3).getId(), COLUMN_EMPLOYEE); assertEquals(dataSet.getColumns().get(4).getId(), COLUMN_DATE); assertEquals(dataSet.getColumns().get(5).getId(), COLUMN_AMOUNT); } public void testCustomNames(ExportFormat format) throws Exception { Displayer displayer = displayerLocator.lookupDisplayer(CUSTOM_NAMES); displayer.draw(); displayer.export(format, 0, exportCallback); ArgumentCaptor dataSetCaptor = ArgumentCaptor.forClass(DataSet.class); if (ExportFormat.CSV.equals(format)) { verify(dataSetExportServices).exportDataSetCSV(dataSetCaptor.capture()); } else { verify(dataSetExportServices).exportDataSetExcel(dataSetCaptor.capture()); } DataSet dataSet = dataSetCaptor.getValue(); assertEquals(dataSet.getColumns().size(), 5); assertEquals(dataSet.getColumns().get(0).getId(), "Dept"); assertEquals(dataSet.getColumns().get(1).getId(), "Emp"); assertEquals(dataSet.getColumns().get(2).getId(), "City"); assertEquals(dataSet.getColumns().get(3).getId(), "Date"); assertEquals(dataSet.getColumns().get(4).getId(), "$"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerFilterTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class DisplayerFilterTest extends AbstractDisplayerTest { DisplayerSettings byDepartment = DisplayerSettingsFactory.newPieChartSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_AMOUNT, SUM) .filterOn(false, true, true) .buildSettings(); DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filterOn(true, false, true) .sort(COLUMN_DEPARTMENT, SortOrder.ASCENDING) .buildSettings(); @Test public void testDrawRequired() { AbstractDisplayer allRowsTable = (AbstractDisplayer) displayerLocator.lookupDisplayer(allRows); allRowsTable.filterUpdate(COLUMN_DEPARTMENT, 0); DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertNull(dataSet); } @Test public void testNotifications() { AbstractDisplayer deptPieChart = (AbstractDisplayer) displayerLocator.lookupDisplayer(byDepartment); DisplayerListener listener = mock(DisplayerListener.class); deptPieChart.addListener(listener); deptPieChart.draw(); deptPieChart.filterUpdate(COLUMN_DEPARTMENT, 0); verify(listener).onFilterEnabled(eq(deptPieChart), any(DataSetGroup.class)); verify(listener, never()).onRedraw(deptPieChart); deptPieChart.filterReset(); verify(listener).onFilterReset(eq(deptPieChart), anyList()); verify(listener, never()).onRedraw(deptPieChart); } @Test public void testDrillDown() { AbstractDisplayer allRowsTable = (AbstractDisplayer) displayerLocator.lookupDisplayer(allRows); DisplayerListener listener = mock(DisplayerListener.class); allRowsTable.addListener(listener); allRowsTable.draw(); // Filter by "Engineering" reset(listener); allRowsTable.filterUpdate(COLUMN_DEPARTMENT, 0); DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 19); verify(listener).onDataLookup(allRowsTable); verify(listener).onRedraw(allRowsTable); } @Test public void testFilterNotAllowed() { AbstractDisplayer allRowsTable = (AbstractDisplayer) displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filterOff(true) .buildSettings()); DisplayerListener listener = mock(DisplayerListener.class); allRowsTable.addListener(listener); allRowsTable.draw(); reset(listener); allRowsTable.filterUpdate(COLUMN_DEPARTMENT, 0); DataSet dataSet = allRowsTable.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 50); verify(listener, never()).onDataLookup(allRowsTable); verify(listener, never()).onRedraw(allRowsTable); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerFormatterMock.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; public class DisplayerFormatterMock implements AbstractDisplayer.Formatter { @Override public String formatMonth(Month month) { return month.name(); } @Override public String formatDayOfWeek(DayOfWeek dayOfWeek) { return dayOfWeek.name(); } @Override public String formatNumber(String pattern, Number n) { DecimalFormat df = new DecimalFormat(pattern); return df.format(n); } @Override public Date parseDate(String pattern, String d) { try { SimpleDateFormat df = new SimpleDateFormat(pattern); return df.parse(d); } catch (ParseException e) { throw new RuntimeException(e); } } @Override public String formatDate(String pattern, Date d) { SimpleDateFormat df = new SimpleDateFormat(pattern); return df.format(d); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerLifecycleTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.mockito.Mockito.*; import static org.junit.Assert.*; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.Assertions.*; @RunWith(MockitoJUnitRunner.Silent.class) public class DisplayerLifecycleTest extends AbstractDisplayerTest { DisplayerSettings settings = DisplayerSettingsFactory.newPieChartSettings() .uuid("expenses") .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, COUNT) .column(COLUMN_AMOUNT, SUM) .buildSettings(); @Mock DisplayerListener listener; @Test public void testLookup() { Displayer displayer = displayerLocator.lookupDisplayer(settings); assertNotNull(displayer); assertNotNull(displayer.getDataSetHandler()); assertNotNull(displayer.getDisplayerSettings()); assertEquals(displayer.getDisplayerSettings(), settings); } @Test public void testDraw() { AbstractDisplayer displayer = (AbstractDisplayer) displayerLocator.lookupDisplayer(settings); AbstractDisplayer.View view = displayer.getView(); displayer.addListener(listener); assertEquals(displayer.isDrawn(), false); displayer.draw(); assertEquals(displayer.isDrawn(), true); verify(view).showLoading(); verify(view).setId("expenses"); verify(listener).onDataLookup(displayer); verify(listener).onDataLoaded(displayer); verify(listener).onDraw(displayer); verify(listener, never()).onRedraw(displayer); assertDataSetValues(displayer.getDataSetHandler().getLastDataSet(), new String[][]{ {"2012", "13.00", "6,126.13"}, {"2013", "11.00", "5,252.96"}, {"2014", "11.00", "4,015.48"}, {"2015", "15.00", "7,336.69"} }, 0); } @Test public void testRedraw() { AbstractDisplayer displayer = (AbstractDisplayer) displayerLocator.lookupDisplayer(settings); AbstractDisplayer.View view = displayer.getView(); displayer.addListener(listener); displayer.draw(); reset(view); reset(listener); assertEquals(displayer.isDrawn(), true); displayer.redraw(); assertEquals(displayer.isDrawn(), true); verify(listener).onDataLookup(displayer); verify(listener).onRedraw(displayer); verify(listener, never()).onDraw(displayer); verify(view, never()).showLoading(); assertDataSetValues(displayer.getDataSetHandler().getLastDataSet(), new String[][]{ {"2012", "13.00", "6,126.13"}, {"2013", "11.00", "5,252.96"}, {"2014", "11.00", "4,015.48"}, {"2015", "15.00", "7,336.69"} }, 0); } @Test public void testClose() { AbstractDisplayer displayer = (AbstractDisplayer) displayerLocator.lookupDisplayer(settings); AbstractDisplayer.View view = displayer.getView(); displayer.addListener(listener); displayer.close(); verify(view).clear(); verify(listener).onClose(displayer); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerMock.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.displayer.DisplayerConstraints; public class DisplayerMock extends AbstractDisplayer { private AbstractDisplayer.View view; private DisplayerConstraints constraints; private boolean ignoreError; public DisplayerMock(AbstractDisplayer.View view, DisplayerConstraints constraints) { this.view = view; this.constraints = constraints; } public DisplayerMock(AbstractDisplayer.View view, DisplayerConstraints constraints, boolean ignoreError) { this.view = view; this.constraints = constraints; this.ignoreError = ignoreError; } @Override public AbstractDisplayer.View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { return constraints; } @Override protected void createVisualization() { // Mock } @Override protected void updateVisualization() { // Mock } @Override public void handleError(ClientRuntimeError error) { super.handleError(error); if (! ignoreError) { throw new RuntimeException(error.getRootCause()); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/DisplayerRefreshTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class DisplayerRefreshTest extends AbstractDisplayerTest { @Test public void testRefreshEnabled() { AbstractDisplayer displayer = (AbstractDisplayer) displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .refreshOn(10, false) .buildSettings() ); displayer.draw(); assertEquals(displayer.isRefreshOn(), true); verify(displayer.getView()).enableRefreshTimer(10); verify(displayer.getView(), never()).cancelRefreshTimer(); } @Test public void testRefreshDisabled() { AbstractDisplayer displayer = (AbstractDisplayer) displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .refreshOff() .buildSettings() ); displayer.draw(); assertEquals(displayer.isRefreshOn(), true); verify(displayer.getView()).cancelRefreshTimer(); verify(displayer.getView(), never()).enableRefreshTimer(anyInt()); } @Test public void testSwitchRefreshOff() { AbstractDisplayer displayer = (AbstractDisplayer) displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .refreshOn(10, false) .buildSettings() ); // Draw is always required ion order to switch refresh on displayer.draw(); // Switch off reset(displayer.getView()); displayer.setRefreshOn(false); assertEquals(displayer.isRefreshOn(), false); verify(displayer.getView()).cancelRefreshTimer(); } @Test public void testSwitchRefreshOn() { AbstractDisplayer displayer = (AbstractDisplayer) displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .refreshOn(10, false) .buildSettings() ); // Refresh enabled on draw AbstractDisplayer.View view = displayer.getView(); displayer.draw(); verify(view).enableRefreshTimer(10); // Already on, nothing happens reset(view); displayer.setRefreshOn(true); verify(view, never()).enableRefreshTimer(anyInt()); verify(view, never()).cancelRefreshTimer(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/RendererManagerTest.java ================================================ package org.dashbuilder.displayer.client; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.renderer.RendererSettings; import org.dashbuilder.renderer.service.RendererSettingsService; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.dashbuilder.displayer.DisplayerSubType.*; import static org.dashbuilder.displayer.DisplayerType.*; 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.mockito.Mockito.*; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.mockito.stubbing.Answer; import org.uberfire.mocks.CallerMock; import com.google.gwtmockito.GwtMockitoTestRunner; @RunWith(GwtMockitoTestRunner.class) public class RendererManagerTest { private static final String REND2_NAME = "renderer 2"; private static final String REND1_NAME = "renderer 1"; private static final String REND2_UUID = "rend2"; private static final String REND1_UUID = "rend1"; private static final String DEFAULT_REND_FOR_BARCHART_UUID = REND1_UUID; @Mock SyncBeanManager beanManager; @Mock DisplayerSettings displayerSettings; @Mock RendererSettingsService rendererSettingsService; @Mock RendererSettings rendererSettings; Caller rendererSettingsServiceCaller; RendererManager rendererManager; int totalBeans; @Before public void setUp() { rendererSettingsServiceCaller = new CallerMock<>(rendererSettingsService); when(rendererSettingsService.getSettings()).thenReturn(rendererSettings); rendererManager = new RendererManager(beanManager, rendererSettingsServiceCaller); mockConstants(); Map> typesAndSubTypes1 = new HashMap<>(); typesAndSubTypes1.put(BARCHART, Arrays.asList(BAR)); typesAndSubTypes1.put(AREACHART, Arrays.asList(AREA)); typesAndSubTypes1.put(LINECHART, Arrays.asList(LINE)); Map> typesAndSubTypes2 = new HashMap<>(); typesAndSubTypes2.put(LINECHART, Arrays.asList(LINE, SMOOTH)); typesAndSubTypes2.put(BARCHART, Arrays.asList(BAR, BAR_STACKED)); List> rendererLibrariesBeans = Arrays.asList( mockSyncBeanForRendererLib(REND1_NAME, REND1_UUID, Arrays.asList(BARCHART, AREACHART), typesAndSubTypes1, true), mockSyncBeanForRendererLib(REND2_NAME, REND2_UUID, Collections.emptyList(), typesAndSubTypes2, false) ); totalBeans = rendererLibrariesBeans.size(); when(beanManager.lookupBeans(RendererLibrary.class)) .thenReturn(rendererLibrariesBeans); rendererManager.init(); } @Test public void renderersForType2Test() { List renderersForType = rendererManager.getRenderersForType(null, null); assertEquals(totalBeans, renderersForType.size()); renderersForType = rendererManager.getRenderersForType(BARCHART, null); assertEquals(2, renderersForType.size()); renderersForType = rendererManager.getRenderersForType(AREACHART, AREA); assertEquals(1, renderersForType.size()); renderersForType = rendererManager.getRenderersForType(BARCHART, BAR); assertEquals(2, renderersForType.size()); renderersForType = rendererManager.getRenderersForType(MAP, null); assertEquals(0, renderersForType.size()); renderersForType = rendererManager.getRenderersForType(MAP, MAP_REGIONS); assertEquals(0, renderersForType.size()); } @Test public void renderersForType2SubTypesTest() { List renderersForSubType = rendererManager.getRenderersForType(null, AREA); assertEquals(1, renderersForSubType.size()); renderersForSubType = rendererManager.getRenderersForType(null, LINE); assertEquals(2, renderersForSubType.size()); renderersForSubType = rendererManager.getRenderersForType(null, MAP_REGIONS); assertEquals(0, renderersForSubType.size()); } @Test public void rendererForTypeTest() { List renderers = rendererManager.getRenderers(); assertEquals(totalBeans, renderers.size()); assertEquals(2, rendererManager.getRenderersForType(BARCHART).size()); assertEquals(1, rendererManager.getRenderersForType(AREACHART).size()); } @Test public void rendererForSubTypeTest() { assertEquals(2, rendererManager.getRenderersForType(BARCHART).size()); assertEquals(1, rendererManager.getRenderersForType(AREACHART).size()); } @Test public void rendererByNameTest() { assertNotNull(rendererManager.getRendererByName(REND1_NAME)); } @Test(expected=RuntimeException.class) public void rendererByNameNotFoundTest() { assertNotNull(rendererManager.getRendererByName("NO NAME")); } @Test public void rendererByUUIDTest() { assertNotNull(rendererManager.getRendererByUUID(REND1_UUID)); } @Test(expected=RuntimeException.class) public void rendererByUUIDNotFoundTest() { assertNotNull(rendererManager.getRendererByUUID("NO UUID")); } @Test public void typeSupportedTest() { assertTrue(rendererManager.isTypeSupported(BARCHART)); assertTrue(!rendererManager.isTypeSupported(MAP)); } @Test public void rendererByDisplayerTest() { DisplayerSettings settings = mock(DisplayerSettings.class); when(settings.getRenderer()).thenReturn(REND1_UUID); when(settings.getType()).thenReturn(BARCHART); when(settings.getSubtype()).thenReturn(BAR); RendererLibrary lib = rendererManager.getRendererForDisplayer(settings); assertNotNull(lib); assertEquals(REND1_UUID, lib.getUUID()); } @Test public void rendererByDisplayerWithoutUUIDTest() { DisplayerSettings settings = mock(DisplayerSettings.class); when(settings.getType()).thenReturn(BARCHART); when(settings.getSubtype()).thenReturn(BAR); RendererLibrary lib = rendererManager.getRendererForDisplayer(settings); assertNotNull(lib); assertEquals(DEFAULT_REND_FOR_BARCHART_UUID, lib.getUUID()); } @Test(expected=RuntimeException.class) public void rendererByDisplayerTypeNotSupportedTest() { DisplayerSettings settings = mock(DisplayerSettings.class); when(settings.getType()).thenReturn(MAP); when(settings.getSubtype()).thenReturn(MAP_MARKERS); rendererManager.getRendererForDisplayer(settings); } @Test public void defaultRendererTest() { assertNotNull(rendererManager.getDefaultRenderer(BARCHART)); assertNull(rendererManager.getDefaultRenderer(LINECHART)); } @Test public void defaultRendererSetByUserTest() { when(rendererSettings.getDefaultRenderer()).thenReturn(REND2_UUID); rendererManager.init(); RendererLibrary barChartDefaultRenderer = rendererManager.getDefaultRenderer(BARCHART); RendererLibrary areaChartDefaultRenderer = rendererManager.getDefaultRenderer(AREACHART); RendererLibrary lineChartDefaultRenderer = rendererManager.getDefaultRenderer(LINECHART); assertEquals(REND2_UUID, barChartDefaultRenderer.getUUID()); assertNotNull(barChartDefaultRenderer); // now rend 2 becomes also default renderer for LINECHART, so it is not null assertNotNull(lineChartDefaultRenderer); // since rend 2 does not support areachart, so rend1 should still be the default renderer for it assertNotNull(areaChartDefaultRenderer); assertEquals(REND1_UUID, areaChartDefaultRenderer.getUUID()); } @Test public void defaultRendererWithUserBadSettingTest() { when(rendererSettings.getDefaultRenderer()).thenReturn("DO NO EXIST"); rendererManager.init(); defaultRendererTest(); } @Test public void offlineRendererTest() { when(rendererSettings.isOffline()).thenReturn(true); rendererManager.init(); assertEquals(1, rendererManager.getRenderers().size()); } private SyncBeanDef mockSyncBeanForRendererLib(String name, String uuid, List defaultTypes, Map> typesAndSubTypes, boolean offline) { SyncBeanDef libBean = mock(SyncBeanDef.class); RendererLibrary lib = mock(RendererLibrary.class); when(lib.getName()).thenReturn(name); when(lib.getUUID()).thenReturn(uuid); when(lib.isOffline()).thenReturn(offline); List supportedTypesList = typesAndSubTypes.keySet().stream().collect(Collectors.toList()); when(lib.getSupportedTypes()).thenReturn(supportedTypesList); typesAndSubTypes.forEach((type, subTypes) -> when(lib.getSupportedSubtypes(type)).thenReturn(subTypes)); defaultTypes.forEach(type -> when(lib.isDefault(type)).thenReturn(true)); when(libBean.getInstance()).thenReturn(lib); return libBean; } private void mockConstants() { rendererManager.i18n = mock(CommonConstants.class, (Answer) invocation -> { return RETURNS_DEFAULTS.answer(invocation); }); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/component/ExternalComponentDispatcherTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component; import java.util.HashSet; import java.util.Optional; import java.util.function.Consumer; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.displayer.client.component.function.ComponentFunctionLocator; import org.dashbuilder.displayer.client.resources.i18n.CommonConstants; import org.dashbuilder.displayer.external.ExternalComponentFunction; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.dashbuilder.displayer.external.ExternalComponentMessageType; import org.dashbuilder.displayer.external.ExternalFilterRequest; import org.dashbuilder.displayer.external.FunctionCallRequest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import static java.util.Optional.empty; import static java.util.Optional.of; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class ExternalComponentDispatcherTest { private static final String DEST1 = "DEST1"; @Mock ExternalComponentMessageHelper messageHelper; @Mock ComponentFunctionLocator functionLocator; @Mock ExternalComponentListener listener; @InjectMocks ExternalComponentDispatcher dispatcher; @Captor ArgumentCaptor> functionExecutionCaptor; @Before public void setup() { dispatcher.listeners = new HashSet<>(); when(listener.getId()).thenReturn(DEST1); dispatcher.register(listener); } @Test public void testFilterWithoutFilterRequest() { ExternalComponentMessage message = filterMessage(); withId(message, Optional.of(DEST1)); dispatcher.onMessage(message); verify(listener, times(0)).onFilter(any()); } @Test public void testFilterWithoutDestination() { ExternalComponentMessage message = filterMessage(); noId(message); dispatcher.onMessage(message); verify(listener, times(0)).onFilter(any()); } @Test public void testFilter() { ExternalFilterRequest filterRequest = mock(ExternalFilterRequest.class); Optional filterRequestOp = Optional.of(filterRequest); ExternalComponentMessage message = filterMessage(filterRequestOp); withId(message, Optional.of(DEST1)); dispatcher.onMessage(message); verify(listener).onFilter(eq(filterRequest)); } @Test public void testFunctionCallWithoutDestination() { ExternalComponentMessage message = functionCallMessage(); noId(message); dispatcher.onMessage(message); verify(functionLocator, times(0)).findFunctionByName(any()); } @Test public void testFunctionCallWithoutRequest() { ExternalComponentMessage message = functionCallMessage(); ExternalComponentMessage noRequestMessage = mock(ExternalComponentMessage.class); when(messageHelper.newFunctionRequestNotFound()).thenReturn(noRequestMessage); withId(message, of(DEST1)); dispatcher.onMessage(message); verify(functionLocator, times(0)).findFunctionByName(any()); verify(messageHelper).functionCallRequest(eq(message)); verify(listener).sendMessage(noRequestMessage); } @Test public void testFunctionCallFunctionNotFound() { FunctionCallRequest callRequest = mock(FunctionCallRequest.class); Optional callRequestOp = Optional.of(callRequest); ExternalComponentMessage message = functionCallMessage(callRequestOp); ExternalComponentMessage functionNotFoundMessage = mock(ExternalComponentMessage.class); String functionName = "f1"; when(callRequest.getFunctionName()).thenReturn(functionName); when(messageHelper.newFunctionNotFound(eq(callRequest))).thenReturn(functionNotFoundMessage); when(functionLocator.findFunctionByName(eq(functionName))).thenReturn(empty()); withId(message, of(DEST1)); dispatcher.onMessage(message); verify(messageHelper).functionCallRequest(eq(message)); verify(functionLocator).findFunctionByName(eq(functionName)); verify(listener).sendMessage(functionNotFoundMessage); } @Test public void testFunctionCallError() { ExternalComponentFunction function = mock(ExternalComponentFunction.class); FunctionCallRequest callRequest = mock(FunctionCallRequest.class); Optional callRequestOp = Optional.of(callRequest); ExternalComponentMessage message = functionCallMessage(callRequestOp); ExternalComponentMessage functionErrorMessage = mock(ExternalComponentMessage.class); String functionName = "f1"; String functionError = "error"; Mockito.doThrow(new RuntimeException(functionError)).when(function).exec(any(), any(), any()); when(callRequest.getFunctionName()).thenReturn(functionName); when(messageHelper.newFunctionError(eq(callRequest), eq(functionError))).thenReturn(functionErrorMessage); when(functionLocator.findFunctionByName(eq(functionName))).thenReturn(Optional.of(function)); withId(message, of(DEST1)); dispatcher.onMessage(message); verify(messageHelper).functionCallRequest(eq(message)); verify(functionLocator).findFunctionByName(eq(functionName)); verify(function).exec(any(), any(), any()); verify(listener).sendMessage(functionErrorMessage); } @Test public void testFunctionCallSuccess() { ExternalComponentFunction function = mock(ExternalComponentFunction.class); FunctionCallRequest callRequest = mock(FunctionCallRequest.class); Optional callRequestOp = Optional.of(callRequest); ExternalComponentMessage message = functionCallMessage(callRequestOp); ExternalComponentMessage functionSuccessMessage = mock(ExternalComponentMessage.class); String functionName = "f1"; String result = "success"; when(callRequest.getFunctionName()).thenReturn(functionName); when(messageHelper.newFunctionSuccess(eq(callRequest), eq(result))).thenReturn(functionSuccessMessage); when(functionLocator.findFunctionByName(eq(functionName))).thenReturn(Optional.of(function)); withId(message, of(DEST1)); dispatcher.onMessage(message); verify(messageHelper).functionCallRequest(eq(message)); verify(functionLocator).findFunctionByName(eq(functionName)); verify(function).exec(any(), functionExecutionCaptor.capture(), any()); functionExecutionCaptor.getValue().accept(result); verify(messageHelper).newFunctionSuccess(eq(callRequest), eq(result)); verify(listener).sendMessage(eq(functionSuccessMessage)); } @Test public void testFixConfigurationWithoutMessage() { ExternalComponentMessage configurationIssueMsg = mock(ExternalComponentMessage.class); withId(configurationIssueMsg, Optional.of(DEST1)); when(messageHelper.messageType(eq(configurationIssueMsg))).thenReturn(ExternalComponentMessageType.FIX_CONFIGURATION); when(messageHelper.getConfigurationIssue(eq(configurationIssueMsg))).thenReturn(empty()); dispatcher.onMessage(configurationIssueMsg); verify(listener).onConfigurationIssue(CommonConstants.INSTANCE.componentConfigDefaultMessage()); } @Test public void testFixConfigurationWithMessage() { ExternalComponentMessage configurationIssueMsg = mock(ExternalComponentMessage.class); String configurationMessage = "config error"; withId(configurationIssueMsg, Optional.of(DEST1)); when(messageHelper.messageType(eq(configurationIssueMsg))).thenReturn(ExternalComponentMessageType.FIX_CONFIGURATION); when(messageHelper.getConfigurationIssue(eq(configurationIssueMsg))).thenReturn(Optional.of(configurationMessage)); dispatcher.onMessage(configurationIssueMsg); verify(listener).onConfigurationIssue(configurationMessage); } @Test public void testOkConfigurationWithMessage() { ExternalComponentMessage configurationOkMsg = mock(ExternalComponentMessage.class); withId(configurationOkMsg, Optional.of(DEST1)); when(messageHelper.messageType(eq(configurationOkMsg))).thenReturn(ExternalComponentMessageType.CONFIGURATION_OK); dispatcher.onMessage(configurationOkMsg); verify(listener).configurationOk(); } private void noId(ExternalComponentMessage message) { withId(message, empty()); } private ExternalComponentMessage filterMessage() { return filterMessage(empty()); } private ExternalComponentMessage functionCallMessage() { return functionCallMessage(empty()); } private void withId(ExternalComponentMessage message, Optional id) { when(messageHelper.getComponentId(eq(message))).thenReturn(id); } private ExternalComponentMessage filterMessage(Optional filterRequestOp) { ExternalComponentMessage message = Mockito.mock(ExternalComponentMessage.class); when(messageHelper.messageType(eq(message))).thenReturn(ExternalComponentMessageType.FILTER); when(messageHelper.filterRequest(eq(message))).thenReturn(filterRequestOp); return message; } private ExternalComponentMessage functionCallMessage(Optional callRequestOp) { ExternalComponentMessage message = Mockito.mock(ExternalComponentMessage.class); when(messageHelper.messageType(eq(message))).thenReturn(ExternalComponentMessageType.FUNCTION_CALL); when(messageHelper.functionCallRequest(eq(message))).thenReturn(callRequestOp); return message; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/component/function/ComponentFunctionLocatorTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.component.function; import java.util.Collections; import java.util.Optional; import org.dashbuilder.displayer.external.ExternalComponentFunction; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class ComponentFunctionLocatorTest { private final String F1_NAME = "f1"; private ExternalComponentFunction f1; private ComponentFunctionLocator locator; @Before public void prepare() { locator = new ComponentFunctionLocator(); f1 = mock(ExternalComponentFunction.class); when(f1.getName()).thenReturn(F1_NAME); locator.functions = Collections.singletonList(f1); } @Test public void testFindFunctionByName() { Optional result = locator.findFunctionByName(F1_NAME); assertEquals(f1, result.get()); } @Test public void testFindFunctionByNameNotFound() { Optional result = locator.findFunctionByName("not found"); assertFalse(result.isPresent()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/DataSetLookupEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Arrays; import java.util.List; import javax.enterprise.event.Event; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.DataSetLookupFactory; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetMetadataCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.def.DataSetDefFactory; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.dataset.impl.DataSetMetadataImpl; import org.dashbuilder.displayer.client.events.DataSetLookupChangedEvent; import org.dashbuilder.displayer.client.events.GroupFunctionChangedEvent; import org.dashbuilder.displayer.client.events.GroupFunctionDeletedEvent; import org.dashbuilder.displayer.client.widgets.filter.DataSetFilterEditor; import org.dashbuilder.displayer.client.widgets.group.ColumnFunctionEditor; import org.dashbuilder.displayer.client.widgets.group.DataSetGroupDateEditor; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import static org.dashbuilder.dataset.filter.FilterFactory.*; import static org.dashbuilder.dataset.ColumnType.*; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class DataSetLookupEditorTest { public static final String POPULATION_UUID = "population"; public static final String REVENUE_UUID = "revenue"; public static final DataSetDef POPULATION_DSET = DataSetDefFactory.newStaticDataSetDef() .uuid(POPULATION_UUID) .name("Population") .label("continent") .label("country") .number("population") .date("year") .buildDef(); public static final DataSetDef REVENUE_DSET = DataSetDefFactory.newStaticDataSetDef() .uuid(REVENUE_UUID) .name("Revenue") .label("company") .label("sector") .number("revenue") .date("year") .buildDef(); public static final List DATA_SET_LIST = Arrays.asList(POPULATION_DSET, REVENUE_DSET); public static final DataSetMetadata POPULATION_META = new DataSetMetadataImpl( POPULATION_DSET, POPULATION_UUID, 0, 4, Arrays.asList("continent", "country", "population", "year"), Arrays.asList(LABEL, LABEL, NUMBER, DATE), 0); public static final DataSetMetadata REVENUE_META = new DataSetMetadataImpl( POPULATION_DSET, REVENUE_UUID, 0, 4, Arrays.asList("company", "sector", "revenue", "year"), Arrays.asList(LABEL, LABEL, NUMBER, DATE), 0); public static final DataSetLookupConstraints DATA_2D_MULTIPLE = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(10) .setMinColumns(2) .setExtraColumnsAllowed(true) .setExtraColumnsType(ColumnType.NUMBER) .setGroupsTitle("Categories") .setColumnsTitle("Series") .setColumnTypes(new ColumnType[]{ LABEL, NUMBER}); public static final DataSetLookupConstraints DATA_2D_FIXED = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(2) .setMinColumns(2) .setExtraColumnsAllowed(false) .setGroupsTitle("Categories") .setColumnsTitle("Series") .setColumnTypes(new ColumnType[]{ LABEL, NUMBER}); public static final DataSetLookupConstraints DATA_MULTIPLE = new DataSetLookupConstraints() .setGroupAllowed(true) .setGroupRequired(false) .setMaxColumns(-1) .setMinColumns(1) .setExtraColumnsAllowed(true) .setGroupsTitle("Rows") .setColumnsTitle("Columns") .setColumnTypes(new ColumnType[]{ LABEL, NUMBER}); public static final DataSetLookupConstraints DATA_MULTIPLE_NO_GROUP = new DataSetLookupConstraints() .setGroupAllowed(false) .setGroupRequired(false) .setMaxColumns(-1) .setMinColumns(1) .setExtraColumnsAllowed(true) .setGroupsTitle("Rows") .setColumnsTitle("Columns") .setColumnTypes(new ColumnType[]{ LABEL, NUMBER}); @Mock DataSetLookupEditor.View view; @Mock Event event; @Mock SyncBeanManager beanManager; @Mock SyncBeanDef columnFunctionEditorBeanDef; @Mock ColumnFunctionEditor columnFunctionEditor; @Mock DataSetFilterEditor filterEditor; @Mock DataSetGroupDateEditor groupDateEditor; @Mock DataSetClientServices clientServices; DataSetLookupEditor presenter = null; @Before public void init() throws Exception { presenter = new DataSetLookupEditor(view, beanManager, filterEditor, groupDateEditor, clientServices, event); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocationOnMock) throws Throwable { RemoteCallback> callback = (RemoteCallback>) invocationOnMock.getArguments()[0]; callback.callback(DATA_SET_LIST); return null; } }).when(clientServices).getPublicDataSetDefs(any(RemoteCallback.class)); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocationOnMock) throws Throwable { DataSetMetadataCallback callback = (DataSetMetadataCallback) invocationOnMock.getArguments()[1]; callback.callback(POPULATION_META); return null; } }).when(clientServices).fetchMetadata(eq(POPULATION_UUID), any(DataSetMetadataCallback.class)); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocationOnMock) throws Throwable { DataSetMetadataCallback callback = (DataSetMetadataCallback) invocationOnMock.getArguments()[1]; callback.callback(REVENUE_META); return null; } }).when(clientServices).fetchMetadata(eq(REVENUE_UUID), any(DataSetMetadataCallback.class)); when(beanManager.lookupBean(ColumnFunctionEditor.class)).thenReturn(columnFunctionEditorBeanDef); when(columnFunctionEditorBeanDef.newInstance()).thenReturn(columnFunctionEditor); } @Test public void testNonExistingLookup() { presenter.init(DATA_2D_FIXED, null); verify(view).clearDataSetSelector(); verify(view).enableDataSetSelectorHint(); verify(view).addDataSetItem("Population", POPULATION_UUID); verify(view).addDataSetItem("Revenue", REVENUE_UUID); verify(view, never()).setSelectedDataSetIndex(anyInt()); verify(view, never()).setFilterEnabled(true); verify(view, never()).setGroupEnabled(true); verify(view, never()).setColumnsSectionEnabled(true); verify(view, never()).setAddColumnOptionEnabled(true); } @Test public void testExistingLookup() { presenter.init(DATA_2D_FIXED, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .filter(greaterThan(100)) .group("country") .column("country", "Country") .column("population", AggregateFunctionType.SUM, "Total") .buildLookup()); verify(view).clearDataSetSelector(); verify(view, never()).enableDataSetSelectorHint(); verify(view).addDataSetItem("Population", POPULATION_UUID); verify(view).addDataSetItem("Revenue", REVENUE_UUID); verify(view, times(1)).setSelectedDataSetIndex(anyInt()); verify(view).setFilterEnabled(true); verify(filterEditor).init(presenter.getDataSetLookup().getFirstFilterOp(), POPULATION_META); verify(view).setGroupEnabled(true); verify(view, never()).setGroupByDateEnabled(true); verify(view).setGroupColumnSelectorTitle("Categories"); verify(view, never()).enableGroupColumnSelectorHint(); verify(groupDateEditor, never()).init(any(ColumnGroup.class)); verify(view).clearGroupColumnSelector(); verify(view).addGroupColumnItem("continent"); verify(view).addGroupColumnItem("country"); verify(view).addGroupColumnItem("year"); verify(view).addGroupColumnItem("population"); verify(view).setColumnsSectionEnabled(true); verify(view, never()).setGroupByDateEnabled(true); verify(view).setColumnSectionTitle("Series"); verify(view).setAddColumnOptionEnabled(false); verify(view, never()).setAddColumnOptionEnabled(true); GroupFunction gf = presenter.getFirstGroupFunctions().get(1); verify(columnFunctionEditor).init(POPULATION_META, gf, NUMBER, null, true, false); verify(view).addColumnEditor(any(ColumnFunctionEditor.class)); } @Test public void testFromNonExistingLookup() { presenter.init(DATA_2D_FIXED, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .filter(greaterThan(100)) .group("country") .column("country", "Country") .column("population", AggregateFunctionType.SUM, "Total") .buildLookup()); verify(view, never()).enableDataSetSelectorHint(); reset(view); presenter.init(DATA_2D_FIXED, null); verify(view).enableDataSetSelectorHint(); } @Test public void testDataSetDefFilter() { presenter.setDataSetDefFilter(new DataSetLookupEditor.DataSetDefFilter() { public boolean accept(DataSetDef def) { return def.getUUID().equals(REVENUE_UUID); } }); presenter.init(DATA_2D_FIXED, null); verify(view).clearDataSetSelector(); verify(view, never()).addDataSetItem("Population", POPULATION_UUID); verify(view).addDataSetItem("Revenue", REVENUE_UUID); } @Test public void testDateGroup() { presenter.init(DATA_2D_FIXED, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .filter(greaterThan(100)) .group("year") .column("year", "Year") .column("population", AggregateFunctionType.SUM, "Total") .buildLookup()); verify(view).setGroupEnabled(true); verify(view).setGroupByDateEnabled(true); verify(view, never()).enableGroupColumnSelectorHint(); verify(groupDateEditor).init(any(ColumnGroup.class)); } @Test public void testGroupAllowed() { presenter.init(DATA_MULTIPLE, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .column("year") .column("population") .buildLookup()); verify(view).setGroupEnabled(true); verify(view).enableGroupColumnSelectorHint(); verify(view).setAddColumnOptionEnabled(true); verify(event, never()).fire(any(DataSetLookupChangedEvent.class)); } @Test public void testDeleteColumns() { DataSetLookup lookup = DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .column("year") .column("population") .buildLookup(); GroupFunction year = lookup.getLastGroupOp().getGroupFunction("year"); presenter.init(DATA_MULTIPLE, lookup); reset(view); presenter.onColumnFunctionDeleted(new GroupFunctionDeletedEvent(year)); verify(view).clearColumnList(); verify(view, times(1)).addColumnEditor(any(ColumnFunctionEditor.class)); verify(event).fire(any(DataSetLookupChangedEvent.class)); } @Test public void testGroupNotAllowed() { presenter.init(DATA_MULTIPLE_NO_GROUP, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .column("year") .column("population") .buildLookup()); verify(view, never()).setGroupEnabled(true); verify(view, never()).enableGroupColumnSelectorHint(); verify(event, never()).fire(any(DataSetLookupChangedEvent.class)); } @Test public void testAutoCreateRequiredGroup() { presenter.init(DATA_2D_FIXED, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .filter(greaterThan(100)) .column("country") .column("population", AggregateFunctionType.SUM) .buildLookup()); assertEquals(presenter.getFirstGroupColumnId(), "continent"); verify(event).fire(any(DataSetLookupChangedEvent.class)); } @Test public void testDataSetSelected() { presenter.init(DATA_2D_FIXED, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .group("country") .column("country") .column("population", AggregateFunctionType.SUM) .buildLookup()); when(view.getSelectedDataSetId()).thenReturn(REVENUE_UUID); presenter.onDataSetSelected(); verify(event).fire(any(DataSetLookupChangedEvent.class)); DataSetLookup newLookup = presenter.getDataSetLookup(); assertEquals(newLookup.getDataSetUUID(), REVENUE_UUID); assertEquals(presenter.getFirstGroupColumnId(), "company"); assertEquals(presenter.getFirstGroupFunctions().size(), 2); assertEquals(presenter.getFirstGroupFunctions().get(0).getSourceId(), "company"); assertEquals(presenter.getFirstGroupFunctions().get(1).getSourceId(), "revenue"); assertEquals(presenter.getFirstGroupFunctions().get(0).getFunction(), null); assertEquals(presenter.getFirstGroupFunctions().get(1).getFunction(), AggregateFunctionType.SUM); } @Test public void testGroupColumnSelected() { presenter.init(DATA_2D_FIXED, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .group("country") .column("country") .column("population", AggregateFunctionType.SUM) .buildLookup()); when(view.getSelectedGroupColumnId()).thenReturn("continent"); presenter.onGroupColumnSelected(); verify(event).fire(any(DataSetLookupChangedEvent.class)); assertEquals(presenter.getFirstGroupColumnId(), "continent"); assertEquals(presenter.getFirstGroupFunctions().size(), 2); assertEquals(presenter.getFirstGroupFunctions().get(0).getSourceId(), "continent"); assertEquals(presenter.getFirstGroupFunctions().get(1).getSourceId(), "population"); assertEquals(presenter.getFirstGroupFunctions().get(0).getFunction(), null); assertEquals(presenter.getFirstGroupFunctions().get(1).getFunction(), AggregateFunctionType.SUM); } @Test public void testGroupColumnDeselected() { presenter.init(DATA_MULTIPLE, DataSetLookupFactory.newDataSetLookupBuilder() .dataset(POPULATION_UUID) .group("country") .column("country") .column("population", AggregateFunctionType.SUM) .buildLookup()); when(view.getSelectedGroupColumnId()).thenReturn(null); presenter.onGroupColumnSelected(); verify(event).fire(any(DataSetLookupChangedEvent.class)); assertEquals(presenter.getFirstGroupColumnId(), null); assertEquals(presenter.getFirstGroupFunctions().size(), 2); assertEquals(presenter.getFirstGroupFunctions().get(0).getSourceId(), "country"); assertEquals(presenter.getFirstGroupFunctions().get(1).getSourceId(), "population"); assertEquals(presenter.getFirstGroupFunctions().get(0).getFunction(), null); assertEquals(presenter.getFirstGroupFunctions().get(1).getFunction(), null); } @Test public void testAddColumns() { DataSetLookup lookup = DATA_2D_MULTIPLE.newDataSetLookup(POPULATION_META); presenter.init(DATA_2D_MULTIPLE, lookup); verify(view).setAddColumnOptionEnabled(true); presenter.onAddColumn(); verify(event).fire(any(DataSetLookupChangedEvent.class)); assertEquals(presenter.getFirstGroupFunctions().size(), 3); assertEquals(presenter.getFirstGroupFunctions().get(2).getSourceId(), "population"); assertEquals(presenter.getFirstGroupFunctions().get(2).getColumnId(), "population_2"); assertEquals(presenter.getFirstGroupFunctions().get(2).getFunction(), AggregateFunctionType.SUM); presenter.onAddColumn(); assertEquals(presenter.getFirstGroupFunctions().size(), 4); assertEquals(presenter.getFirstGroupFunctions().get(3).getSourceId(), "population"); assertEquals(presenter.getFirstGroupFunctions().get(3).getColumnId(), "population_3"); assertEquals(presenter.getFirstGroupFunctions().get(3).getFunction(), AggregateFunctionType.SUM); reset(event); GroupFunction gf = new GroupFunction("population", "population_2", AggregateFunctionType.SUM); presenter.onColumnFunctionDeleted(new GroupFunctionDeletedEvent(gf)); verify(event).fire(any(DataSetLookupChangedEvent.class)); assertEquals(presenter.getFirstGroupFunctions().size(), 3); assertEquals(presenter.getFirstGroupFunctions().get(2).getSourceId(), "population"); assertEquals(presenter.getFirstGroupFunctions().get(2).getColumnId(), "population_3"); assertEquals(presenter.getFirstGroupFunctions().get(2).getFunction(), AggregateFunctionType.SUM); presenter.onAddColumn(); assertEquals(presenter.getFirstGroupFunctions().size(), 4); assertEquals(presenter.getFirstGroupFunctions().get(3).getSourceId(), "population"); assertEquals(presenter.getFirstGroupFunctions().get(3).getColumnId(), "population_2"); assertEquals(presenter.getFirstGroupFunctions().get(3).getFunction(), AggregateFunctionType.SUM); } @Test public void testColumnChanged() { DataSetLookup lookup = DATA_2D_MULTIPLE.newDataSetLookup(POPULATION_META); presenter.init(DATA_2D_MULTIPLE, lookup); GroupFunction gf = new GroupFunction("population", "population", AggregateFunctionType.SUM); presenter.onColumnFunctionChanged(new GroupFunctionChangedEvent(gf)); assertEquals(gf.getColumnId(), "population_2"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/DisplayerEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Arrays; import javax.enterprise.event.Event; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.uuid.UUIDGenerator; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.displayer.client.RendererLibrary; import org.dashbuilder.displayer.client.RendererManager; import org.dashbuilder.displayer.client.events.DataSetLookupChangedEvent; import org.dashbuilder.displayer.client.events.DisplayerEditorClosedEvent; import org.dashbuilder.displayer.client.events.DisplayerEditorSavedEvent; import org.dashbuilder.displayer.client.events.DisplayerSettingsChangedEvent; import org.dashbuilder.displayer.client.prototypes.DisplayerPrototypes; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class DisplayerEditorTest { @Mock DisplayerEditor.View view; @Mock DataSetClientServices clientServices; @Mock RendererManager rendererManager; @Mock RendererLibrary rendererLibrary; @Mock DisplayerLocator displayerLocator; @Mock DisplayerTypeSelector typeSelector; @Mock DataSetLookupEditor lookupEditor; @Mock DisplayerSettingsEditor settingsEditor; @Mock DisplayerEditorStatus editorStatus; @Mock Event saveEvent; @Mock Event closeEvent; @Mock DisplayerSettings displayerSettings; @Mock DisplayerSettings tableSettings; @Mock Displayer displayer; @Mock DisplayerHtmlEditor displayerHtmlEditor; @Mock Displayer tableDisplayer; @Mock UUIDGenerator uuidGenerator; @Mock DisplayerPrototypes displayerPrototypes; @Mock DisplayerConstraints displayerConstraints; @Mock DataSetLookupConstraints lookupConstraints; @Mock DisplayerSettingsChangedEvent displayerSettingsChangedEvent; @Mock ExternalComponentPropertiesEditor componentPropertiesEditor; @Mock Event displayerSettingsChangedEventSource; DisplayerEditor presenter = null; @Before public void init() throws Exception { when(displayerPrototypes.getProto(any(), any())).thenReturn(displayerSettings); when(displayerSettings.cloneInstance()).thenReturn(tableSettings); when(displayerLocator.lookupDisplayer(displayerSettings)).thenReturn(displayer); when(displayerLocator.lookupDisplayer(tableSettings)).thenReturn(tableDisplayer); when(displayer.getDisplayerConstraints()).thenReturn(displayerConstraints); when(displayerConstraints.getDataSetLookupConstraints()).thenReturn(lookupConstraints); when(rendererManager.getDefaultRenderer(any())).thenReturn(rendererLibrary); presenter = new DisplayerEditor(view, clientServices, displayerLocator, displayerPrototypes, typeSelector, lookupEditor, settingsEditor, editorStatus, displayerHtmlEditor, saveEvent, closeEvent, rendererManager, componentPropertiesEditor, displayerSettingsChangedEventSource); } @Test public void testBrandNewDisplayer() { when(view.getBrandNewDisplayerTitle()).thenReturn("New displayer"); presenter.setDisplayerType(DisplayerType.SELECTOR); presenter.setDisplayerSubType(DisplayerSubType.SELECTOR_DROPDOWN); presenter.init(null); assertEquals(presenter.isBrandNewDisplayer(), true); verify(displayerSettings).setTitle("New displayer"); verify(displayerPrototypes).getProto(DisplayerType.SELECTOR, DisplayerSubType.SELECTOR_DROPDOWN); verify(displayerLocator).lookupDisplayer(displayerSettings); verify(displayer).draw(); verify(typeSelector).init(any(), any()); verify(lookupEditor).init(lookupConstraints, null); verify(settingsEditor).init(displayer); verify(view).showDisplayer(displayer); } @Test public void testNavigation() { presenter.setTypeSelectorEnabled(true); presenter.setDataSetLookupConfEnabled(true); presenter.setDisplaySettingsEnabled(true); // Default when(editorStatus.getSelectedOption(any())).thenReturn(-1); presenter.init(null); verify(view).goToTypeSelection(typeSelector); // Type selector when(editorStatus.getSelectedOption(any())).thenReturn(0); presenter.init(null); verify(view).goToTypeSelection(typeSelector); // Data lookup conf when(editorStatus.getSelectedOption(any())).thenReturn(1); presenter.init(null); verify(view).goToDataSetLookupConf(lookupEditor); // Display settings when(editorStatus.getSelectedOption(any())).thenReturn(2); presenter.init(null); verify(view).goToDisplaySettings(settingsEditor); } @Test public void testTypeSelectorDisabled() { presenter.setTypeSelectorEnabled(false); presenter.setDataSetLookupConfEnabled(true); presenter.setDisplaySettingsEnabled(true); when(editorStatus.getSelectedOption(any())).thenReturn(-1); presenter.init(null); verify(view).goToDataSetLookupConf(lookupEditor); verify(view, never()).goToTypeSelection(typeSelector); verify(view, never()).goToDisplaySettings(settingsEditor); } @Test public void testDataLookupConfDisabled() { presenter.setTypeSelectorEnabled(false); presenter.setDataSetLookupConfEnabled(false); presenter.setDisplaySettingsEnabled(true); when(editorStatus.getSelectedOption(any())).thenReturn(-1); presenter.init(null); verify(view, never()).goToDataSetLookupConf(lookupEditor); verify(view, never()).goToTypeSelection(typeSelector); verify(view).goToDisplaySettings(settingsEditor); } @Test public void testTableModeAvailable() { for (DisplayerType type : Arrays.asList( DisplayerType.BARCHART, DisplayerType.LINECHART, DisplayerType.PIECHART, DisplayerType.AREACHART, DisplayerType.BUBBLECHART, DisplayerType.METERCHART, DisplayerType.METRIC, DisplayerType.MAP)) { reset(view); when(displayerSettings.getType()).thenReturn(type); presenter.init(null); presenter.gotoDataSetLookupConf(); verify(view).setTableDisplayModeEnabled(true); } } @Test public void testTableModeNotAvailable() { when(displayerSettings.getType()).thenReturn(DisplayerType.TABLE); presenter.init(null); presenter.gotoDataSetLookupConf(); verify(view).setTableDisplayModeEnabled(false); verify(view, never()).setTableDisplayModeEnabled(true); } @Test public void testTableMode() { when(view.isTableDisplayModeOn()).thenReturn(true); presenter.init(null); verify(tableDisplayer).draw(); verify(view).showDisplayer(tableDisplayer); } @Test public void testDataLookupChanged() { DisplayerSettings settings1 = DisplayerSettingsFactory.newPieChartSettings() .uuid("test1") .dataset("test") .group("employee") .column("employee").format("Employee") .column(AggregateFunctionType.COUNT, "#items").format("#Items") .buildSettings(); DisplayerSettings settings2 = DisplayerSettingsFactory.newPieChartSettings() .uuid("test2") .dataset("test") .group("department") .column("department").format("Department") .column("amount", AggregateFunctionType.SUM).format("Total amount") .buildSettings(); when(displayerLocator.lookupDisplayer(any())).thenReturn(displayer); presenter.init(settings1); assertEquals(presenter.getDisplayerSettings().getColumnSettingsList().size(), 2); reset(settingsEditor); presenter.onDataSetLookupChanged(new DataSetLookupChangedEvent(settings2.getDataSetLookup())); verify(settingsEditor).init(any()); assertEquals(presenter.getDisplayerSettings().getColumnSettingsList().size(), 0); } @Test public void rendererSettingChangedTest() { String otherRenderer = "otherRenderer"; when(displayerSettingsChangedEvent.getDisplayerSettings()).thenReturn(displayerSettings); presenter.onDisplayerSettingsChanged(displayerSettingsChangedEvent); verify(settingsEditor, times(0)).init(any()); when(displayerSettings.getRenderer()).thenReturn(otherRenderer); presenter.onDisplayerSettingsChanged(displayerSettingsChangedEvent); verify(settingsEditor).init(any()); assertEquals(otherRenderer, presenter.getCurrentRenderer()); reset(displayerSettings); when(displayerSettings.getRenderer()).thenReturn(null); presenter.onDisplayerSettingsChanged(displayerSettingsChangedEvent); assertEquals(otherRenderer, presenter.getCurrentRenderer()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/DisplayerHtmlEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.HashSet; import java.util.Set; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.widgets.sourcecode.SourceCodeEditor; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DisplayerHtmlEditorTest { @Mock DisplayerHtmlEditor.View view; @Mock SourceCodeEditor codeEditor; @Mock DisplayerConstraints constraints; @Mock Displayer displayer; DisplayerHtmlEditor presenter; @Before public void init() throws Exception { Set supportedAttrs = new HashSet<>(); supportedAttrs.add(DisplayerAttributeDef.HTML_TEMPLATE); supportedAttrs.add(DisplayerAttributeDef.JS_TEMPLATE); when(constraints.getSupportedAttributes()).thenReturn(supportedAttrs); when(displayer.getDisplayerConstraints()).thenReturn(constraints); presenter = new DisplayerHtmlEditor(view, codeEditor); presenter.setDisplayer(displayer); } @Test public void testInit() { verify(view).showDisplayer(displayer); verify(codeEditor, never()).init(any(), any(), any(), any()); } @Test public void testSourceCodeItems() { verify(view).addSourceCodeItem("html"); verify(view).addSourceCodeItem("javascript"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/DisplayerSettingsEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Arrays; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.Position; import org.dashbuilder.displayer.client.DataSetHandler; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.displayer.client.RendererLibrary; import org.dashbuilder.displayer.client.RendererManager; import org.dashbuilder.displayer.client.events.DisplayerSettingsChangedEvent; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.uberfire.ext.properties.editor.model.validators.PropertyFieldValidator; import org.uberfire.mocks.EventSourceMock; import static org.dashbuilder.displayer.DisplayerAttributeDef.*; import static org.dashbuilder.displayer.DisplayerAttributeGroupDef.*; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DisplayerSettingsEditorTest { @Mock DisplayerSettingsEditor.View view; @Mock Displayer displayer; @Mock DataSetHandler dataSetHandler; @Mock EventSourceMock event; @Mock DisplayerLocator displayerLocator; @Mock RendererManager rendererManager; @Mock RendererLibrary rendererA; @Mock RendererLibrary rendererB; DisplayerSettingsEditor presenter; @Before public void init() throws Exception { when(rendererManager.getRenderersForType(any(DisplayerType.class))).thenReturn(Arrays.asList(rendererA, rendererB)); when(rendererA.getUUID()).thenReturn("rendererA"); when(rendererB.getUUID()).thenReturn("rendererB"); when(rendererManager.getRendererForDisplayer(any(DisplayerSettings.class))).thenReturn(rendererB); when(displayer.getDataSetHandler()).thenReturn(dataSetHandler); when(displayer.getDisplayerConstraints()).thenReturn(new DisplayerConstraints(null) .supportsAttribute(TYPE) .supportsAttribute(SUBTYPE) .supportsAttribute(RENDERER) .supportsAttribute(GENERAL_GROUP) .supportsAttribute(COLUMNS_GROUP) .supportsAttribute(REFRESH_GROUP) .supportsAttribute(FILTER_GROUP) .supportsAttribute(CHART_GROUP) .supportsAttribute(TABLE_GROUP) .supportsAttribute(AXIS_GROUP) .supportsAttribute(METER_GROUP)); presenter = new DisplayerSettingsEditor(view, displayerLocator, rendererManager, event); // Call to init implies calling to presenter.show() internally doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocationOnMock) throws Throwable { presenter.show(); return null; } }).when(dataSetHandler).lookupDataSet(any(DataSetReadyCallback.class)); } @Test public void testGeneralSettings() { when(dataSetHandler.getLastDataSet()).thenReturn(DataSetFactory.newDataSetBuilder() .label("dept") .number("amount") .buildDataSet()); when(displayer.getDisplayerSettings()).thenReturn(DisplayerSettingsFactory.newBarChartSettings() .dataset("dset") .group("dept") .column("dept").format("Department") .column("amount").format("Total", "#.##0").expression("value/100") .title("Sales by dept") .titleVisible(true) .legendOn(Position.BOTTOM) .width(400).height(200) .xAxisTitle("Depts") .yAxisTitle("Amount $") .margins(10, 80, 80, 100) .filterOn(false, true, true) .refreshOn(3, false) .buildSettings()); // Call to init implies calling to presenter.show() internally (see above) presenter.init(displayer); verify(view).clear(); verify(view).addTextProperty(TITLE, "Sales by dept"); verify(view).addBooleanProperty(TITLE_VISIBLE, true); verify(view, never()).addBooleanProperty(EXPORT_TO_CSV, false); verify(view, never()).addBooleanProperty(EXPORT_TO_XLS, false); verify(view).addTextProperty(eq(CHART_WIDTH), eq("400"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addTextProperty(eq(CHART_HEIGHT), eq("200"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addColorProperty(eq(CHART_BGCOLOR), anyString()); verify(view).addBooleanProperty(CHART_3D, false); verify(view).addTextProperty(eq(CHART_MARGIN_TOP), eq("10"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addTextProperty(eq(CHART_MARGIN_BOTTOM), eq("80"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addTextProperty(eq(CHART_MARGIN_LEFT), eq("80"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addTextProperty(eq(CHART_MARGIN_RIGHT), eq("100"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addBooleanProperty(CHART_SHOWLEGEND, true); verify(view).addListProperty(eq(CHART_LEGENDPOSITION), anyList(), any()); verify(view).addBooleanProperty(XAXIS_SHOWLABELS, true); verify(view).addTextProperty(XAXIS_LABELSANGLE, "0"); verify(view).addTextProperty(XAXIS_TITLE, "Depts"); verify(view).addBooleanProperty(YAXIS_SHOWLABELS, true); verify(view).addTextProperty(YAXIS_TITLE, "Amount $"); verify(view).addBooleanProperty(FILTER_ENABLED, true); verify(view).addBooleanProperty(FILTER_SELFAPPLY_ENABLED, false); verify(view).addBooleanProperty(FILTER_NOTIFICATION_ENABLED, true); verify(view).addBooleanProperty(FILTER_LISTENING_ENABLED, true); verify(view).addTextProperty(eq(REFRESH_INTERVAL), eq("3"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addBooleanProperty(REFRESH_STALE_DATA, false); verify(view).addTextProperty(eq("columns.dept.name"), anyString(), eq("Department")); verify(view).addTextProperty(eq("columns.amount.name"), anyString(), eq("Total")); verify(view).addTextProperty(eq("columns.amount.expression"), anyString(), eq("value/100")); verify(view).addTextProperty(eq("columns.amount.pattern"), anyString(), eq("#.##0")); verify(view).show(); } @Test public void testChangeAttributes() { DisplayerSettings settings = DisplayerSettingsFactory.newBarChartSettings().buildSettings(); when(displayer.getDisplayerSettings()).thenReturn(settings); presenter.init(displayer); presenter.onAttributeChanged(TITLE.getFullId(), "Test"); presenter.onAttributeChanged(TITLE_VISIBLE.getFullId(), "true"); presenter.onAttributeChanged(EXPORT_TO_CSV.getFullId(), "false"); presenter.onAttributeChanged(EXPORT_TO_XLS.getFullId(), "false"); presenter.onAttributeChanged(CHART_HEIGHT.getFullId(), "400"); presenter.onAttributeChanged("columns.amount.name", "Total"); presenter.onAttributeChanged("columns.amount.pattern", "#.###,00"); presenter.onAttributeChanged("columns.amount.expression", "value"); assertEquals(settings.getTitle(), "Test"); assertEquals(settings.isTitleVisible(), true); assertEquals(settings.isCSVExportAllowed(), false); assertEquals(settings.isExcelExportAllowed(), false); assertEquals(settings.getChartHeight(), 400); assertEquals(settings.getColumnSettings("amount").getColumnName(), "Total"); assertEquals(settings.getColumnSettings("amount").getValuePattern(), "#.###,00"); assertEquals(settings.getColumnSettings("amount").getValueExpression(), "value"); verify(event, atLeastOnce()).fire(any(DisplayerSettingsChangedEvent.class)); } @Test public void testTableSettings() { when(dataSetHandler.getLastDataSet()).thenReturn(DataSetFactory.newDataSetBuilder() .label("dept") .date("date") .number("amount") .buildDataSet()); when(displayer.getDisplayerConstraints()).thenReturn( new DisplayerConstraints(null) .supportsAttribute(TABLE_GROUP) .supportsAttribute(EXPORT_GROUP)); when(displayer.getDisplayerSettings()).thenReturn(DisplayerSettingsFactory.newTableSettings() .tablePageSize(10) .tableWidth(500) .tableOrderEnabled(true) .tableOrderDefault("date", SortOrder.ASCENDING) .tableColumnPickerEnabled(false) .allowCsvExport(true) .allowExcelExport(false) .buildSettings()); presenter.init(displayer); verify(view).clear(); verify(view).addTextProperty(eq(TABLE_WIDTH), eq("500"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addBooleanProperty(TABLE_SORTENABLED, true); verify(view).addListProperty(eq(TABLE_SORTCOLUMNID), anyListOf(String.class), eq("date")); verify(view).addListProperty(eq(TABLE_SORTORDER), anyListOf(String.class), eq(SortOrder.ASCENDING.toString())); verify(view).addBooleanProperty(TABLE_COLUMN_PICKER_ENABLED, false); verify(view).addBooleanProperty(EXPORT_TO_CSV, true); verify(view).addBooleanProperty(EXPORT_TO_XLS, false); verify(view).show(); } @Test public void testMeterSettings() { when(displayer.getDisplayerConstraints()).thenReturn( new DisplayerConstraints(null) .supportsAttribute(METER_GROUP)); when(displayer.getDisplayerSettings()).thenReturn(DisplayerSettingsFactory.newMeterChartSettings() .meter(0, 100, 500, 900) .buildSettings()); presenter.init(displayer); verify(view).clear(); verify(view).addTextProperty(eq(METER_START), eq("0"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addTextProperty(eq(METER_WARNING), eq("100"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addTextProperty(eq(METER_CRITICAL), eq("500"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).addTextProperty(eq(METER_END), eq("900"), any(DisplayerSettingsEditor.LongValidator.class)); verify(view).show(); } @Test public void testRenderer() { DisplayerSettings settings = DisplayerSettingsFactory.newBarChartSettings() .renderer("rendererB") .buildSettings(); when(rendererManager.getRendererForDisplayer(settings)).thenReturn(rendererB); when(displayer.getDisplayerConstraints()).thenReturn( new DisplayerConstraints(null) .supportsAttribute(RENDERER)); when(displayer.getDisplayerSettings()).thenReturn(settings); presenter.init(displayer); verify(view).clear(); verify(view).addListProperty(RENDERER, Arrays.asList("rendererA", "rendererB"), "rendererB"); verify(view).show(); } @Test public void testSupportedAttrs() { when(displayer.getDisplayerConstraints()).thenReturn(new DisplayerConstraints(null) .supportsAttribute(TYPE) .supportsAttribute(SUBTYPE) .supportsAttribute(TITLE) .supportsAttribute(FILTER_GROUP)); when(displayer.getDisplayerSettings()).thenReturn(DisplayerSettingsFactory.newBarChartSettings().buildSettings()); presenter.init(displayer); assertEquals(presenter.isSupported(TYPE), true); assertEquals(presenter.isSupported(SUBTYPE), true); assertEquals(presenter.isSupported(TITLE), true); assertEquals(presenter.isSupported(TITLE_VISIBLE), false); assertEquals(presenter.isSupported(RENDERER), false); assertEquals(presenter.isSupported(FILTER_ENABLED), true); assertEquals(presenter.isSupported(FILTER_LISTENING_ENABLED), true); assertEquals(presenter.isSupported(FILTER_NOTIFICATION_ENABLED), true); assertEquals(presenter.isSupported(FILTER_SELFAPPLY_ENABLED), true); } @Test public void testLongValidator() { PropertyFieldValidator validator = presenter.createLongValidator(); assertEquals(validator.validate("500"), true); assertEquals(validator.validate("500d"), false); assertEquals(validator.validate("aaa"), false); } @Test public void testMeterValidator() { DisplayerSettings settings = DisplayerSettingsFactory.newMeterChartSettings() .meter(0, 100, 500, 900) .buildSettings(); when(displayer.getDisplayerSettings()).thenReturn(settings); presenter.init(displayer); PropertyFieldValidator validator = presenter.createMeterValidator(settings, 0); assertEquals(validator.validate("aaa"), false); assertEquals(validator.validate("0"), true); assertEquals(validator.validate("99"), true); assertEquals(validator.validate("100"), true); assertEquals(validator.validate("101"), false); assertEquals(validator.validate("-999999999999"), true); validator = presenter.createMeterValidator(settings, 1); assertEquals(validator.validate("0"), true); assertEquals(validator.validate("99"), true); assertEquals(validator.validate("100"), true); assertEquals(validator.validate("101"), true); assertEquals(validator.validate("500"), true); assertEquals(validator.validate("501"), false); assertEquals(validator.validate("-1"), false); validator = presenter.createMeterValidator(settings, 2); assertEquals(validator.validate("99"), false); assertEquals(validator.validate("100"), true); assertEquals(validator.validate("900"), true); assertEquals(validator.validate("901"), false); validator = presenter.createMeterValidator(settings, 3); assertEquals(validator.validate("499"), false); assertEquals(validator.validate("500"), true); assertEquals(validator.validate("900"), true); assertEquals(validator.validate("10000000000000"), true); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/DisplayerSubtypeSelectorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Arrays; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.RendererLibrary; import org.dashbuilder.displayer.client.RendererManager; import org.dashbuilder.displayer.client.events.DisplayerSubtypeSelectedEvent; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mocks.EventSourceMock; import static org.dashbuilder.displayer.DisplayerSubType.*; import static org.dashbuilder.displayer.DisplayerType.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class DisplayerSubtypeSelectorTest { @Mock DisplayerSubtypeSelector.View subtypeView; @Mock RendererManager rendererManager; @Mock RendererLibrary rendererLibrary; @Mock EventSourceMock subtypeSelectedEvent; DisplayerSubtypeSelector presenter; @Before public void init() { when(rendererManager.getRendererForType(any(DisplayerType.class))).thenReturn(rendererLibrary); when(rendererLibrary.getSupportedSubtypes(BARCHART)).thenReturn(Arrays.asList(BAR, BAR_STACKED)); when(rendererLibrary.getSupportedSubtypes(LINECHART)).thenReturn(Arrays.asList(LINE, SMOOTH)); when(rendererLibrary.getSupportedSubtypes(BUBBLECHART)).thenReturn(null); presenter = new DisplayerSubtypeSelector(subtypeView, rendererManager, subtypeSelectedEvent); } @Test public void testInitialization1() { presenter.init(BARCHART, BAR); verify(subtypeView).show(BARCHART, BAR); verify(subtypeView).show(BARCHART, BAR_STACKED); verify(subtypeView).select(BAR); } @Test public void testInitialization2() { presenter.init(LINECHART, null); verify(subtypeView).show(LINECHART, LINE); verify(subtypeView).show(LINECHART, SMOOTH); verify(subtypeView).select(LINE); } @Test public void testInitialization3() { presenter.init(BUBBLECHART, null); verify(subtypeView, never()).show(any(DisplayerType.class), any(DisplayerSubType.class)); verify(subtypeView).showDefault(BUBBLECHART); } @Test public void testOnSelect() { presenter.onSelect(LINE); assertEquals(presenter.getSelectedSubtype(), LINE); verify(subtypeSelectedEvent).fire(any(DisplayerSubtypeSelectedEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/DisplayerTypeSelectorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import static org.dashbuilder.displayer.DisplayerSubType.SMOOTH; import static org.dashbuilder.displayer.DisplayerType.BARCHART; import static org.dashbuilder.displayer.DisplayerType.LINECHART; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.RendererManager; import org.dashbuilder.displayer.client.events.DisplayerTypeSelectedEvent; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mocks.EventSourceMock; @RunWith(MockitoJUnitRunner.class) public class DisplayerTypeSelectorTest { @Mock DisplayerTypeSelector.View typeView; @Mock DisplayerSubtypeSelector subtypeSelector; @Mock EventSourceMock typeSelectedEvent; @Mock RendererManager rendererManager; DisplayerTypeSelector presenter; @Before public void init() { presenter = new DisplayerTypeSelector(typeView, subtypeSelector, typeSelectedEvent, rendererManager); } @Test public void testInitialization() { presenter.init(LINECHART, SMOOTH); verify(typeView).select(LINECHART); } @Test public void testOnSelect() { presenter.onSelect(BARCHART); assertEquals(presenter.getSelectedType(), BARCHART); verify(typeSelectedEvent).fire(any(DisplayerTypeSelectedEvent.class)); } @Test public void testNotSupportedDisplayer() { Mockito.when(rendererManager.isTypeSupported(DisplayerType.BARCHART)).thenReturn(true); Mockito.when(rendererManager.isTypeSupported(DisplayerType.LINECHART)).thenReturn(true); presenter = new DisplayerTypeSelector(typeView, subtypeSelector, typeSelectedEvent, rendererManager); verify(typeView, times(2)).show(any()); verify(typeView, times(0)).show(DisplayerType.MAP); verify(typeView).show(DisplayerType.BARCHART); verify(typeView).show(DisplayerType.LINECHART); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/ExternalComponentPresenterTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.displayer.client.component.ExternalComponentDispatcher; import org.dashbuilder.displayer.client.widgets.ExternalComponentPresenter.View; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class ExternalComponentPresenterTest { @Mock View view; @Mock ExternalComponentDispatcher dispatcher; @Mock ExternalComponentMessageHelper messageHelper; @InjectMocks ExternalComponentPresenter externalComponentPresenter; @Test public void testSendMessage() { ExternalComponentMessage message = new ExternalComponentMessage(); externalComponentPresenter.sendMessage(message); verify(messageHelper).withId(eq(message), eq(externalComponentPresenter.getId())); verify(view).postMessage(eq(message)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/ExternalComponentPropertiesEditorTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Optional; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.external.model.ComponentParameter; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.uberfire.ext.properties.editor.model.PropertyEditorCategory; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.mocks.CallerMock; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.matches; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class ExternalComponentPropertiesEditorTest { @Mock ComponentService externalComponentServiceMock; @Mock ExternalComponentPropertiesEditor.View view; @Mock BusyIndicatorView loading; @Captor ArgumentCaptor> categoriesCaptor; CallerMock externalComponentService; @InjectMocks ExternalComponentPropertiesEditor externalComponentPropertiesEditor; @Before public void init() { externalComponentService = new CallerMock<>(externalComponentServiceMock); externalComponentPropertiesEditor.setExternalComponentService(externalComponentService); } @Test public void testComponentNotFound() { String c1 = "c1"; when(externalComponentServiceMock.byId(matches(c1))).thenReturn(Optional.empty()); externalComponentPropertiesEditor.init(c1, Collections.emptyMap(), props -> { }); verify(view).componentNotFound(); } @Test public void testNoProperties() { ExternalComponent c1 = new ExternalComponent("c1", "c1 name", "c1 icon", false, Collections.emptyList()); when(externalComponentServiceMock.byId(matches(c1.getId()))).thenReturn(Optional.of(c1)); externalComponentPropertiesEditor.init(c1.getId(), Collections.emptyMap(), props -> { }); verify(view).noPropertiesComponent(); } @Test public void testLoadProperties() { ComponentParameter p1 = param("P1 CAT", "p1val", "text", "P1 Field", "p1", emptyList()); ComponentParameter p2 = param("P2 CAT", "p2val", "combo", "P2 Field", "p2", asList("V1", "V2")); ExternalComponent c1 = new ExternalComponent("c1", "c1 name", "c1 icon", false, asList(p1, p2)); when(externalComponentServiceMock.byId(matches(c1.getId()))).thenReturn(Optional.of(c1)); externalComponentPropertiesEditor.init(c1.getId(), new HashMap<>(), props -> { }); verify(view).addCategories(categoriesCaptor.capture()); Collection categories = categoriesCaptor.getValue(); assertEquals(3, categories.size()); } private ComponentParameter param(String category, String defaultValue, String type, String label, String name, List comboValues) { return new ComponentParameter(name, type, category, defaultValue, label, comboValues); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/RendererSelectorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets; import java.util.Arrays; import java.util.List; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.AbstractRendererLibrary; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.RendererLibrary; import org.dashbuilder.displayer.client.RendererManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class RendererSelectorTest { @Mock RendererSelector.RadioListView radioListView; @Mock RendererSelector.TabListView tabListView; @Mock RendererSelector.ListBoxView listBoxView; @Mock RendererManager rendererManager; @Mock Command selectCommand; RendererLibMock gwtLib = new RendererLibMock("gwt"); RendererLibMock d3Lib = new RendererLibMock("d3"); RendererLibMock lienzoLib = new RendererLibMock("lienzo"); DisplayerSettings settings = DisplayerSettingsFactory .newPieChartSettings() .renderer("d3") .buildSettings(); RendererSelector presenter; class RendererLibMock extends AbstractRendererLibrary { String name; public RendererLibMock(String name) { this.name = name; } @Override public String getUUID() { return null; } @Override public String getName() { return name; } @Override public List getSupportedTypes() { return null; } @Override public List getSupportedSubtypes(DisplayerType displayerType) { return null; } @Override public Displayer lookupDisplayer(DisplayerSettings displayer) { return null; } } @Before public void init() { presenter = new RendererSelector(tabListView, listBoxView, radioListView, rendererManager); } @Test public void testSingleRenderer() { List rendererLibs = Arrays.asList((RendererLibrary) d3Lib); when(rendererManager.getRendererForDisplayer(settings)).thenReturn(d3Lib); presenter.init(settings, RendererSelector.SelectorType.TAB, 300, selectCommand); verify(tabListView).setVisible(false); verify(tabListView, never()).setWidth(anyInt()); verify(tabListView, never()).clearRendererSelector(); verify(tabListView, never()).addRendererItem(anyString()); verify(tabListView, never()).setSelectedRendererIndex(anyInt()); verifyZeroInteractions(listBoxView, radioListView); } @Test public void testMultipleRenderers() { List rendererLibs = Arrays.asList((RendererLibrary) gwtLib, d3Lib, lienzoLib); when(rendererManager.getRenderersForType(any(), any())).thenReturn(rendererLibs); when(rendererManager.getRendererForDisplayer(settings)).thenReturn(d3Lib); presenter.init(settings, RendererSelector.SelectorType.LIST, 300, selectCommand); verify(listBoxView).setVisible(true); verify(listBoxView).setWidth(300); verify(listBoxView).clearRendererSelector(); verify(listBoxView).addRendererItem("gwt"); verify(listBoxView).addRendererItem("d3"); verify(listBoxView).addRendererItem("lienzo"); verify(listBoxView).setSelectedRendererIndex(1); verifyZeroInteractions(tabListView, radioListView); } @Test public void testOnSelect() { List rendererLibs = Arrays.asList((RendererLibrary) gwtLib, d3Lib); when(rendererManager.getRendererForDisplayer(settings)).thenReturn(d3Lib); when(rendererManager.getRendererByName(gwtLib.getName())).thenReturn(gwtLib); when(tabListView.getRendererSelected()).thenReturn(gwtLib.getName()); presenter.init(settings, RendererSelector.SelectorType.TAB, 300, selectCommand); presenter.onRendererSelected(); verify(selectCommand).execute(); assertEquals(presenter.getRendererLibrary(), gwtLib); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/ColumnFilterEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.displayer.client.events.ColumnFilterChangedEvent; import org.dashbuilder.displayer.client.events.ColumnFilterDeletedEvent; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class ColumnFilterEditorTest { @Mock ColumnFilterEditor.View view; @Mock SyncBeanManager beanManager; @Mock SyncBeanDef textParameterBeanDef; @Mock SyncBeanDef numberParameterBeanDef; @Mock SyncBeanDef dateParameterBeanDef; @Mock SyncBeanDef timeFrameBeanDef; @Mock SyncBeanDef likeToFunctionBeanDef; @Mock TextParameterEditor textParameterEditor; @Mock NumberParameterEditor numberParameterEditor; @Mock DateParameterEditor dateParameterEditor; @Mock TimeFrameEditor timeFrameEditor; @Mock LikeToFunctionEditor likeToFunctionEditor; @Mock DataSetMetadata metadata; @Mock EventSourceMock changedEvent; @Mock EventSourceMock deletedEvent; @Before public void init() { when(beanManager.lookupBean(TextParameterEditor.class)).thenReturn(textParameterBeanDef); when(beanManager.lookupBean(NumberParameterEditor.class)).thenReturn(numberParameterBeanDef); when(beanManager.lookupBean(DateParameterEditor.class)).thenReturn(dateParameterBeanDef); when(beanManager.lookupBean(TimeFrameEditor.class)).thenReturn(timeFrameBeanDef); when(beanManager.lookupBean(LikeToFunctionEditor.class)).thenReturn(likeToFunctionBeanDef); when(textParameterBeanDef.newInstance()).thenReturn(textParameterEditor); when(numberParameterBeanDef.newInstance()).thenReturn(numberParameterEditor); when(dateParameterBeanDef.newInstance()).thenReturn(dateParameterEditor); when(likeToFunctionBeanDef.newInstance()).thenReturn(likeToFunctionEditor); when(timeFrameBeanDef.newInstance()).thenReturn(timeFrameEditor); } protected ColumnFilterEditor setupEditor(ColumnType columnType, CoreFunctionType functionType, Comparable... params) { when(metadata.getColumnType("col")).thenReturn(columnType); CoreFunctionFilter filter = new CoreFunctionFilter("col", functionType, params); ColumnFilterEditor filterEditor = new ColumnFilterEditor(view, beanManager, changedEvent, deletedEvent); filterEditor.init(metadata, filter); assertEquals(view, filterEditor.getView()); return filterEditor; } @Test public void testTextParam() { setupEditor(ColumnType.LABEL, CoreFunctionType.EQUALS_TO, "Test"); int n = CoreFunctionType.getSupportedTypes(ColumnType.LABEL).size()-1; verify(view).clearFunctionSelector(); verify(view, times(n)).addFunctionItem(Mockito. any()); verify(view, never()).addFunctionItem(CoreFunctionType.TIME_FRAME); verify(view).clearFilterConfig(); verify(view).addFilterConfigWidget(textParameterEditor); verify(view).setFunctionSelected("col = Test"); } @Test public void testNumberParam() throws Exception { double number = 1000.23; NumberFormat numberFormat = NumberFormat.getNumberInstance(); when(view.formatNumber(number)).thenReturn(numberFormat.format(number)); setupEditor(ColumnType.NUMBER, CoreFunctionType.EQUALS_TO, number); int n = CoreFunctionType.getSupportedTypes(ColumnType.NUMBER).size()-1; verify(view).clearFunctionSelector(); verify(view, times(n)).addFunctionItem(Mockito. any()); verify(view, never()).addFunctionItem(CoreFunctionType.TIME_FRAME); verify(view, never()).addFunctionItem(CoreFunctionType.LIKE_TO); verify(view).clearFilterConfig(); verify(view).addFilterConfigWidget(numberParameterEditor); verify(view).setFunctionSelected("col = " + numberFormat.format(number)); } @Test public void testDateParam() throws Exception { SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); String dateStr = "23-11-2020 23:59:59"; Date d = dateFormat.parse(dateStr); when(view.formatDate(d)).thenReturn(dateStr); setupEditor(ColumnType.DATE, CoreFunctionType.EQUALS_TO, d); int n = CoreFunctionType.getSupportedTypes(ColumnType.DATE).size()-1; verify(view).clearFunctionSelector(); verify(view, times(n)).addFunctionItem(Mockito. any()); verify(view).addFunctionItem(CoreFunctionType.TIME_FRAME); verify(view, never()).addFunctionItem(CoreFunctionType.LIKE_TO); verify(view).clearFilterConfig(); verify(view).addFilterConfigWidget(dateParameterEditor); verify(view).setFunctionSelected("col = " + dateStr); } @Test public void testNotEquals() { setupEditor(ColumnType.LABEL, CoreFunctionType.NOT_EQUALS_TO, "Test"); verify(view).setFunctionSelected("col != Test"); } @Test public void testBetween() { setupEditor(ColumnType.LABEL, CoreFunctionType.BETWEEN, "A", "B"); verify(view).setFunctionSelected("col [A B]"); } @Test public void testGreaterOrEquals() { setupEditor(ColumnType.LABEL, CoreFunctionType.GREATER_OR_EQUALS_TO, "Test"); verify(view).setFunctionSelected("col >= Test"); } @Test public void testGreaterThan() { setupEditor(ColumnType.LABEL, CoreFunctionType.GREATER_THAN, "Test"); verify(view).setFunctionSelected("col > Test"); } @Test public void testLowerOrEquals() { setupEditor(ColumnType.LABEL, CoreFunctionType.LOWER_OR_EQUALS_TO, "Test"); verify(view).setFunctionSelected("col <= Test"); } @Test public void testLowerThan() { setupEditor(ColumnType.LABEL, CoreFunctionType.LOWER_THAN, "Test"); verify(view).setFunctionSelected("col < Test"); } @Test public void testNull() { setupEditor(ColumnType.LABEL, CoreFunctionType.IS_NULL); verify(view).setFunctionSelected("col = null "); } @Test public void testNotNull() { setupEditor(ColumnType.LABEL, CoreFunctionType.NOT_NULL); verify(view).setFunctionSelected("col != null "); } @Test public void testLikeTo() { setupEditor(ColumnType.LABEL, CoreFunctionType.LIKE_TO, "Test"); verify(view).clearFilterConfig(); verify(view).setFunctionSelected("col like Test"); verify(view).addFilterConfigWidget(likeToFunctionEditor); } @Test public void testTimeFrame() { setupEditor(ColumnType.DATE, CoreFunctionType.TIME_FRAME, "begin[year February] till now"); verify(view).clearFilterConfig(); verify(view).setFunctionSelected("col = begin[year February] till now"); verify(view).addFilterConfigWidget(timeFrameEditor); } @Test public void testSelectFunction() { ColumnFilterEditor presenter = setupEditor(ColumnType.LABEL, CoreFunctionType.EQUALS_TO, "value"); verify(view).clearFilterConfig(); verify(view).setFunctionSelected("col = value"); reset(view); when(view.getSelectedFunctionIndex()).thenReturn(2); presenter.onSelectFilterFunction(); assertEquals(presenter.getCoreFilter().getType(), CoreFunctionType.NOT_EQUALS_TO); verify(changedEvent).fire(Mockito.any()); verify(view).clearFilterConfig(); verify(view).setFunctionSelected("col != value1"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/DataSetFilterEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import javax.enterprise.event.Event; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupFactory; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.displayer.client.events.ColumnFilterDeletedEvent; import org.dashbuilder.displayer.client.events.DataSetFilterChangedEvent; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DataSetFilterEditorTest { @Mock ColumnFilterEditor columnFilterEditor; @Mock DataSetFilterEditor.View filterView; @Mock SyncBeanManager beanManager; @Mock SyncBeanDef columnFilterEditorBeanDef; @Mock DataSetMetadata metadata; @Mock Event changedEvent; @Before public void setup() { when(beanManager.lookupBean(ColumnFilterEditor.class)).thenReturn(columnFilterEditorBeanDef); when(columnFilterEditorBeanDef.newInstance()).thenReturn(columnFilterEditor); when(metadata.getNumberOfColumns()).thenReturn(3); when(metadata.getColumnId(0)).thenReturn("column1"); when(metadata.getColumnId(1)).thenReturn("column2"); when(metadata.getColumnId(2)).thenReturn("column3"); when(metadata.getColumnType(0)).thenReturn(ColumnType.LABEL); when(metadata.getColumnType(2)).thenReturn(ColumnType.DATE); } @Test public void testViewInitialization() { DataSetFilter filter = new DataSetFilter(); ColumnFilter filter1 = FilterFactory.equalsTo("column1", "Test"); filter.addFilterColumn(filter1); DataSetFilterEditor filterEditor = new DataSetFilterEditor(filterView, beanManager, changedEvent); filterEditor.init(filter, metadata); assertEquals(filterView, filterEditor.view); verify(filterView).showNewFilterHome(); verify(filterView).addColumn("column1"); verify(filterView).addColumn("column2"); verify(filterView).addColumn("column3"); verify(filterView, times(filter.getColumnFilterList().size())).addColumnFilterEditor(any(ColumnFilterEditor.class)); } @Test public void testWorkflow() { DataSetFilterEditor filterEditor = new DataSetFilterEditor(filterView, beanManager, changedEvent); filterEditor.init(null, metadata); reset(filterView); filterEditor.onNewFilterStart(); verify(filterView).showColumnSelector(); filterEditor.onNewFilterCancel(); verify(filterView).showNewFilterHome(); } @Test public void testCreateLabelFilter() { DataSetFilterEditor filterEditor = new DataSetFilterEditor(filterView, beanManager, changedEvent); filterEditor.init(null, metadata); reset(filterView); when(filterView.getSelectedColumnIndex()).thenReturn(0); filterEditor.onCreateFilter(); verify(changedEvent).fire(any(DataSetFilterChangedEvent.class)); DataSetFilter filter = filterEditor.getFilter(); assertNotNull(filter); assertEquals(filter.getColumnFilterList().size(), 1); ColumnFilter expected = FilterFactory.createCoreFunctionFilter("column1", ColumnType.LABEL, CoreFunctionType.NOT_EQUALS_TO); assertEquals(filter.getColumnFilterList().get(0), expected); } @Test public void testCreateDateFilter() { DataSetFilterEditor filterEditor = new DataSetFilterEditor(filterView, beanManager, changedEvent); filterEditor.init(null, metadata); reset(filterView); when(filterView.getSelectedColumnIndex()).thenReturn(2); filterEditor.onCreateFilter(); verify(changedEvent).fire(any(DataSetFilterChangedEvent.class)); DataSetFilter filter = filterEditor.getFilter(); assertNotNull(filter); assertEquals(filter.getColumnFilterList().size(), 1); ColumnFilter expected = FilterFactory.createCoreFunctionFilter("column3", ColumnType.DATE, CoreFunctionType.TIME_FRAME); assertEquals(filter.getColumnFilterList().get(0), expected); } @Test public void testDeleteDuplicatedFilters() { ColumnFilter columnFilter1 = FilterFactory.notEqualsTo("column", "val1"); ColumnFilter columnFilter2 = FilterFactory.notEqualsTo("column", "val1"); ColumnFilterEditor columnFilterEditor1 = mock(ColumnFilterEditor.class); ColumnFilterEditor columnFilterEditor2 = mock(ColumnFilterEditor.class); when(columnFilterEditor1.getFilter()).thenReturn(columnFilter1); when(columnFilterEditor2.getFilter()).thenReturn(columnFilter2); when(columnFilterEditorBeanDef.newInstance()).thenReturn(columnFilterEditor1, columnFilterEditor2); DataSetFilter filter = new DataSetFilter(); filter.addFilterColumn(columnFilter1, columnFilter2); DataSetFilterEditor filterEditor = new DataSetFilterEditor(filterView, beanManager, changedEvent); filterEditor.init(filter, metadata); filterEditor.onColumnFilterDeleted(new ColumnFilterDeletedEvent(columnFilterEditor2)); filterEditor.onColumnFilterDeleted(new ColumnFilterDeletedEvent(columnFilterEditor1)); assertEquals(filter.getColumnFilterList().size(), 0); verify(filterView).removeColumnFilterEditor(columnFilterEditor1); verify(filterView).removeColumnFilterEditor(columnFilterEditor2); verify(beanManager).destroyBean(columnFilterEditor1); verify(beanManager).destroyBean(columnFilterEditor2); verify(changedEvent, times(2)).fire(any(DataSetFilterChangedEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/LikeToFunctionEditorTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class LikeToFunctionEditorTest { LikeToFunctionEditor presenter; @Mock LikeToFunctionEditor.View view; @Mock Command changedEvent; @Before public void init() { presenter = new LikeToFunctionEditor(view); } @Test public void testShowValue() { presenter.setPattern("%val%"); verify(view).setPattern("%val%"); } @Test public void testParseVoidInput() { when(view.getPattern()).thenReturn(""); presenter.viewUpdated(); verify(view).error(); assertNull(presenter.getPattern()); } @Test public void testParseInput() { when(view.getPattern()).thenReturn("val"); presenter.viewUpdated(); assertEquals(presenter.getPattern(), "val"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/MultipleNumberParameterEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class MultipleNumberParameterEditorTest { MultipleNumberParameterEditor presenter; @Mock MultipleNumberParameterEditor.View view; @Mock Command changedEvent; @Before public void init() { presenter = new MultipleNumberParameterEditor(view); } @Test public void testShowSingleValue() { presenter.setValues(Arrays.asList(10d)); verify(view).setValue("10.0"); } @Test public void testShowSingleValue2() { presenter.setValues(Arrays.asList("10")); verify(view).setValue("10"); } @Test public void testShowMultipleValues() { presenter.setValues(Arrays.asList(10d, 20d, 30d)); verify(view).setValue("10.0 | 20.0 | 30.0"); } @Test public void testParseVoidInput() { when(view.getValue()).thenReturn(""); presenter.valueChanged(); assertTrue(presenter.getValues().isEmpty()); verify(view).error(); } @Test public void testParseSingleInput() { when(view.getValue()).thenReturn("3"); presenter.valueChanged(); assertEquals(presenter.getValues().size(), 1); assertEquals(presenter.getValues().get(0), 3d); } @Test public void testMultipleInput() { when(view.getValue()).thenReturn("|1| 2 | 3|4| "); presenter.valueChanged(); assertEquals(presenter.getValues().size(), 4); assertEquals(presenter.getValues().get(0), 1d); assertEquals(presenter.getValues().get(1), 2d); assertEquals(presenter.getValues().get(2), 3d); assertEquals(presenter.getValues().get(3), 4d); // Endure values are cleared on every change presenter.valueChanged(); assertEquals(presenter.getValues().size(), 4); } @Test public void testMultipleInput2() { when(view.getValue()).thenReturn(",1, 2 , 3,4, "); presenter.valueChanged(); assertEquals(presenter.getValues().size(), 4); assertEquals(presenter.getValues().get(0), 1d); assertEquals(presenter.getValues().get(1), 2d); assertEquals(presenter.getValues().get(2), 3d); assertEquals(presenter.getValues().get(3), 4d); } @Test public void testSingleInputError() { when(view.getValue()).thenReturn("a"); presenter.valueChanged(); assertTrue(presenter.getValues().isEmpty()); verify(view).error(); } @Test public void testMultipleInputError() { when(view.getValue()).thenReturn("a,3"); presenter.valueChanged(); assertTrue(presenter.getValues().isEmpty()); verify(view).error(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/MultipleTextParameterEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class MultipleTextParameterEditorTest { MultipleTextParameterEditor presenter; @Mock MultipleTextParameterEditor.View view; @Mock Command changedEvent; @Before public void init() { presenter = new MultipleTextParameterEditor(view); } @Test public void testShowSingleValue() { presenter.setValues(Arrays.asList("val")); verify(view).setValue("val"); } @Test public void testShowMultipleValues() { presenter.setValues(Arrays.asList("val1", "val2", "val3")); verify(view).setValue("val1 | val2 | val3"); } @Test public void testParseVoidInput() { when(view.getValue()).thenReturn(""); presenter.valueChanged(); assertTrue(presenter.getValues().isEmpty()); verify(view).error(); } @Test public void testParseSingleInput() { when(view.getValue()).thenReturn("val"); presenter.valueChanged(); assertEquals(presenter.getValues().size(), 1); assertEquals(presenter.getValues().get(0), "val"); } @Test public void testMultipleInput() { when(view.getValue()).thenReturn("|1| 2 | 3|4| "); presenter.valueChanged(); assertEquals(presenter.getValues().size(), 4); assertEquals(presenter.getValues().get(0), "1"); assertEquals(presenter.getValues().get(1), "2"); assertEquals(presenter.getValues().get(2), "3"); assertEquals(presenter.getValues().get(3), "4"); // Endure values are cleared on every change presenter.valueChanged(); assertEquals(presenter.getValues().size(), 4); } @Test public void testMultipleInput2() { when(view.getValue()).thenReturn(",1, 2 , 3,4, "); presenter.valueChanged(); assertEquals(presenter.getValues().size(), 4); assertEquals(presenter.getValues().get(0), "1"); assertEquals(presenter.getValues().get(1), "2"); assertEquals(presenter.getValues().get(2), "3"); assertEquals(presenter.getValues().get(3), "4"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/NumberParameterEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class NumberParameterEditorTest { NumberParameterEditor presenter; @Mock NumberParameterEditor.View view; @Mock Command changedEvent; @Before public void init() { presenter = new NumberParameterEditor(view); } @Test public void testShowValue() { presenter.setValue(10d); verify(view).setValue("10.0"); } @Test public void testParseVoidInput() { when(view.getValue()).thenReturn(""); presenter.valueChanged(); assertNull(presenter.getValue()); verify(view).error();; } @Test public void testParseSingleInput() { when(view.getValue()).thenReturn("3"); presenter.valueChanged(); verify(view, never()).error();; assertEquals(presenter.getValue(), 3d); } @Test public void testInputError() { when(view.getValue()).thenReturn("a"); presenter.valueChanged(); assertNull(presenter.getValue()); verify(view).error(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/TextParameterEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class TextParameterEditorTest { TextParameterEditor presenter; @Mock TextParameterEditor.View view; @Mock Command changedEvent; @Before public void init() { presenter = new TextParameterEditor(view); } @Test public void testShowValue() { presenter.setValue("val"); verify(view).setValue("val"); } @Test public void testParseVoidInput() { when(view.getValue()).thenReturn(""); presenter.valueChanged(); verify(view).error(); assertNull(presenter.getValue()); } @Test public void testParseInput() { when(view.getValue()).thenReturn("val"); presenter.valueChanged(); assertEquals(presenter.getValue(), "val"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/TimeAmountEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import org.dashbuilder.dataset.date.TimeAmount; import org.dashbuilder.dataset.group.DateIntervalType; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class TimeAmountEditorTest { @Mock TimeAmountEditor.View timeAmountView; @Mock Command changeCommand; @Test public void testViewInitialization() { TimeAmount timeAmount = new TimeAmount(10, DateIntervalType.DAY); TimeAmountEditor editor = new TimeAmountEditor(timeAmountView); editor.init(timeAmount, changeCommand); verify(timeAmountView).clearIntervalTypeSelector(); verify(timeAmountView, times(TimeAmountEditor.INTERVAL_TYPES.size())).addIntervalTypeItem(any(DateIntervalType.class)); verify(timeAmountView).setSelectedTypeIndex(3); verify(timeAmountView).setQuantity(10); } @Test public void testNullInitialization() { TimeAmountEditor editor = new TimeAmountEditor(timeAmountView); editor.init(null, changeCommand); verify(timeAmountView).clearIntervalTypeSelector(); verify(timeAmountView, times(TimeAmountEditor.INTERVAL_TYPES.size())).addIntervalTypeItem(any(DateIntervalType.class)); // "0year" set by default verify(timeAmountView).setSelectedTypeIndex(7); verify(timeAmountView).setQuantity(0); } @Test public void testDecreaseQuantity() { TimeAmount timeAmount = new TimeAmount(10, DateIntervalType.DAY); TimeAmountEditor timeAmountEditor = new TimeAmountEditor(timeAmountView); timeAmountEditor.init(timeAmount, changeCommand); timeAmountEditor.decreaseQuantity(); verify(timeAmountView).setQuantity(9); verify(changeCommand).execute(); assertEquals(timeAmount.getQuantity(), 9); } @Test public void testIncreaseQuantity() { TimeAmount timeAmount = new TimeAmount(10, DateIntervalType.DAY); TimeAmountEditor timeAmountEditor = new TimeAmountEditor(timeAmountView); timeAmountEditor.init(timeAmount, changeCommand); timeAmountEditor.increaseQuantity(); verify(timeAmountView).setQuantity(11); verify(changeCommand).execute(); assertEquals(timeAmount.getQuantity(), 11); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/TimeFrameEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.date.TimeFrame; import org.dashbuilder.dataset.group.DateIntervalType; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class TimeFrameEditorTest { @Mock SyncBeanManager beanManager; @Mock Command changeCommand; @Mock TimeFrameEditor.View timeFrameView; @Mock TimeAmountEditor.View timeAmountView; @Mock TimeInstantEditor.View timeInstantView; TimeAmountEditor fromAmountEditor; TimeAmountEditor toAmountEditor; TimeInstantEditor fromInstantEditor; TimeInstantEditor toInstantEditor; TimeFrameEditor timeFrameEditor; public static final TimeFrame TEN_DAYS = TimeFrame.parse("begin[year March] till 10day"); public static final TimeFrame LAST_DAY = TimeFrame.parse("now -1day till now"); public static final TimeFrame CURRENT_YEAR = TimeFrame.parse("begin[year] till end[year]"); public static final TimeFrame UNDEFINED = null; @Before public void init() { fromAmountEditor = new TimeAmountEditor(timeAmountView); toAmountEditor = new TimeAmountEditor(timeAmountView); fromInstantEditor = new TimeInstantEditor(timeInstantView, fromAmountEditor); toInstantEditor = new TimeInstantEditor(timeInstantView, toAmountEditor); timeFrameEditor = new TimeFrameEditor(timeFrameView, beanManager); SyncBeanDef tieBeanDef = mock(SyncBeanDef.class); when(beanManager.lookupBean(TimeInstantEditor.class)).thenReturn(tieBeanDef); when(tieBeanDef.newInstance()).thenReturn(fromInstantEditor, toInstantEditor); } @Test public void testViewInitialization() { timeFrameEditor.init(TEN_DAYS, changeCommand); assertEquals(timeFrameView, timeFrameEditor.view); verify(timeFrameView).init(timeFrameEditor); verify(timeFrameView).clearFirstMonthSelector(); verify(timeFrameView, times(Month.values().length)).addFirstMonthItem(any(Month.class)); verify(timeFrameView).setSelectedFirstMonthIndex(Month.MARCH.getIndex() - 1); } @Test public void testNullInitialization() { timeFrameEditor.init(UNDEFINED, changeCommand); assertEquals(timeFrameView, timeFrameEditor.view); verify(timeFrameView).init(timeFrameEditor); verify(timeFrameView).clearFirstMonthSelector(); verify(timeFrameView, times(Month.values().length)).addFirstMonthItem(any(Month.class)); verify(timeFrameView).setSelectedFirstMonthIndex(Month.JANUARY.getIndex() - 1); } @Test public void testChangeTimeAmountQuantity() { TimeFrame timeFrame = TimeFrame.parse("now -1year till now"); timeFrameEditor.init(timeFrame, changeCommand); long qb = timeFrame.getFrom().getTimeAmount().getQuantity(); fromAmountEditor.decreaseQuantity(); long qa = timeFrame.getFrom().getTimeAmount().getQuantity(); verify(changeCommand).execute(); assertEquals(qb - 1, qa); } @Test public void testChangeTimeAmountType() { TimeFrame timeFrame = TimeFrame.parse("now -1year till now"); timeFrameEditor.init(timeFrame, changeCommand); when(timeAmountView.getSelectedTypeIndex()).thenReturn(3); fromAmountEditor.changeIntervalType(); DateIntervalType type = timeFrame.getFrom().getTimeAmount().getType(); verify(changeCommand).execute(); assertEquals(type, DateIntervalType.DAY); } @Test public void testChangeTimeInstant() { TimeFrame timeFrame = TimeFrame.parse("now -1year till now"); timeFrameEditor.init(timeFrame, changeCommand); when(timeInstantView.getSelectedIntervalTypeIndex()).thenReturn(3); fromInstantEditor.changeIntervalType(); DateIntervalType type = timeFrame.getFrom().getIntervalType(); verify(changeCommand).execute(); assertEquals(type, DateIntervalType.MONTH); } @Test public void testFirstMonthAvailable() { timeFrameEditor.init(CURRENT_YEAR, changeCommand); assertEquals(timeFrameEditor.isFirstMonthAvailable(), true); } @Test public void testFirstMonthUnavailable() { timeFrameEditor.init(LAST_DAY, changeCommand); assertEquals(timeFrameEditor.isFirstMonthAvailable(), false); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/filter/TimeInstantEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.filter; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.date.TimeAmount; import org.dashbuilder.dataset.date.TimeInstant; import org.dashbuilder.dataset.group.DateIntervalType; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class TimeInstantEditorTest { @Mock TimeInstantEditor.View timeInstantView; @Mock TimeAmountEditor timeAmountEditor; @Mock Command changeCommand; @Test public void testViewInitialization() { TimeInstant beginMonth = new TimeInstant(TimeInstant.TimeMode.BEGIN, DateIntervalType.MONTH, Month.JANUARY, new TimeAmount(10, DateIntervalType.DAY)); TimeInstantEditor timeInstantEditor = new TimeInstantEditor(timeInstantView, timeAmountEditor); timeInstantEditor.init(beginMonth, changeCommand); assertEquals(timeInstantView, timeInstantEditor.view); verify(timeInstantView).init(timeInstantEditor); verify(timeInstantView).clearTimeModeSelector(); verify(timeInstantView, times(TimeInstant.TimeMode.values().length)).addTimeModeItem(any(TimeInstant.TimeMode.class)); verify(timeInstantView).setSelectedTimeModeIndex(TimeInstant.TimeMode.BEGIN.getIndex()); verify(timeInstantView).enableIntervalTypeSelector(); verify(timeInstantView).clearIntervalTypeSelector(); verify(timeInstantView, times(TimeInstantEditor.INTERVAL_TYPES.size())).addIntervalTypeItem(any(DateIntervalType.class)); verify(timeInstantView).setSelectedIntervalTypeIndex(3); } @Test public void testNullInitialization() { TimeInstantEditor timeInstantEditor = new TimeInstantEditor(timeInstantView, timeAmountEditor); timeInstantEditor.init(null, changeCommand); assertEquals(timeInstantView, timeInstantEditor.view); verify(timeInstantView).init(timeInstantEditor); verify(timeInstantView).clearTimeModeSelector(); verify(timeInstantView, times(TimeInstant.TimeMode.values().length)).addTimeModeItem(any(TimeInstant.TimeMode.class)); verify(timeInstantView).setSelectedTimeModeIndex(TimeInstant.TimeMode.NOW.getIndex()); verify(timeInstantView).disableIntervalTypeSelector(); verify(timeInstantView, never()).clearIntervalTypeSelector(); verify(timeInstantView, never()).enableIntervalTypeSelector(); verify(timeInstantView, never()).addIntervalTypeItem(any(DateIntervalType.class)); verify(timeInstantView, never()).setSelectedIntervalTypeIndex(any(Integer.class)); } @Test public void testChangeTimeMode() { when(timeInstantView.getTimeModeSelectedIndex()).thenReturn(TimeInstant.TimeMode.BEGIN.getIndex()); TimeInstantEditor timeInstantEditor = new TimeInstantEditor(timeInstantView, timeAmountEditor); timeInstantEditor.init(null, changeCommand); timeInstantEditor.changeTimeMode(); TimeInstant timeInstant = timeInstantEditor.getTimeInstant(); assertEquals(timeInstant.getTimeMode(), TimeInstant.TimeMode.BEGIN); verify(changeCommand).execute(); } @Test public void testChangeIntervalType() { when(timeInstantView.getSelectedIntervalTypeIndex()).thenReturn(0); TimeInstantEditor timeInstantEditor = new TimeInstantEditor(timeInstantView, timeAmountEditor); timeInstantEditor.init(null, changeCommand); timeInstantEditor.changeIntervalType(); TimeInstant timeInstant = timeInstantEditor.getTimeInstant(); assertEquals(timeInstant.getIntervalType(), DateIntervalType.MINUTE); verify(changeCommand).execute(); } @Test public void testSwitchToNow() { TimeInstantEditor timeInstantEditor = new TimeInstantEditor(timeInstantView, timeAmountEditor); timeInstantEditor.init(null, changeCommand); reset(timeInstantView); when(timeInstantView.getTimeModeSelectedIndex()).thenReturn(TimeInstant.TimeMode.NOW.getIndex()); timeInstantEditor.changeTimeMode(); TimeInstant timeInstant = timeInstantEditor.getTimeInstant(); assertEquals(timeInstant.getTimeMode(), TimeInstant.TimeMode.NOW); verify(timeInstantView).disableIntervalTypeSelector(); verify(timeInstantView, never()).enableIntervalTypeSelector(); verify(changeCommand).execute(); } @Test public void testSwitchFromNow() { TimeInstantEditor timeInstantEditor = new TimeInstantEditor(timeInstantView, timeAmountEditor); timeInstantEditor.init(null, changeCommand); reset(timeInstantView); when(timeInstantView.getTimeModeSelectedIndex()).thenReturn(TimeInstant.TimeMode.END.getIndex()); timeInstantEditor.changeTimeMode(); TimeInstant timeInstant = timeInstantEditor.getTimeInstant(); assertEquals(timeInstant.getTimeMode(), TimeInstant.TimeMode.END); verify(timeInstantView).enableIntervalTypeSelector(); verify(changeCommand).execute(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/group/ColumnFunctionEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import java.util.List; import javax.enterprise.event.Event; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.displayer.client.events.GroupFunctionChangedEvent; import org.dashbuilder.displayer.client.events.GroupFunctionDeletedEvent; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class ColumnFunctionEditorTest { @Mock ColumnFunctionEditor.View view; @Mock ColumnDetailsEditor columnDetailsEditor; @Mock Event changeEvent; @Mock Event deleteEvent; @Mock DataSetMetadata metadata; ColumnFunctionEditor presenter; @Before public void init() { presenter = new ColumnFunctionEditor(view, columnDetailsEditor, changeEvent, deleteEvent); when(metadata.getNumberOfColumns()).thenReturn(3); when(metadata.getColumnId(0)).thenReturn("column1"); when(metadata.getColumnId(1)).thenReturn("column2"); when(metadata.getColumnId(2)).thenReturn("column3"); when(metadata.getColumnType(0)).thenReturn(ColumnType.LABEL); when(metadata.getColumnType(1)).thenReturn(ColumnType.NUMBER); when(metadata.getColumnType(2)).thenReturn(ColumnType.DATE); when(metadata.getColumnType("column1")).thenReturn(ColumnType.LABEL); when(metadata.getColumnType("column2")).thenReturn(ColumnType.NUMBER); } @Test public void testViewInitialization() { GroupFunction groupFunction = new GroupFunction("column1", "column1", null); presenter.init(metadata, groupFunction, null, "Title", false, false); verify(view).setDeleteOptionEnabled(false); verify(view, never()).setDeleteOptionEnabled(true); verify(view).setColumnSelectorTitle("Title"); verify(view).clearColumnSelector(); verify(view, times(3)).addColumnItem(anyString()); verify(view).setSelectedColumnIndex(0); verify(view).setFunctionSelectorEnabled(false); verify(view, never()).setFunctionSelectorEnabled(true); } @Test public void testLabelTarget() { GroupFunction groupFunction = new GroupFunction("column1", "column1", null); presenter.init(metadata, groupFunction, ColumnType.LABEL, "Title", true, true); verify(view).clearColumnSelector(); verify(view, times(1)).addColumnItem(anyString()); verify(view).setSelectedColumnIndex(0); verify(view).setFunctionSelectorEnabled(false); verify(view, never()).setFunctionSelectorEnabled(true); } @Test public void testNumericTarget() { GroupFunction groupFunction = new GroupFunction("column1", "column1", null); presenter.init(metadata, groupFunction, ColumnType.NUMBER, "Title", true, true); verify(view).clearColumnSelector(); verify(view, times(3)).addColumnItem(anyString()); verify(view).setSelectedColumnIndex(0); verify(view).setFunctionSelectorEnabled(true); verify(view, never()).setVoidFunctionEnabled(true); verify(view, times(presenter.getSupportedFunctionTypes().size())).addFunctionItem(any(AggregateFunctionType.class)); verify(view, never()).setSelectedFunctionIndex(anyInt()); } @Test public void testUnspecifiedTarget() { GroupFunction groupFunction = new GroupFunction("column1", "column1", AggregateFunctionType.COUNT); presenter.init(metadata, groupFunction, null, "Title", true, true); verify(view).clearColumnSelector(); verify(view, times(3)).addColumnItem(anyString()); verify(view).setSelectedColumnIndex(0); List supportedFunctions = presenter.getSupportedFunctionTypes(); verify(view).setFunctionSelectorEnabled(true); verify(view).setVoidFunctionEnabled(true); verify(view, times(supportedFunctions.size())).addFunctionItem(any(AggregateFunctionType.class)); verify(view).setSelectedFunctionIndex(anyInt()); } @Test public void testSelectColumn() { when(view.getSelectedColumnId()).thenReturn("column2"); GroupFunction groupFunction = new GroupFunction("column1", "column1", AggregateFunctionType.COUNT); presenter.init(metadata, groupFunction, null, "Title", true, true); presenter.onColumnSelected(); assertEquals(presenter.getGroupFunction().getSourceId(), "column2"); verify(changeEvent).fire(any(GroupFunctionChangedEvent.class)); } @Test public void testUpdateFunctionsAvailable() { GroupFunction groupFunction = new GroupFunction("column1", "column1", AggregateFunctionType.COUNT); presenter.init(metadata, groupFunction, null, "Title", true, true); List typeListColumn1 = presenter.getSupportedFunctionTypes(); List typeListLabel = presenter.getSupportedFunctionTypes(ColumnType.LABEL); assertEquals(typeListColumn1.size(), typeListLabel.size()); verify(view).clearFunctionSelector(); verify(view, times(typeListLabel.size())).addFunctionItem(any(AggregateFunctionType.class)); reset(view); when(view.getSelectedColumnId()).thenReturn("column2"); presenter.onColumnSelected(); List typeListColumn2 = presenter.getSupportedFunctionTypes(); List typeListNumber = presenter.getSupportedFunctionTypes(ColumnType.NUMBER); assertEquals(typeListColumn2.size(), typeListNumber.size()); assertEquals(presenter.getGroupFunction().getSourceId(), "column2"); verify(view).clearFunctionSelector(); verify(view, times(typeListNumber.size())).addFunctionItem(any(AggregateFunctionType.class)); verify(changeEvent).fire(any(GroupFunctionChangedEvent.class)); } @Test public void testSelectFunction() { when(view.getSelectedFunctionIndex()).thenReturn(1); GroupFunction groupFunction = new GroupFunction("column1", "column1", AggregateFunctionType.COUNT); presenter.init(metadata, groupFunction, null, "Title", true, true); presenter.onFunctionSelected(); List supportedFunctions = presenter.getSupportedFunctionTypes(); assertEquals(presenter.getGroupFunction().getFunction(), supportedFunctions.get(1)); verify(changeEvent).fire(any(GroupFunctionChangedEvent.class)); } @Test public void testDelete() { GroupFunction groupFunction = new GroupFunction("column1", "column1", AggregateFunctionType.COUNT); presenter.init(metadata, groupFunction, null, "Title", true, true); presenter.delete(); verify(deleteEvent).fire(any(GroupFunctionDeletedEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/group/DataSetGroupDateEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.group; import javax.enterprise.event.Event; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.displayer.client.events.DataSetGroupDateChanged; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.group.DateIntervalType.*; import static org.dashbuilder.dataset.group.GroupStrategy.*; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DataSetGroupDateEditorTest { @Mock DataSetGroupDateEditor.View view; @Mock Event changeEvent; DataSetGroupDateEditor presenter; @Before public void init() { presenter = new DataSetGroupDateEditor(view, changeEvent); } @Test public void testFixedModeInit() { presenter.init(new ColumnGroup("col", "col", FIXED, 15, HOUR.toString())); verify(view).setFixedModeValue(true); verify(view).clearIntervalTypeSelector(); verify(view, times(FIXED_INTERVALS_SUPPORTED.size())).addIntervalTypeItem(any(DateIntervalType.class)); verify(view).setSelectedIntervalTypeIndex(anyInt()); verify(view, never()).setMaxIntervalsVisibility(true); verify(view, never()).setFirstDayVisibility(true); verify(view, never()).setFirstMonthVisibility(true); } @Test public void testDynamicModeInit() { ColumnGroup columnGroup = new ColumnGroup("col", "col", DYNAMIC, 15, HOUR.toString()); presenter.init(columnGroup); verify(view).setFixedModeValue(false); verify(view).clearIntervalTypeSelector(); verify(view, times(DateIntervalType.values().length)).addIntervalTypeItem(any(DateIntervalType.class)); verify(view).setSelectedIntervalTypeIndex(anyInt()); verify(view).setMaxIntervalsVisibility(true); verify(view).setMaxIntervalsValue("15"); verify(view, never()).setFirstDayVisibility(true); verify(view, never()).setFirstMonthVisibility(true); } @Test public void testFirstMonthDayVisibility() { presenter.init(new ColumnGroup("col", "col", FIXED, 15, QUARTER.toString())); verify(view).setFirstMonthVisibility(false); verify(view).setFirstDayVisibility(false); verify(view, never()).setFirstDayVisibility(true); verify(view, never()).setFirstMonthVisibility(true); reset(view); presenter.init(new ColumnGroup("col", "col", FIXED, 15, MONTH.toString())); verify(view).setFirstMonthVisibility(true); verify(view).setFirstDayVisibility(false); verify(view, never()).setFirstDayVisibility(true); reset(view); presenter.init(new ColumnGroup("col", "col", FIXED, 15, DAY_OF_WEEK.toString())); verify(view).setFirstDayVisibility(true); verify(view).setFirstMonthVisibility(false); verify(view, never()).setFirstMonthVisibility(true); reset(view); presenter.init(new ColumnGroup("col", "col", FIXED, 15, HOUR.toString())); verify(view).setFirstMonthVisibility(false); verify(view).setFirstDayVisibility(false); verify(view, never()).setFirstDayVisibility(true); verify(view, never()).setFirstMonthVisibility(true); reset(view); presenter.init(new ColumnGroup("col", "col", FIXED, 15, MINUTE.toString())); verify(view).setFirstMonthVisibility(false); verify(view).setFirstDayVisibility(false); verify(view, never()).setFirstDayVisibility(true); verify(view, never()).setFirstMonthVisibility(true); reset(view); presenter.init(new ColumnGroup("col", "col", FIXED, 15, SECOND.toString())); verify(view).setFirstMonthVisibility(false); verify(view).setFirstDayVisibility(false); verify(view, never()).setFirstDayVisibility(true); verify(view, never()).setFirstMonthVisibility(true); } @Test public void testEnableFixedMode() { presenter.init(new ColumnGroup("col", "col", DYNAMIC, 15, CENTURY.toString())); reset(view); when(view.getFixedModeValue()).thenReturn(true); presenter.onFixedStrategyChanged(); verify(changeEvent).fire(any(DataSetGroupDateChanged.class)); ColumnGroup result = presenter.getColumnGroup(); assertEquals(result.getStrategy(), FIXED); verify(view).setFirstMonthVisibility(true); verify(view, never()).setMaxIntervalsVisibility(true); verify(view, never()).setFirstDayVisibility(true); } @Test public void testDisableFixedMode() { when(view.getFixedModeValue()).thenReturn(false); presenter.init(new ColumnGroup("col", "col", FIXED, 15, HOUR.toString())); presenter.onFixedStrategyChanged(); verify(changeEvent).fire(any(DataSetGroupDateChanged.class)); ColumnGroup result = presenter.getColumnGroup(); assertEquals(result.getStrategy(), DYNAMIC); verify(view).setMaxIntervalsVisibility(true); verify(view).setMaxIntervalsValue("15"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/sourcecode/JsValidatorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.google.gwtmockito.GwtMockitoTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class JsValidatorTest { @Mock JsEvaluator jsEvaluator; DefaultJsValidator validator; @Before public void setUp() { validator = new DefaultJsValidator(jsEvaluator); } @Test public void testNoError() { String error = validator.validate("var a=1; var b = 42+a; alert(b);", null); assertNull(error); } @Test public void testNotAllowed_document() { String error = validator.validate("document.getElementById(\"\");", null); assertNotNull(error); } @Test public void testNotAllowed_window() { String error = validator.validate("window.location=\"\"", null); assertNotNull(error); } @Test public void testNotAllowed_eval() { String error = validator.validate("eval(\"\");", null); assertNotNull(error); error = validator.validate("eval\n(\"\");", null); assertNotNull(error); error = validator.validate("eval (\"\");", null); assertNotNull(error); error = validator.validate("eval\t(\"\");", null); assertNotNull(error); } @Test public void testNotAllowed_innerHtml() { String error = validator.validate("this.innerHtml=\"\"", null); assertNotNull(error); } @Test public void testVariableReplacement() throws Exception { String error = validator.validate("${this}.style.cursor=\"pointer\";", null); String js = "function __alert(msg) {};\nvar __var0__ = document.createElement(\"div\");\n__var0__.style.cursor=\"pointer\";"; verify(jsEvaluator).evaluate(js); assertNull(error); doThrow(new Exception("error __var0__")).when(jsEvaluator).evaluate(anyString()); error = validator.validate("${this}.style.cursor=\"pointer\";", null); assertEquals(error, "error ${this}"); } @Test public void testAllowedVariables() throws Exception { List vars = Arrays.asList("${this}"); String error = validator.validate("${this}.style.cursor=\"pointer\";", vars); assertNull(error); vars = new ArrayList<>(); error = validator.validate("${this}.style.cursor=\"pointer\";", vars); assertNotNull(error); } @Test public void testOcurrences() throws Exception { assertEquals(validator.occurrences("", "{"), 0); assertEquals(validator.occurrences("{", "{"), 1); assertEquals(validator.occurrences("{", "}"), 0); assertEquals(validator.occurrences("{}", "}"), 1); assertEquals(validator.occurrences("{}", "{"), 1); assertEquals(validator.occurrences("{{}}", "{"), 2); } @Test public void testIsolateLines() throws Exception { String js = "if (a) b;\nelse c;"; String isolated = validator.isolateLines(js); assertEquals(isolated, "if (a) b;\nc;\n"); js = " "; isolated = validator.isolateLines(js); assertEquals(isolated.length(), 0); js = "if (a) {\nb;\n} else c;"; isolated = validator.isolateLines(js); assertEquals(isolated, "if (a) {}\nb;\n{} c;\n"); js = "if (a) {\nb; }\nelse c;"; isolated = validator.isolateLines(js); assertEquals(isolated, "if (a) {}\nb; \nc;\n"); js = "if (a)\n{ b;\n} else c;"; isolated = validator.isolateLines(js); assertEquals(isolated, "if (a)\n b;\n{} c;\n"); js = "if (a) { b; } else c;"; isolated = validator.isolateLines(js); assertEquals(isolated, "if (a) { b; } c;\n"); js = "if (a) { if (b) {}}"; isolated = validator.isolateLines(js); assertEquals(isolated, "if (a) { if (b) {}}\n"); js = "if (a) {\nif (b) {\n}\n}"; isolated = validator.isolateLines(js); assertEquals(isolated, "if (a) {}\nif (b) {}\n"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-client/src/test/java/org/dashbuilder/displayer/client/widgets/sourcecode/SourceCodeEditorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.widgets.sourcecode; import java.util.HashMap; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class SourceCodeEditorTest { @Mock SourceCodeEditor.View view; @Mock Command onChange; @Mock HtmlValidator htmlValidator; @Mock JsValidator jsValidator; SourceCodeEditor presenter; @Before public void init() { presenter = new SourceCodeEditor(view, htmlValidator, jsValidator); presenter.init(SourceCodeType.HTML, "Hi", new HashMap<>(), onChange); } @Test public void testInitialization() { verify(view).edit(SourceCodeType.HTML, "Hi"); } @Test public void testEmpty() { reset(htmlValidator); presenter.init(SourceCodeType.HTML, null, new HashMap<>(), onChange); verify(htmlValidator, never()).validate(any()); reset(htmlValidator); presenter.init(SourceCodeType.HTML, "", new HashMap<>(), onChange); verify(htmlValidator, never()).validate(any()); reset(jsValidator); presenter.init(SourceCodeType.JAVASCRIPT, null, new HashMap<>(), onChange); verify(jsValidator, never()).validate(any(), anyCollection()); reset(jsValidator); presenter.init(SourceCodeType.JAVASCRIPT, "", new HashMap<>(), onChange); verify(jsValidator, never()).validate(any(), anyCollection()); } @Test public void testOnChange() { presenter.onSourceCodeChanged("howdy?"); assertEquals(presenter.getCode(), "howdy?"); assertEquals(presenter.hasErrors(), false); verify(htmlValidator).validate("howdy?"); verify(onChange).execute(); verify(view, never()).error(anyString()); } @Test public void testError() { when(htmlValidator.validate("howdy?")).thenReturn("Error"); boolean ok = presenter.onSourceCodeChanged("howdy?"); assertFalse(ok); assertEquals(presenter.getCode(), "Hi"); assertEquals(presenter.hasErrors(), true ); verify(htmlValidator).validate("howdy?"); verify(onChange, never()).execute(); verify(view).error("Error"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-displayer-editor jar Dashbuilder Displayer Editor Widgets org.uberfire uberfire-client-all org.uberfire uberfire-api org.uberfire uberfire-workbench-client org.uberfire uberfire-layout-editor-api org.uberfire uberfire-layout-editor-client org.uberfire uberfire-runtime-plugins-client com.google.gwt gwt-user provided org.jboss.errai errai-common org.jboss.errai errai-ioc org.gwtbootstrap3 gwtbootstrap3 org.dashbuilder dashbuilder-common-client org.dashbuilder dashbuilder-displayer-client org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-screen com.google.gwt.gwtmockito gwtmockito test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/AreaChartDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class AreaChartDragComponent extends DisplayerDragComponent { @Inject public AreaChartDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.AREACHART; } @Override public String getDragComponentIconClass() { return "fa fa-area-chart"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_areachart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/BarChartDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; @Dependent public class BarChartDragComponent extends DisplayerDragComponent { @Inject public BarChartDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.BARCHART; } @Override public String getDragComponentIconClass() { return "fa fa-bar-chart"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_barchart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/BubbleChartDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class BubbleChartDragComponent extends DisplayerDragComponent { @Inject public BubbleChartDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.BUBBLECHART; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_bubblechart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/DisplayerDragComponent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerEditorPopup; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.gwtbootstrap3.client.ui.Modal; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.layout.editor.client.api.HasModalConfiguration; import org.uberfire.ext.layout.editor.client.api.LayoutDragComponent; import org.uberfire.ext.layout.editor.client.api.ModalConfigurationContext; import org.uberfire.ext.layout.editor.client.api.RenderingContext; import org.uberfire.mvp.Command; import javax.enterprise.context.Dependent; import javax.inject.Inject; import java.util.Map; @Dependent public class DisplayerDragComponent implements LayoutDragComponent, HasModalConfiguration { SyncBeanManager beanManager; DisplayerViewer viewer; PlaceManager placeManager; PerspectiveCoordinator perspectiveCoordinator; DisplayerSettingsJSONMarshaller marshaller; @Inject public DisplayerDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator) { this.beanManager = beanManager; this.viewer = viewer; this.placeManager = placeManager; this.perspectiveCoordinator = perspectiveCoordinator; this.marshaller = DisplayerSettingsJSONMarshaller.get(); } public DisplayerType getDisplayerType() { return null; } public DisplayerSubType getDisplayerSubType() { return null; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.DisplayerComponent(); } @Override public IsWidget getPreviewWidget(final RenderingContext ctx) { return getShowWidget(ctx); } @Override public IsWidget getShowWidget(final RenderingContext ctx) { Map properties = ctx.getComponent().getProperties(); String json = properties.get("json"); if (json == null) { return null; } final DisplayerSettings settings = marshaller.fromJsonString(json); viewer.removeFromParent(); viewer.init(settings); viewer.addAttachHandler(attachEvent -> { if (attachEvent.isAttached()) { final int offsetWidth = ctx.getContainer().getOffsetWidth(); int containerWidth = offsetWidth > 40 ? offsetWidth - 40 : 0; adjustSize(settings, containerWidth); Displayer displayer = viewer.draw(); perspectiveCoordinator.addDisplayer(displayer); } }); int containerWidth = ctx.getContainer().getOffsetWidth() - 40; adjustSize(settings, containerWidth); Displayer displayer = viewer.draw(); perspectiveCoordinator.addDisplayer(displayer); return viewer; } @Override public Modal getConfigurationModal(final ModalConfigurationContext ctx) { return buildEditorPopUp(ctx); } @Override public void removeCurrentWidget(RenderingContext ctx) { Displayer displayer = viewer.getDisplayer(); if (displayer != null) { perspectiveCoordinator.removeDisplayer(displayer); displayer.close(); } } protected DisplayerEditorPopup buildEditorPopUp(final ModalConfigurationContext ctx) { Map properties = ctx.getComponentProperties(); String json = properties.get("json"); DisplayerSettings settings = json != null ? marshaller.fromJsonString(json) : initialSettings(ctx); DisplayerEditorPopup editor = beanManager.lookupBean(DisplayerEditorPopup.class).newInstance(); // For brand new components set the default type/subtype to create if (settings == null) { if (getDisplayerType() != null) { editor.setDisplayerType(getDisplayerType()); } if (getDisplayerSubType() != null) { editor.setDisplayerSubType(getDisplayerSubType()); } } editor.init(settings); editor.setOnSaveCommand(getSaveCommand(editor, ctx)); editor.setOnCloseCommand(getCloseCommand(editor, ctx)); return editor; } protected DisplayerSettings initialSettings(final ModalConfigurationContext ct) { return null; } protected Command getSaveCommand(final DisplayerEditorPopup editor, final ModalConfigurationContext ctx) { return () -> { String json = marshaller.toJsonString(editor.getDisplayerSettings()); ctx.setComponentProperty("json", json); ctx.configurationFinished(); beanManager.destroyBean(editor); }; } protected Command getCloseCommand(final DisplayerEditorPopup editor, final ModalConfigurationContext ctx) { return () -> { ctx.configurationCancelled(); beanManager.destroyBean(editor); }; } protected void adjustSize(DisplayerSettings settings, int containerWidth) { int displayerWidth = settings.getChartWidth(); int tableWidth = settings.getTableWidth(); if (containerWidth > 0 && displayerWidth > containerWidth) { int ratio = containerWidth * 100 / displayerWidth; settings.setChartWidth(containerWidth); settings.setChartHeight(settings.getChartHeight() * ratio / 100); } if (tableWidth == 0 || tableWidth > containerWidth) { settings.setTableWidth(containerWidth > 20 ? containerWidth - 20 : 0); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/DisplayerEditorEntryPoint.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import javax.annotation.PostConstruct; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.jboss.errai.ioc.client.api.AfterInitialization; import org.jboss.errai.ioc.client.api.EntryPoint; @EntryPoint public class DisplayerEditorEntryPoint { /** * https://issues.jboss.org/browse/DASHBUILDE-105 => Sometimes, due to unknown reasons, the Displayer editor * does not show all the attributes in the "Display" tab The fix is to force the DisplayerAttributeDef static * fields to initialize on startup. */ @PostConstruct public void init() { DisplayerAttributeDef def = DisplayerAttributeDef.TITLE; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/LineChartDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class LineChartDragComponent extends DisplayerDragComponent { @Inject public LineChartDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.LINECHART; } @Override public String getDragComponentIconClass() { return "fa fa-line-chart"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_linechart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/MapChartDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class MapChartDragComponent extends DisplayerDragComponent { @Inject public MapChartDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.MAP; } @Override public String getDragComponentIconClass() { return "fa fa-map"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_mapchart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/MeterChartDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class MeterChartDragComponent extends DisplayerDragComponent { @Inject public MeterChartDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.METERCHART; } @Override public String getDragComponentIconClass() { return "fa fa-tachometer"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_meterchart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/MetricDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class MetricDragComponent extends DisplayerDragComponent { @Inject public MetricDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.METRIC; } @Override public String getDragComponentIconClass() { return "fa fa-calculator"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_metric(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/PerspectiveEditorReportingGroupProvider.java ================================================ /* * Copyright 2018 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.RendererManager; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.ext.layout.editor.client.api.LayoutDragComponentGroup; import org.uberfire.ext.plugin.client.perspective.editor.api.PerspectiveEditorComponentGroupProvider; import static org.dashbuilder.displayer.DisplayerType.AREACHART; import static org.dashbuilder.displayer.DisplayerType.BARCHART; import static org.dashbuilder.displayer.DisplayerType.BUBBLECHART; import static org.dashbuilder.displayer.DisplayerType.LINECHART; import static org.dashbuilder.displayer.DisplayerType.MAP; import static org.dashbuilder.displayer.DisplayerType.METERCHART; import static org.dashbuilder.displayer.DisplayerType.METRIC; import static org.dashbuilder.displayer.DisplayerType.PIECHART; import static org.dashbuilder.displayer.DisplayerType.SELECTOR; import static org.dashbuilder.displayer.DisplayerType.TABLE; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; /** * {@link PerspectiveEditorComponentGroupProvider} holding all the chart displayer components */ @ApplicationScoped public class PerspectiveEditorReportingGroupProvider implements PerspectiveEditorComponentGroupProvider { private SyncBeanManager beanManager; private Constants i18n = Constants.INSTANCE; private RendererManager rendererManager; @Inject public PerspectiveEditorReportingGroupProvider(SyncBeanManager beanManager, RendererManager rendererManager) { this.beanManager = beanManager; this.rendererManager = rendererManager; } @Override public String getName() { return i18n.drag_group_name_reporting(); } @Override public LayoutDragComponentGroup getComponentGroup() { LayoutDragComponentGroup group = new LayoutDragComponentGroup(getName()); addComponent(BARCHART, group, i18n.drag_component_name_barchart(), BarChartDragComponent.class); addComponent(PIECHART, group, i18n.drag_component_name_piechart(), PieChartDragComponent.class); addComponent(LINECHART, group, i18n.drag_component_name_linechart(), LineChartDragComponent.class); addComponent(AREACHART, group, i18n.drag_component_name_areachart(), AreaChartDragComponent.class); addComponent(BUBBLECHART, group, i18n.drag_component_name_bubblechart(), BubbleChartDragComponent.class); addComponent(METERCHART, group, i18n.drag_component_name_meterchart(), MeterChartDragComponent.class); addComponent(MAP, group, i18n.drag_component_name_mapchart(), MapChartDragComponent.class); addComponent(METRIC, group, i18n.drag_component_name_metric(), MetricDragComponent.class); addComponent(TABLE, group, i18n.drag_component_name_table(), TableDragComponent.class); addComponent(SELECTOR, group, i18n.drag_component_name_filter(), SelectorDragComponent.class); return group; } private void addComponent(DisplayerType type, LayoutDragComponentGroup group, String name, Class dragClass) { if (rendererManager.isTypeSupported(type)) { group.addLayoutDragComponent(name, lookupDisplayerComponent(dragClass)); } } protected DisplayerDragComponent lookupDisplayerComponent(Class dragClass) { SyncBeanDef displayerBeanDef = beanManager.lookupBean(dragClass); return displayerBeanDef.newInstance(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/PieChartDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class PieChartDragComponent extends DisplayerDragComponent { @Inject public PieChartDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.PIECHART; } @Override public String getDragComponentIconClass() { return "fa fa-pie-chart"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_piechart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/SelectorDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class SelectorDragComponent extends DisplayerDragComponent { @Inject public SelectorDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.SELECTOR; } @Override public String getDragComponentIconClass() { return "fa fa-filter"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_filter(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/TableDragComponent.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class TableDragComponent extends DisplayerDragComponent { @Inject public TableDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator ) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public DisplayerType getDisplayerType() { return DisplayerType.TABLE; } @Override public String getDragComponentIconClass() { return "fa fa-table"; } @Override public String getDragComponentTitle() { return Constants.INSTANCE.drag_component_name_table(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/external/ComponentGroupProducer.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor.external; import java.util.List; import java.util.stream.Collectors; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.editor.resources.i18n.Constants; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentService; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.ext.layout.editor.client.api.LayoutDragComponentGroup; import org.uberfire.ext.layout.editor.client.api.LayoutDragComponentPalette; import org.uberfire.ext.layout.editor.client.widgets.LayoutComponentPaletteGroupProvider; import org.uberfire.ext.plugin.client.perspective.editor.events.PerspectiveEditorFocusEvent; @ApplicationScoped public class ComponentGroupProducer { private static final Constants i18n = Constants.INSTANCE; private SyncBeanManager beanManager; private LayoutDragComponentPalette layoutDragComponentPalette; private Caller componentService; @Inject public ComponentGroupProducer(Caller externalComponentService, SyncBeanManager beanManager, LayoutDragComponentPalette layoutDragComponentPalette) { this.componentService = externalComponentService; this.beanManager = beanManager; this.layoutDragComponentPalette = layoutDragComponentPalette; } public void onEditorFocus(@Observes PerspectiveEditorFocusEvent event) { loadComponents(); } public void loadComponents() { componentService.call((List components) -> { addProvidedComponents(components.stream() .filter(c -> c.isProvided()) .collect(Collectors.toList())); addExternalComponents(components.stream() .filter(c -> !c.isProvided()) .collect(Collectors.toList())); }).listAllComponents(); } public void addExternalComponents(List components) { String groupId = i18n.externalComponentsGroupName(); if (!components.isEmpty()) { checkGroup(groupId); } components.forEach(comp -> { layoutDragComponentPalette.addDraggableComponent(groupId, comp.getId(), produceDragComponent(comp)); }); } public void addProvidedComponents(List components) { components.stream().forEach(component -> { String groupId = component.getCategory() != null ? component.getCategory() : i18n.internalComponentsGroupName(); checkGroup(groupId); layoutDragComponentPalette.addDraggableComponent(groupId, component.getId(), produceDragComponent(component)); }); } private void checkGroup(String groupId) { if (!layoutDragComponentPalette.hasDraggableGroup(groupId)) { layoutDragComponentPalette.addDraggableGroup(new LayoutComponentPaletteGroupProvider() { @Override public String getName() { return groupId; } @Override public LayoutDragComponentGroup getComponentGroup() { return new LayoutDragComponentGroup(groupId); } }); } } ExternalComponentDragDef produceDragComponent(ExternalComponent comp) { ExternalComponentDragDef dragComp; if (comp.isNoData()) { dragComp = beanManager.lookupBean(ExternalDragComponent.class).getInstance(); } else { dragComp = beanManager.lookupBean(ExternalDisplayerDragComponent.class).getInstance(); } dragComp.setDragInfo(comp.getName(), comp.getIcon()); dragComp.setComponentId(comp.getId()); return dragComp; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/external/ExternalComponentDragDef.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor.external; import java.util.Collections; import java.util.Map; import org.uberfire.ext.layout.editor.client.api.HasDragAndDropSettings; import org.uberfire.ext.layout.editor.client.api.LayoutDragComponent; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_ID_KEY; public interface ExternalComponentDragDef extends LayoutDragComponent, HasDragAndDropSettings { public default String getDragComponentTitle() { final String componentName = getComponentName(); return componentName == null ? "Unknown" : componentName; } public default String getDragComponentIconClass() { final String componentIcon = getComponentIcon(); return componentIcon != null ? componentIcon : LayoutDragComponent.super.getDragComponentIconClass(); } public default String[] getSettingsKeys() { return new String[]{COMPONENT_ID_KEY}; } public default String getSettingValue(String key) { if (COMPONENT_ID_KEY.equals(key)) { return getComponentId(); } return null; } public default void setSettingValue(String key, String value) { if (COMPONENT_ID_KEY.equals(key)) { setComponentId(value); } } public default Map getMapSettings() { return Collections.singletonMap(COMPONENT_ID_KEY, getComponentId()); } String getComponentName(); String getComponentIcon(); String getComponentId(); void setComponentId(String componentId); void setDragInfo(String componentName, String componentIcon); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/external/ExternalDisplayerDragComponent.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor.external; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.client.editor.DisplayerDragComponent; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.client.events.DisplayerSettingsChangedEvent; import org.dashbuilder.displayer.client.prototypes.DisplayerPrototypes; import org.dashbuilder.displayer.client.widgets.DisplayerEditorPopup; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.gwtbootstrap3.client.ui.Modal; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.layout.editor.client.api.ModalConfigurationContext; import static org.dashbuilder.displayer.DisplayerType.EXTERNAL_COMPONENT; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_ID_KEY; @Dependent public class ExternalDisplayerDragComponent extends DisplayerDragComponent implements ExternalComponentDragDef { String componentId; private String componentName; private String componentIcon; @Inject Event displayerSettingsChangedEvent; @Inject DisplayerPrototypes displayerPrototypes; @Inject public ExternalDisplayerDragComponent(SyncBeanManager beanManager, DisplayerViewer viewer, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator) { super(beanManager, viewer, placeManager, perspectiveCoordinator); } @Override public void setDragInfo(String componentName, String componentIcon) { this.componentName = componentName; this.componentIcon = componentIcon; } @Override public Modal getConfigurationModal(ModalConfigurationContext ctx) { DisplayerEditorPopup editorPopUp = buildEditorPopUp(ctx); editorPopUp.setTypeSelectorEnabled(false); editorPopUp.setExternalDisplayerEnabled(true); return editorPopUp; } @Override protected DisplayerSettings initialSettings(ModalConfigurationContext ctx) { DisplayerSettings settings = displayerPrototypes.getProto(EXTERNAL_COMPONENT); String storedComponentId = ctx.getComponentProperty(COMPONENT_ID_KEY); settings.setComponentId(storedComponentId); return settings; } @Override public DisplayerType getDisplayerType() { return DisplayerType.EXTERNAL_COMPONENT; } public void setComponentId(String componentId) { this.componentId = componentId; } @Override public String getComponentName() { return componentName; } @Override public String getComponentIcon() { return componentIcon; } @Override public String getComponentId() { return componentId; } @Override public String getDragComponentTitle() { return ExternalComponentDragDef.super.getDragComponentTitle(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/external/ExternalDragComponent.java ================================================ package org.dashbuilder.client.editor.external; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.displayer.client.widgets.ExternalComponentEditorPopUp; import org.dashbuilder.displayer.client.widgets.ExternalComponentPresenter; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.gwtbootstrap3.client.ui.Label; import org.gwtbootstrap3.client.ui.Modal; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.ext.layout.editor.client.api.HasModalConfiguration; import org.uberfire.ext.layout.editor.client.api.ModalConfigurationContext; import org.uberfire.ext.layout.editor.client.api.RenderingContext; import org.uberfire.mvp.Command; import static java.util.stream.Collectors.toMap; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_ID_KEY; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_PARTITION_KEY; @Dependent public class ExternalDragComponent implements ExternalComponentDragDef, HasModalConfiguration { @Inject SyncBeanManager beanManager; @Inject ExternalComponentPresenter externalComponentPresenter; @Inject ExternalComponentMessageHelper messageHelper; private String componentId; private String componentName; private String componentIcon; @Override public IsWidget getPreviewWidget(RenderingContext ctx) { return getShowWidget(ctx); } @Override public IsWidget getShowWidget(RenderingContext ctx) { Map ltProps = ctx.getComponent().getProperties(); String storedComponentId = ltProps.get(COMPONENT_ID_KEY); String partition = ltProps.get(COMPONENT_PARTITION_KEY); if (storedComponentId == null) { return new Label("Component not found."); } if (partition != null) { externalComponentPresenter.withComponent(storedComponentId, partition); } else { externalComponentPresenter.withComponent(storedComponentId); } Map componentProperties = new HashMap<>(retrieveComponentProperties(storedComponentId, ltProps)); ExternalComponentMessage message = messageHelper.newInitMessage(componentProperties); externalComponentPresenter.sendMessage(message); return externalComponentPresenter.getView(); } @Override public String getComponentName() { return componentName; } @Override public String getComponentIcon() { return componentIcon; } @Override public String getComponentId() { return componentId; } @Override public void setComponentId(String componentId) { this.componentId = componentId; } @Override public void setDragInfo(String componentName, String componentIcon) { this.componentName = componentName; this.componentIcon = componentIcon; } @Override public Modal getConfigurationModal(ModalConfigurationContext ctx) { String storedComponentId = ctx.getComponentProperty(COMPONENT_ID_KEY); ExternalComponentEditorPopUp editor = beanManager.lookupBean(ExternalComponentEditorPopUp.class).newInstance(); Map existingProps = retrieveComponentProperties(storedComponentId, ctx.getComponentProperties()); editor.init(storedComponentId, existingProps, getCloseCommand(editor, ctx), getSaveCommand(storedComponentId, editor, ctx)); return editor; } protected Command getSaveCommand(String componentId, final ExternalComponentEditorPopUp editor, final ModalConfigurationContext ctx) { return () -> { editor.getProperties().forEach((k, v) -> { String key = appendComponentPrefix(componentId, k); ctx.getComponentProperties().put(key, v); }); ctx.configurationFinished(); beanManager.destroyBean(editor); }; } protected Command getCloseCommand(final ExternalComponentEditorPopUp editor, final ModalConfigurationContext ctx) { return () -> { ctx.configurationCancelled(); beanManager.destroyBean(editor); }; } private Map retrieveComponentProperties(String componentId, Map componentProperties) { String prefix = getComponentPrefix(componentId); return componentProperties.entrySet() .stream().filter(e -> e.getKey().startsWith(prefix)) .collect(toMap(e -> removeComponentPrefix(componentId, e.getKey()), Map.Entry::getValue)); } private String getComponentPrefix(String componentId) { return componentId + "."; } private String appendComponentPrefix(String componentId, String key) { return componentId + "." + key; } private String removeComponentPrefix(String componentId, String key) { return key.replaceFirst(componentId + ".", ""); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/java/org/dashbuilder/client/editor/resources/i18n/Constants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface Constants extends Messages { public static final Constants INSTANCE = GWT.create( Constants.class ); String displayer_perspective_editor_title(); String DisplayerComponent(); String drag_group_name_reporting(); String drag_component_name_barchart(); String drag_component_name_piechart(); String drag_component_name_areachart(); String drag_component_name_linechart(); String drag_component_name_bubblechart(); String drag_component_name_meterchart(); String drag_component_name_mapchart(); String drag_component_name_metric(); String drag_component_name_table(); String drag_component_name_filter(); String externalComponentsGroupName(); String internalComponentsGroupName(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/DisplayerEditor.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_perspective_editor_title=Edit Displayer DisplayerComponent=Displayer drag_group_name_reporting=Reporting drag_component_name_barchart=Bar drag_component_name_piechart=Pie drag_component_name_areachart=Area drag_component_name_linechart=Line drag_component_name_bubblechart=Bubble drag_component_name_meterchart=Meter drag_component_name_mapchart=Map drag_component_name_metric=Metric drag_component_name_table=Table drag_component_name_filter=Filter externalComponentsGroupName=External Components internalComponentsGroupName=Components ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants_de.properties ================================================ displayer_perspective_editor_title=Displayer bearbeiten ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants_es.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_perspective_editor_title=Editar visualizador DisplayerComponent=Visualizador drag_group_name_reporting=Generación de informes drag_component_name_barchart=Barra drag_component_name_piechart=Circular drag_component_name_areachart=Área drag_component_name_linechart=Línea drag_component_name_bubblechart=Burbuja drag_component_name_meterchart=Medidor drag_component_name_mapchart=Mapa drag_component_name_metric=Métrica drag_component_name_table=Tabla drag_component_name_filter=Filtro externalComponentsGroupName=Componentes externos internalComponentsGroupName=Componentes ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants_fr.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_perspective_editor_title=Modifier l''afficheur DisplayerComponent=Afficheur drag_group_name_reporting=Rapports drag_component_name_barchart=Barres drag_component_name_piechart=Secteurs drag_component_name_areachart=Aires drag_component_name_linechart=Ligne drag_component_name_bubblechart=Bulles drag_component_name_meterchart=Compteur drag_component_name_mapchart=Carte drag_component_name_metric=Métrique drag_component_name_table=Tableau drag_component_name_filter=Filtrer externalComponentsGroupName=Composants externes internalComponentsGroupName=Composants ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants_it.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_perspective_editor_title=Modifica Displayer DisplayerComponent=Displayer drag_group_name_reporting=Reporting drag_component_name_barchart=Grafico a barre drag_component_name_piechart=Grafico a torta drag_component_name_areachart=Grafico ad area drag_component_name_linechart=Grafico a linea drag_component_name_bubblechart=Grafico a bolle drag_component_name_meterchart=Grafico a misuratore drag_component_name_mapchart=Mappa drag_component_name_metric=Metrica drag_component_name_table=Tabella drag_component_name_filter=Filtro externalComponentsGroupName=Componenti Esterni internalComponentsGroupName=Componenti Interni ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants_ja.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # displayer_perspective_editor_title=ディスプレイヤーの編集 DisplayerComponent=ディスプレイヤー drag_group_name_reporting=レポート drag_component_name_barchart=バー drag_component_name_piechart=円 (パイ) drag_component_name_areachart=エリア drag_component_name_linechart=Line drag_component_name_bubblechart=バブル drag_component_name_meterchart=メーター drag_component_name_mapchart=マップ drag_component_name_metric=メトリック drag_component_name_table=テーブル drag_component_name_filter=フィルター externalComponentsGroupName=外部コンポーネント internalComponentsGroupName=コンポーネント ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants_pt_BR.properties ================================================ displayer_perspective_editor_title=Editar Exibidor ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/main/resources/org/dashbuilder/client/editor/resources/i18n/Constants_zh_CN.properties ================================================ displayer_perspective_editor_title=编辑显示屏 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/test/java/org/dashbuilder/client/editor/DisplayerDragComponentTest.java ================================================ /* * Copyright 2018 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.widgets.DisplayerEditorPopup; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.uberfire.ext.layout.editor.client.api.ModalConfigurationContext; import java.util.Map; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DisplayerDragComponentTest { @InjectMocks DisplayerDragComponent displayerDragComponent; @Mock SyncBeanManager beanManager; @Mock SyncBeanDef editorBeanDef; @Mock DisplayerEditorPopup editorPopup; @Mock ModalConfigurationContext configurationContext; @Mock Map configurationProperties; @InjectMocks LineChartDragComponent lineChartDragComponent; @Before public void setUp(){ when(configurationContext.getComponentProperties()).thenReturn(configurationProperties); when(beanManager.lookupBean(DisplayerEditorPopup.class)).thenReturn(editorBeanDef); when(editorBeanDef.newInstance()).thenReturn(editorPopup); } @Test public void testDefaultDisplayerType() { assertEquals(lineChartDragComponent.getDisplayerType(), DisplayerType.LINECHART); assertEquals(lineChartDragComponent.getDisplayerSubType(), null); lineChartDragComponent.getConfigurationModal(configurationContext); verify(editorPopup).setDisplayerType(DisplayerType.LINECHART); verify(editorPopup, never()).setDisplayerSubType(any()); } @Test public void testDoNotSetDisplayerType() { when(configurationProperties.get("json")).thenReturn(""); lineChartDragComponent.getConfigurationModal(configurationContext); verify(editorPopup, never()).setDisplayerType(any()); verify(editorPopup, never()).setDisplayerSubType(any()); } @Test public void testAdjustSize(){ final DisplayerSettings settings = mock(DisplayerSettings.class); when(settings.getChartWidth()).thenReturn(0); when(settings.getTableWidth()).thenReturn(0); displayerDragComponent.adjustSize(settings, 0); verify(settings).setTableWidth(0); displayerDragComponent.adjustSize(settings, 30); verify(settings).setTableWidth(10); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/test/java/org/dashbuilder/client/editor/PerspectiveEditorReportingGroupProviderTest.java ================================================ package org.dashbuilder.client.editor; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import java.util.Arrays; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.RendererLibrary; import org.dashbuilder.displayer.client.RendererManager; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.uberfire.ext.layout.editor.client.api.LayoutDragComponentGroup; import com.google.gwtmockito.GwtMockitoTestRunner; @RunWith(GwtMockitoTestRunner.class) public class PerspectiveEditorReportingGroupProviderTest { @Mock RendererManager rendererManager; @Mock SyncBeanManager beanManager; @InjectMocks PerspectiveEditorReportingGroupProvider perspectiveEditorReportingGroupProvider; @Mock RendererLibrary rendererLibrary; @Mock SyncBeanDef displayerDragComponentBeanDef; @Mock DisplayerDragComponent displayerDragComponent; @Before public void setUp() { when(beanManager.lookupBean(any(DisplayerDragComponent.class.getClass()))) .thenReturn(displayerDragComponentBeanDef); when(displayerDragComponentBeanDef.getInstance()).thenReturn(displayerDragComponent); } @Test public void groupShouldBeEmptyWhenTheresNoRendererTest() { LayoutDragComponentGroup componentGroup = perspectiveEditorReportingGroupProvider.getComponentGroup(); assertTrue(componentGroup.getLayoutDragComponentIds().isEmpty()); } @Test public void groupShouldHaveNComponentWhenTheresRendererTest() { when(rendererManager.isTypeSupported(DisplayerType.BARCHART)).thenReturn(true); when(rendererManager.isTypeSupported(DisplayerType.LINECHART)).thenReturn(true); LayoutDragComponentGroup componentGroup = perspectiveEditorReportingGroupProvider.getComponentGroup(); assertEquals(componentGroup.getLayoutDragComponentIds().size(), 2); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-editor/src/test/java/org/dashbuilder/client/editor/external/ExternalComponentGroupProviderTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.editor.external; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.external.model.ExternalComponent; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class ExternalComponentGroupProviderTest { @Mock ExternalDragComponent drag1; @Mock SyncBeanDef c1Bean; @Mock ExternalComponent c1; @Mock ExternalDisplayerDragComponent drag2; @Mock SyncBeanDef c2Bean; @Mock ExternalComponent c2; @Mock SyncBeanManager beanManager; @InjectMocks ComponentGroupProducer componentGroupProducer; @Test public void testProduceDragComponent() { when(c1Bean.getInstance()).thenReturn(drag1); when(beanManager.lookupBean(eq(ExternalDragComponent.class))).thenReturn(c1Bean); when(c2Bean.getInstance()).thenReturn(drag2); when(beanManager.lookupBean(eq(ExternalDisplayerDragComponent.class))).thenReturn(c2Bean); when(c1.isNoData()).thenReturn(false); when(c2.isNoData()).thenReturn(true); componentGroupProducer.produceDragComponent(c1); componentGroupProducer.produceDragComponent(c2); verify(beanManager).lookupBean(eq(ExternalDisplayerDragComponent.class)); verify(beanManager).lookupBean(eq(ExternalDragComponent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-displayer-screen jar Dashbuilder Displayer Screen com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 org.jboss.errai errai-ioc org.uberfire uberfire-api org.uberfire uberfire-client-api org.uberfire uberfire-workbench-client org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-common-client org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-displayer-client ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/java/org/dashbuilder/displayer/client/DisplayerScreenPresenter.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.uuid.UUIDGenerator; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.export.ExportCallback; import org.dashbuilder.displayer.client.export.ExportFormat; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.displayer.client.resources.i18n.Constants; import org.dashbuilder.displayer.client.widgets.DisplayerEditorPopup; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.gwtbootstrap3.client.ui.AnchorListItem; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.ButtonGroup; import org.gwtbootstrap3.client.ui.DropDownMenu; import org.gwtbootstrap3.client.ui.constants.ButtonSize; import org.gwtbootstrap3.client.ui.constants.Pull; import org.gwtbootstrap3.client.ui.constants.Toggle; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PerspectiveManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.PanelManager; import org.uberfire.client.workbench.events.ChangeTitleWidgetEvent; import org.uberfire.lifecycle.OnClose; import org.uberfire.lifecycle.OnStartup; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuItem; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.menu.impl.BaseMenuCustom; @WorkbenchScreen(identifier = "DisplayerScreen") @Dependent public class DisplayerScreenPresenter { private SyncBeanManager beanManager; private DataSetClientServices dataSetClientServices; private DisplayerViewer displayerViewer; private PerspectiveCoordinator perspectiveCoordinator; private PerspectiveManager perspectiveManager; private PanelManager panelManager; private PlaceManager placeManager; private UUIDGenerator uuidGenerator; private Event changeTitleEvent; private DisplayerSettingsJSONMarshaller jsonMarshaller; private DisplayerSettings displayerSettings; private PlaceRequest placeRequest; private Menus menu = null; private boolean editEnabled = false; private boolean cloneEnabled = false; private boolean csvExportAllowed = false; private boolean excelExportAllowed = false; private ButtonGroup menuActionsButton; // TODO allow configuration of this through a custom system property? private static final int MAX_EXPORT_LIMIT = 100000; @Inject public DisplayerScreenPresenter(SyncBeanManager beanManager, DataSetClientServices dataSetClientServices, UUIDGenerator uuidGenerator, PerspectiveManager perspectiveManager, PlaceManager placeManager, DisplayerViewer displayerViewer, PanelManager panelManager, PerspectiveCoordinator perspectiveCoordinator, Event changeTitleEvent) { this.beanManager = beanManager; this.dataSetClientServices = dataSetClientServices; this.uuidGenerator = uuidGenerator; this.placeManager = placeManager; this.perspectiveManager = perspectiveManager; this.displayerViewer = displayerViewer; this.panelManager = panelManager; this.perspectiveCoordinator = perspectiveCoordinator; this.menuActionsButton = getMenuActionsButton(); this.changeTitleEvent = changeTitleEvent; this.jsonMarshaller = DisplayerSettingsJSONMarshaller.get(); } @OnStartup public void onStartup( final PlaceRequest placeRequest ) { this.placeRequest = placeRequest; String json = placeRequest.getParameter("json", ""); if (!StringUtils.isBlank(json)) { this.displayerSettings = jsonMarshaller.fromJsonString(json); } if (displayerSettings == null ) { throw new IllegalArgumentException(Constants.INSTANCE.displayer_presenter_displayer_notfound()); } // Check if display renderer selector component. Boolean showRendererSelector = Boolean.parseBoolean(placeRequest.getParameter("showRendererSelector","false")); displayerViewer.setIsShowRendererSelector(showRendererSelector); // Draw the Displayer. if ( StringUtils.isBlank(displayerSettings.getUUID())) { displayerSettings.setUUID(uuidGenerator.newUuid()); } displayerViewer.init(displayerSettings); Displayer displayer = displayerViewer.draw(); // Register the Displayer into the coordinator. perspectiveCoordinator.addDisplayer(displayer); // Check edit mode String edit = placeRequest.getParameter("edit", "false" ); String clone = placeRequest.getParameter("clone", "false" ); editEnabled = Boolean.parseBoolean(edit); cloneEnabled = Boolean.parseBoolean(clone); csvExportAllowed = displayerSettings.isCSVExportAllowed(); excelExportAllowed = displayerSettings.isExcelExportAllowed(); this.menu = makeMenuBar(); adjustMenuActions(this.displayerSettings); } @OnClose public void onClose() { this.removeDisplayer(); } @WorkbenchPartTitle public String getTitle() { return displayerSettings.getTitle(); } @WorkbenchPartView public IsWidget getView() { return displayerViewer; } @WorkbenchMenu public void getMenus(final Consumer menusConsumer) { menusConsumer.accept(menu); } private Menus makeMenuBar() { return MenuFactory .newTopLevelCustomMenu( new MenuFactory.CustomMenuBuilder() { @Override public void push( MenuFactory.CustomMenuBuilder element ) { } @Override public MenuItem build() { return new BaseMenuCustom() { @Override public IsWidget build() { return menuActionsButton; } @Override public boolean isEnabled() { return editEnabled || cloneEnabled || csvExportAllowed || excelExportAllowed; } @Override public void setEnabled( boolean enabled ) { } }; } } ).endMenu() .build(); } private Command getEditCommand() { return () -> { perspectiveCoordinator.editOn(); String currentTitle = displayerSettings.getTitle(); DisplayerEditorPopup displayerEditor = beanManager.lookupBean(DisplayerEditorPopup.class).newInstance(); displayerEditor.init(displayerSettings.cloneInstance()); displayerEditor.setOnSaveCommand(getSaveCommand(displayerEditor, currentTitle)); displayerEditor.setOnCloseCommand(getCloseCommand(displayerEditor)); }; } protected Command getCloneCommand() { return () -> { perspectiveCoordinator.editOn(); DisplayerSettings clonedSettings = displayerSettings.cloneInstance(); clonedSettings.setUUID(uuidGenerator.newUuid()); clonedSettings.setTitle("Copy of " + clonedSettings.getTitle()); DisplayerEditorPopup displayerEditor = beanManager.lookupBean(DisplayerEditorPopup.class).newInstance(); displayerEditor.init(clonedSettings); displayerEditor.setOnSaveCommand(getSaveCloneCommand(displayerEditor)); displayerEditor.setOnCloseCommand(getCloseCommand(displayerEditor)); }; } protected Command getSaveCommand(final DisplayerEditorPopup displayerEditor, final String currentTitle) { return () -> { // On save perspectiveCoordinator.editOff(); DisplayerSettings newSettings = displayerEditor.getDisplayerSettings(); if (!displayerSettings.equals(newSettings)) { String newTitle = newSettings.getTitle(); if (!currentTitle.equals(newTitle)) { changeTitleEvent.fire(new ChangeTitleWidgetEvent(placeRequest, newSettings.getTitle())); } PanelDefinition panelDefinition = panelManager.getPanelForPlace(placeRequest); beanManager.destroyBean(displayerEditor); placeManager.goTo(createPlaceRequest(newSettings), panelDefinition); placeManager.closePlace(placeRequest); perspectiveManager.savePerspectiveState(() -> {}); } }; } protected Command getSaveCloneCommand(final DisplayerEditorPopup displayerEditor) { return () -> { perspectiveCoordinator.editOff(); beanManager.destroyBean(displayerEditor); PanelDefinition panelDefinition = panelManager.getPanelForPlace(placeRequest); placeManager.goTo(createPlaceRequest(displayerEditor.getDisplayerSettings()), panelDefinition); perspectiveManager.savePerspectiveState(() -> {}); }; } protected Command getCloseCommand(final DisplayerEditorPopup displayerEditor) { return () -> { perspectiveCoordinator.editOff(); beanManager.destroyBean(displayerEditor); }; } protected Command getExportCsvCommand() { return getExportCommand(ExportFormat.CSV); } protected Command getExportExcelCommand() { return getExportCommand(ExportFormat.XLS); } protected Command getExportCommand(ExportFormat format) { return () -> displayerViewer.getDisplayer().export(format, MAX_EXPORT_LIMIT, new ExportCallback() { @Override public void noData() { Window.alert(Constants.INSTANCE.displayer_presenter_export_no_data()); } @Override public void tooManyRows(int rowNum) { Window.alert(Constants.INSTANCE.displayer_presenter_export_large_dataset()); } @Override public void exportFileUrl(String url) { Window.open(url, "downloading", "resizable=no,scrollbars=yes,status=no"); } @Override public void error(ClientRuntimeError error) { displayerViewer.error(error); } }); } protected void removeDisplayer() { Displayer displayer = displayerViewer.getDisplayer(); perspectiveCoordinator.removeDisplayer(displayer); displayer.close(); beanManager.destroyBean(displayerViewer); } protected PlaceRequest createPlaceRequest( DisplayerSettings displayerSettings ) { String json = jsonMarshaller.toJsonString(displayerSettings); Map params = new HashMap<>(); params.put("json", json); params.put("edit", "true"); params.put("clone", "true"); return new DefaultPlaceRequest("DisplayerScreen", params); } protected void adjustMenuActions(DisplayerSettings displayerSettings) { final ComplexPanel menu = (ComplexPanel) menuActionsButton.getWidget(1); menu.getWidget(2).setVisible(displayerSettings.isCSVExportAllowed()); menu.getWidget(3).setVisible(displayerSettings.isExcelExportAllowed()); } protected ButtonGroup getMenuActionsButton() { return new ButtonGroup() {{ add(new Button( Constants.INSTANCE.menu_button_actions()) {{ setSize(ButtonSize.EXTRA_SMALL); addStyleName(Pull.RIGHT.getCssName()); setDataToggle(Toggle.DROPDOWN); }} ); add(new DropDownMenu() {{ add(new AnchorListItem(Constants.INSTANCE.menu_edit()) {{ addClickHandler(event -> getEditCommand().execute()); }} ); add(new AnchorListItem(Constants.INSTANCE.menu_clone() ) {{ addClickHandler(event -> getCloneCommand().execute()); }} ); add(new AnchorListItem(Constants.INSTANCE.menu_export_csv() ) {{ addClickHandler(event -> getExportCsvCommand().execute()); }} ); add(new AnchorListItem(Constants.INSTANCE.menu_export_excel()) {{ addClickHandler(event -> getExportExcelCommand().execute()); }} ); }} ); }}; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/java/org/dashbuilder/displayer/client/PerspectiveCoordinator.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.events.DataSetModifiedEvent; import org.dashbuilder.displayer.DisplayerSettings; import org.uberfire.client.workbench.events.PerspectiveChange; /** * It holds the set of Displayer instances being displayed on the current perspective. *

It also makes sure those instances are properly synced to reflect the data set manipulation requests * issued by any Displayer on the dashboard.

*/ @ApplicationScoped public class PerspectiveCoordinator { /** * The real coordinator. */ private DisplayerCoordinator displayerCoordinator; /** * Flag indicating if the perspective is on edit mode. */ boolean editOn = false; public PerspectiveCoordinator() { } @Inject public PerspectiveCoordinator(DisplayerCoordinator coordinator) { this.displayerCoordinator = coordinator; } /** * Adds a Displayer instance to the current perspective context. */ public void addDisplayer(Displayer displayer) { displayerCoordinator.addDisplayer(displayer); } /** * Removes a Displayer instance from the current perspective context. */ public boolean removeDisplayer(Displayer displayer) { return displayerCoordinator.removeDisplayer(displayer); } /** * * @return the current list of displayers */ public List getDisplayerList(){ return displayerCoordinator.getDisplayerList(); } /** * Turn on the edition of the perspective */ public void editOn() { editOn = true; // Turns off the automatic refresh of all the displayers. for (Displayer displayer : displayerCoordinator.getDisplayerList()) { displayer.setRefreshOn(false); } } /** * Turn off the edition of the perspective */ public void editOff() { editOn = false; // Resumes the automatic refresh on all the displayers. for (Displayer displayer : displayerCoordinator.getDisplayerList()) { displayer.setRefreshOn(true); } } /** * Reset the coordinator every time the perspective is changed. */ private void onPerspectiveChanged(@Observes final PerspectiveChange event) { displayerCoordinator.clear(); } /** * Listen to modifications on any of the data set being used in this perspective. */ private void onDataSetModifiedEvent(@Observes DataSetModifiedEvent event) { if (!editOn) { String targetUUID = event.getDataSetDef().getUUID(); for (Displayer displayer : displayerCoordinator.getDisplayerList()) { DisplayerSettings settings = displayer.getDisplayerSettings(); // Do nothing if the displayer: // - Is not drawn // - Is handling the refresh by itself // - Is not configured to be updated on stale data if (!displayer.isDrawn() || displayer.isRefreshOn() || !settings.isRefreshStaleData()) { continue; } String uuid = null; DataSet dataSet = settings.getDataSet(); if (dataSet != null) { uuid = dataSet.getUUID(); } DataSetLookup dataSetLookup = settings.getDataSetLookup(); if (uuid == null && dataSetLookup != null) { uuid = dataSetLookup.getDataSetUUID(); } if (uuid != null && targetUUID.equals(uuid)) { displayer.redraw(); } } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/java/org/dashbuilder/displayer/client/resources/i18n/Constants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface Constants extends Messages { Constants INSTANCE = GWT.create(Constants.class); String menu_button_actions(); String menu_edit(); String menu_clone(); String menu_export_csv(); String menu_export_excel(); String displayer_presenter_displayer_notfound(); String displayer_presenter_export_large_dataset(); String displayer_presenter_export_no_data(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/DisplayerScreen.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants.properties ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # menu_button_actions=Actions menu_edit=Edit menu_clone=Clone menu_export_csv=Export to CSV menu_export_excel=Export to Excel displayer_presenter_displayer_notfound=Displayer settings not found. displayer_presenter_export_large_dataset=The data set about to be exported might be large, no more than 100K rows will be exported. displayer_presenter_export_no_data=No data to export. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants_de.properties ================================================ menu_button_actions=Aktionen menu_edit=Bearbeiten menu_clone=Klonen menu_export_csv=In CSV exportieren menu_export_excel=In Excel exportieren displayer_presenter_displayer_notfound=Displayer-Einstellungen nicht gefunden. displayer_presenter_export_large_dataset=Der zu exportierende Datensatz könnte groß sein, es werden nicht mehr als 100K Reihen exportiert. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants_es.properties ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # menu_button_actions=Acciones menu_edit=Editar menu_clone=Clonar menu_export_csv=Exportar a CSV menu_export_excel=Exportar a Excel displayer_presenter_displayer_notfound=No se encuentran los ajustes de pantalla. displayer_presenter_export_large_dataset=El conjunto de datos a punto de ser exportado podría ser grande; no se exportarán más de 100 000 filas. displayer_presenter_export_no_data=No hay datos para exportar. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants_fr.properties ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # menu_button_actions=Actions menu_edit=Modifier menu_clone=Cloner menu_export_csv=Exporter au format CSV menu_export_excel=Exporter vers Excel displayer_presenter_displayer_notfound=Paramètres de l''afficheur introuvables. displayer_presenter_export_large_dataset=Il se peut que l''ensemble de données qui est sur le point d''être exporté soit trop volumineux ; 100 000 lignes au maximum seront exportées. displayer_presenter_export_no_data=Aucune donnée à exporter. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants_it.properties ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # menu_button_actions=Azioni menu_edit=Modifica menu_clone=Clona menu_export_csv=Esporta in CSV menu_export_excel=Esporta in Excel displayer_presenter_displayer_notfound=Impostazioni del visualizzatore non trovate. displayer_presenter_export_large_dataset=Il set di dati da esportare potrebbe essere grande, verranno esportate al massimo 100.000 righe. displayer_presenter_export_no_data=Nessun dato da esportare. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants_ja.properties ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # menu_button_actions=アクション menu_edit=編集 menu_clone=クローン menu_export_csv=CSVにエクスポート menu_export_excel=Excelにエクスポート displayer_presenter_displayer_notfound=ディスプレイヤー設定が見つかりません。 displayer_presenter_export_large_dataset=エクスポートするデータセットが大きい可能性があります。100K 行超はエクスポートされません。 displayer_presenter_export_no_data=エクスポートするデータがありません ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants_pt_BR.properties ================================================ menu_button_actions=Ações menu_edit=Editar menu_clone=Clonar menu_export_csv=Exportar ao CSV menu_export_excel=Exportar ao Excel displayer_presenter_displayer_notfound=Configurações do exibidor não foi encontrado. displayer_presenter_export_large_dataset=O data set a ser exportado deve ser muito grande, serão exportadas até 100K linhas. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/main/resources/org/dashbuilder/displayer/client/resources/i18n/Constants_zh_CN.properties ================================================ menu_button_actions=动作 menu_edit=编辑 menu_clone=克隆 menu_export_csv=导出到 CSV menu_export_excel=导出到 Excel displayer_presenter_displayer_notfound=未找到显示屏设置 displayer_presenter_export_large_dataset=要导出的数据集可能太大,少于 100K 行数据将被导出。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-displayer-screen/src/test/java/org/dashbuilder/displayer/client/PerspectiveCoordinatorTest.java ================================================ package org.dashbuilder.displayer.client; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class PerspectiveCoordinatorTest { PerspectiveCoordinator coordinator; @Before public void init(){ final RendererManager rendererManager = mock(RendererManager.class); final DisplayerCoordinator displayerCoordinator = new DisplayerCoordinator(rendererManager); coordinator = new PerspectiveCoordinator(displayerCoordinator); } @Test public void testDisplayerList() { assertNotNull(coordinator.getDisplayerList()); assertEquals(0, coordinator.getDisplayerList().size()); final Displayer displayer = mock(Displayer.class); coordinator.addDisplayer(displayer); assertEquals(1, coordinator.getDisplayerList().size()); coordinator.removeDisplayer(displayer); assertEquals(0, coordinator.getDisplayerList().size()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/.gitignore ================================================ /target /local # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject *.ipr *.iws *.iml # Repository wide ignore mac DS_Store files .DS_Store # Bitronix transactin logs *.tlog ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-kie-server-client jar Dashbuilder Kie Server Client org.dashbuilder dashbuilder-kie-server-api org.dashbuilder dashbuilder-client-all provided org.dashbuilder dashbuilder-common-client provided org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-dataset-client provided org.dashbuilder dashbuilder-dataset-client test-jar test org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-client provided org.dashbuilder dashbuilder-displayer-screen provided org.dashbuilder dashbuilder-renderer-default provided org.dashbuilder dashbuilder-validations provided org.dashbuilder dashbuilder-widgets provided org.uberfire uberfire-api org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-client-api org.uberfire uberfire-workbench-client org.uberfire uberfire-workbench-processors provided org.uberfire uberfire-widgets-commons provided org.jboss.errai errai-ui org.jboss.errai errai-ioc org.jboss.errai errai-common org.jboss.errai errai-data-binding com.google.gwt gwt-user provided ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/RemoteDataSetDefAttributesEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor; import com.google.gwt.editor.client.ValueAwareEditor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.kieserver.RemoteDataSetDef; /** *

The GWT editor contract for the specific attributes of type org.jbpm.workbench.ks.integration.RemoteDataSetDef.

*

Used to to edit the following sub-set of attributes:

*
    *
  • queryTarget
  • *
  • dataSource
  • *
  • dbSQL
  • *
*/ public interface RemoteDataSetDefAttributesEditor extends ValueAwareEditor { LeafAttributeEditor queryTarget(); LeafAttributeEditor serverTemplateId(); public ValueBoxEditor dataSource(); LeafAttributeEditor dbSQL(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/RemoteDataSetDefEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.dataset.client.editor.DataSetDefEditor; import org.dashbuilder.kieserver.RemoteDataSetDef; public interface RemoteDataSetDefEditor extends DataSetDefEditor { LeafAttributeEditor queryTarget(); LeafAttributeEditor serverTemplateId(); public ValueBoxEditor dataSource(); LeafAttributeEditor dbSQL(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/RemoteDataSetEditorDriverFactory.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import com.google.gwt.core.client.GWT; import org.dashbuilder.client.kieserver.dataset.editor.driver.RemoteDataSetDefAttributesDriver; import org.dashbuilder.client.kieserver.dataset.editor.driver.RemoteDataSetDefDriver; @ApplicationScoped public class RemoteDataSetEditorDriverFactory { final RemoteDataSetDefAttributesDriver remoteDataSetDefAttributesDriver = GWT.create(RemoteDataSetDefAttributesDriver.class); final RemoteDataSetDefDriver remoteDataSetDefDriver = GWT.create(RemoteDataSetDefDriver.class); @Produces public RemoteDataSetDefDriver remoteDataSetDefDriver() { return remoteDataSetDefDriver; } @Produces public RemoteDataSetDefAttributesDriver remoteDataSetDefAttributesDriver() { return remoteDataSetDefAttributesDriver; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/driver/RemoteDataSetDefAttributesDriver.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.kieserver.dataset.editor.RemoteDataSetDefAttributesEditor; import org.dashbuilder.kieserver.RemoteDataSetDef; /** *

Driver for RemoteDataSetDefAttributesEditor.

* */ public interface RemoteDataSetDefAttributesDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/driver/RemoteDataSetDefDriver.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.kieserver.dataset.editor.RemoteDataSetDefEditor; import org.dashbuilder.kieserver.RemoteDataSetDef; /** *

Driver for RemoteDataSetDefEditor.

* */ public interface RemoteDataSetDefDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/impl/RemoteDataSetDefAttributesEditorImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.impl; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.kieserver.dataset.editor.RemoteDataSetDefAttributesEditor; import org.dashbuilder.client.kieserver.resources.i18n.KieServerClientConstants; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.dashbuilder.kieserver.KieServerConnectionInfoProvider; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.jboss.errai.common.client.api.Caller; import org.uberfire.client.mvp.UberView; /** *

KIE Server/Remote Data Set specific attributes editor presenter.

*/ @Dependent public class RemoteDataSetDefAttributesEditorImpl implements IsWidget, RemoteDataSetDefAttributesEditor { public interface View extends UberView { /** *

Specify the views to use for each sub-editor before calling initWidget.

*/ void initWidgets(DropDownEditor.View queryTarget, DropDownEditor.View serverTemplateId, ValueBoxEditor.View dbSourceName, ValueBoxEditor.View dbSQL); } DropDownEditor queryTarget; DropDownEditor serverTemplateId; ValueBoxEditor dataSource; ValueBoxEditor dbSQL; public View view; private Caller kieServerConnectionInfoProvider; @Inject public RemoteDataSetDefAttributesEditorImpl(final DropDownEditor queryTarget, final DropDownEditor serverTemplateId, final ValueBoxEditor dataSource, final ValueBoxEditor dbSQL, final View view, final Caller specManagementService) { this.queryTarget = queryTarget; this.serverTemplateId = serverTemplateId; this.dataSource = dataSource; this.dbSQL = dbSQL; this.view = view; this.kieServerConnectionInfoProvider = specManagementService; } @PostConstruct public void init() { view.init(this); view.initWidgets(queryTarget.view, serverTemplateId.view, dataSource.view, dbSQL.view); queryTarget.setSelectHint(KieServerClientConstants.INSTANCE.remoteQueryTargetHint()); List entries = Stream.of("CUSTOM", "PROCESS", "TASK", "BA_TASK", "PO_TASK", "JOBS", "FILTERED_PROCESS", "FILTERED_BA_TASK", "FILTERED_PO_TASK") .map(s -> queryTarget.newEntry(s, s)).collect(Collectors.toList()); queryTarget.setEntries(entries); queryTarget.addHelpContent(KieServerClientConstants.INSTANCE.remoteQueryTarget(), KieServerClientConstants.INSTANCE.remoteQueryTargetDescription(), Placement.RIGHT); //bottom placement would interfere with the dropdown serverTemplateId.setSelectHint(KieServerClientConstants.INSTANCE.remoteServerTemplateHint()); kieServerConnectionInfoProvider.call((List serverTemplates) -> onServerTemplateLoad(serverTemplates)).serverTemplates(); serverTemplateId.addHelpContent(KieServerClientConstants.INSTANCE.remoteServerTemplate(), KieServerClientConstants.INSTANCE.remoteServerTemplateDescription(), Placement.RIGHT); dataSource.addHelpContent(KieServerClientConstants.INSTANCE.remoteDataSetEditor(), KieServerClientConstants.INSTANCE.remoteDatasourceDescription(), Placement.BOTTOM); dbSQL.addHelpContent(KieServerClientConstants.INSTANCE.remoteDataSetEditor(), KieServerClientConstants.INSTANCE.remoteDatasourceDescription(), Placement.BOTTOM); } private void onServerTemplateLoad(List templates) { List entries = templates.stream().map(st -> serverTemplateId.newEntry(st, st)).collect(Collectors.toList()); serverTemplateId.setEntries(entries); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public Widget asWidget() { return view.asWidget(); } @Override public DropDownEditor queryTarget() { return queryTarget; } @Override public DropDownEditor serverTemplateId() { return serverTemplateId; } @Override public ValueBoxEditor dataSource() { return dataSource; } @Override public ValueBoxEditor dbSQL() { return dbSQL; } @Override public void flush() { // empty } @Override public void onPropertyChange(final String... paths) { // empty } @Override public void setDelegate(final EditorDelegate delegate) { // No delegation required. } @Override public void setValue(RemoteDataSetDef value) { queryTarget.setValue(value.getQueryTarget()); serverTemplateId.setValue(value.getServerTemplateId()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/impl/RemoteDataSetDefAttributesEditorView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.impl; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; /** *

The KIE Server/Remote Data Set attributes editor view.

* */ @Dependent public class RemoteDataSetDefAttributesEditorView extends Composite implements RemoteDataSetDefAttributesEditorImpl.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } RemoteDataSetDefAttributesEditorImpl presenter; @UiField(provided = true) DropDownEditor.View queryTarget; @UiField(provided = true) DropDownEditor.View serverTemplateId; @UiField(provided = true) ValueBoxEditor.View dataSource; @UiField FlowPanel dbSQLPanel; @UiField(provided = true) ValueBoxEditor.View dbSQL; @Override public void init(final RemoteDataSetDefAttributesEditorImpl presenter) { this.presenter = presenter; } @Override public void initWidgets(final DropDownEditor.View queryTarget, final DropDownEditor.View serverTemplateId, final ValueBoxEditor.View dataSource, final ValueBoxEditor.View dbSQL) { this.queryTarget = queryTarget; this.serverTemplateId = serverTemplateId; this.dataSource = dataSource; this.dbSQL = dbSQL; initWidget(Binder.BINDER.createAndBindUi(this)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/impl/RemoteDataSetDefAttributesEditorView.ui.xml ================================================ .sourceSelectorButton { float: left; margin-right: 10px; } .queryBox { height: 200px; } .row { margin-bottom: 5px; } .attr { float: left; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/impl/RemoteDataSetEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.impl; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.client.kieserver.dataset.editor.RemoteDataSetDefEditor; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.kieserver.RemoteDataSetDef; /** *

KIE Server/Remote Data Set editor presenter.

* */ @Dependent public class RemoteDataSetEditor extends DataSetEditor implements RemoteDataSetDefEditor { RemoteDataSetDefAttributesEditorImpl attributesEditor; @Inject public RemoteDataSetEditor(final DataSetDefBasicAttributesEditor basicAttributesEditor, final RemoteDataSetDefAttributesEditorImpl attributesEditor, final DataSetDefColumnsFilterEditor columnsAndFilterEditor, final DataSetDefPreviewTable previewTable, final DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor, final DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor, final DataSetDefRefreshAttributesEditor refreshEditor, final DataSetClientServices clientServices, final LoadingBox loadingBox, final Event errorEvent, final Event tabChangedEvent, final View view) { super(basicAttributesEditor, attributesEditor.view, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); this.attributesEditor = attributesEditor; } @PostConstruct public void init() { // Initialize the generic data set editor view. super.init(); } public RemoteDataSetDefAttributesEditorImpl getAttributesEditor() { return attributesEditor; } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public DropDownEditor queryTarget() { return attributesEditor.queryTarget(); } @Override public ValueBoxEditor dataSource() { return attributesEditor.dataSource(); } @Override public ValueBoxEditor dbSQL() { return attributesEditor.dbSQL(); } @Override public DropDownEditor serverTemplateId() { return attributesEditor.serverTemplateId(); } @Override public void setValue(RemoteDataSetDef value) { super.setValue(value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/impl/RemoteDataSetEditorPlugin.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.impl; import javax.enterprise.context.Dependent; import com.google.gwt.safehtml.shared.SafeUri; import org.dashbuilder.client.kieserver.dataset.editor.workflow.RemoteDataSetBasicAttributesWorkflow; import org.dashbuilder.client.kieserver.dataset.editor.workflow.RemoteDataSetEditWorkflow; import org.dashbuilder.client.kieserver.resources.i18n.KieServerClientConstants; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.resources.bundles.DataSetClientResources; import org.dashbuilder.kieserver.RuntimeKieServerDataSetProviderType; @Dependent public class RemoteDataSetEditorPlugin implements DataSetEditorPlugin { private static DataSetProviderType TYPE = new RuntimeKieServerDataSetProviderType(); @Override public String getTypeSelectorTitle() { return KieServerClientConstants.INSTANCE.remoteDataSetEditor(); } @Override public String getTypeSelectorText() { return KieServerClientConstants.INSTANCE.remoteDataSetEditorDescription(); } @Override public SafeUri getTypeSelectorImageUri() { return DataSetClientResources.INSTANCE.images().sqlIcon160().getSafeUri(); } @Override public DataSetProviderType getProviderType() { return TYPE; } @Override public Class getBasicAttributesWorkflowClass() { return RemoteDataSetBasicAttributesWorkflow.class; } @Override public Class getWorkflowClass() { return RemoteDataSetEditWorkflow.class; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/validator/RemoteDataSetDefValidator.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.validator; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefDbSQLValidation; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefValidation; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.kieserver.RemoteDataSetDefValidation; import org.dashbuilder.kieserver.RuntimeKieServerDataSetProviderType; import org.dashbuilder.validations.dataset.AbstractDataSetDefValidator; /** *

The singleton application Remote data set definition validator.

*/ @Dependent public class RemoteDataSetDefValidator extends AbstractDataSetDefValidator { @Inject public RemoteDataSetDefValidator(Validator validator) { super(validator); } @Override public DataSetProviderType getSupportedProvider() { return new RuntimeKieServerDataSetProviderType(); } @Override public Iterable> validateCustomAttributes(RemoteDataSetDef dataSetDef, Object... params) { Set> violations = validator.validate(dataSetDef, RemoteDataSetDefValidation.class, SQLDataSetDefValidation.class, SQLDataSetDefDbSQLValidation.class); return toIterable(violations); } @Override public Iterable> validate(RemoteDataSetDef dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params) { Set> _violations = validator.validate(dataSetDef, getValidationGroups(isCacheEnabled, isPushEnabled, isRefreshEnabled, RemoteDataSetDefValidation.class, SQLDataSetDefValidation.class, SQLDataSetDefDbSQLValidation.class)); return toIterable(_violations); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/workflow/RemoteDataSetBasicAttributesWorkflow.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.workflow; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.kieserver.dataset.editor.RemoteDataSetDefAttributesEditor; import org.dashbuilder.client.kieserver.dataset.editor.driver.RemoteDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.DataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetLookupFactory; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.client.DataSetEditHandler; import org.dashbuilder.displayer.client.DataSetHandler; import org.dashbuilder.kieserver.ConsoleDataSetLookup; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

SQL Data Set Editor workflow presenter for setting data set definition basic attributes.

*/ @Dependent public class RemoteDataSetBasicAttributesWorkflow extends DataSetBasicAttributesWorkflow { @Inject public RemoteDataSetBasicAttributesWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefBasicAttributesEditor basicAttributesEditor, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return RemoteDataSetDefAttributesDriver.class; } @Override protected Class getEditorClass() { return RemoteDataSetDefAttributesEditor.class; } @Override protected Iterable> validate() { return validatorProvider.validateAttributes(getDataSetDef()); } @Override public void testDataSet(org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow.TestDataSetCallback testDataSetCallback) { checkDataSetDefNotNull(); // Reset columns and filter configuration. getDataSetDef().setAllColumnsEnabled(true); getDataSetDef().setColumns(null); getDataSetDef().setDataSetFilter(null); DataSetDef editCloneWithoutCacheSettings = getDataSetDef().clone(); editCloneWithoutCacheSettings.setCacheEnabled(false); final DataSetLookup lookup = DataSetLookupFactory.newDataSetLookupBuilder() .dataset(dataSetDef.getUUID()) .rowOffset(0) .rowNumber(10) .buildLookup(); try { DataSetHandler editHandler = new DataSetEditHandler(clientServices, ConsoleDataSetLookup.fromInstance(lookup, getDataSetDef().getServerTemplateId()), editCloneWithoutCacheSettings); editHandler.lookupDataSet(new DataSetReadyCallback() { @Override public void callback(final DataSet dataSet) { getDataSetDef().setColumns(dataSet.getDefinition().getColumns()); testDataSetCallback.onSuccess(dataSet); } @Override public void notFound() { testDataSetCallback.onError(new ClientRuntimeError(DataSetEditorConstants.INSTANCE.defNotFound())); } @Override public boolean onError(final ClientRuntimeError error) { testDataSetCallback.onError(error); return false; } }); } catch (final Exception e) { testDataSetCallback.onError(new ClientRuntimeError(e)); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/dataset/editor/workflow/RemoteDataSetEditWorkflow.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.dataset.editor.workflow; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.kieserver.dataset.editor.RemoteDataSetDefEditor; import org.dashbuilder.client.kieserver.dataset.editor.driver.RemoteDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.DataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.client.DataSetEditHandler; import org.dashbuilder.displayer.client.DataSetHandler; import org.dashbuilder.kieserver.ConsoleDataSetLookup; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

SQL Data Set Editor workflow presenter for editing a data set definition instance.

*

This class is the main entry point for editing an existing data set definition instance. It links the gwt editors with the given driver to perform flushing and validations.

* @since 0.4.0 */ @Dependent public class RemoteDataSetEditWorkflow extends DataSetEditWorkflow { @Inject public RemoteDataSetEditWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override public void testDataSet(TestDataSetCallback testDataSetCallback) { checkDataSetDefNotNull(); // Reset columns and filter configuration. getDataSetDef().setAllColumnsEnabled(true); getDataSetDef().setColumns(null); getDataSetDef().setDataSetFilter(null); DataSetDef editCloneWithoutCacheSettings = getDataSetDef().clone(); editCloneWithoutCacheSettings.setCacheEnabled(false); final DataSetLookup lookup = DataSetFactory.newDataSetLookupBuilder() .dataset(dataSetDef.getUUID()) .rowOffset(0) .rowNumber(10) .buildLookup(); try { DataSetHandler editHandler = new DataSetEditHandler(clientServices, ConsoleDataSetLookup.fromInstance(lookup, getDataSetDef().getServerTemplateId()), editCloneWithoutCacheSettings); editHandler.lookupDataSet(new DataSetReadyCallback() { @Override public void callback(final DataSet dataSet) { getDataSetDef().setColumns(dataSet.getDefinition().getColumns()); testDataSetCallback.onSuccess(dataSet); } @Override public void notFound() { testDataSetCallback.onError(new ClientRuntimeError(DataSetEditorConstants.INSTANCE.defNotFound())); } @Override public boolean onError(final ClientRuntimeError error) { testDataSetCallback.onError(error); return false; } }); } catch (final Exception e) { testDataSetCallback.onError(new ClientRuntimeError(e)); } } @Override protected Class> getDriverClass() { return RemoteDataSetDefDriver.class; } @Override protected Class getEditorClass() { return RemoteDataSetDefEditor.class; } @Override protected Iterable> validate(boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled) { return validatorProvider.validate(dataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/java/org/dashbuilder/client/kieserver/resources/i18n/KieServerClientConstants.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.kieserver.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface KieServerClientConstants extends Messages { public static final KieServerClientConstants INSTANCE = GWT.create(KieServerClientConstants.class); public String remoteDataSetEditor(); public String remoteDataSetEditorDescription(); public String remoteQueryTarget(); public String remoteQueryTargetHint(); public String remoteServerTemplateHint(); public String remoteServerTemplate(); public String remoteServerTemplateDescription(); public String remoteDatasourceDescription(); public String remoteQueryTargetDescription(); public String remoteSourceDescription(); public String remoteQueryPlaceHolder(); public String remoteSqlSource(); public String remoteSqlDatasource(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/META-INF/ErraiApp.properties ================================================ # # Copyright 2012 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/org/dashbuilder/DashbuilderKieServerClient.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/org/dashbuilder/client/kieserver/resources/i18n/KieServerClientConstants.properties ================================================ # # Copyright 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # remoteDataSetEditor=Execution Server remoteDataSetEditorDescription=Execution Server provider allows to consume data via custom queries feature of the Execution Server remoteQueryTarget=Remote query target remoteQueryTargetHint=Select query target remoteServerTemplateHint=Select server configuration remoteServerTemplate=Remote Server Template remoteServerTemplateDescription=Server configuration remoteDatasourceDescription=Data source remoteQueryTargetDescription=Query target that will be executed on Kie Server remoteSourceDescription=The source remoteQueryPlaceHolder=select * from ProcessInstanceLog remoteSqlSource=Source remoteSqlDatasource=Datasource used to run queries ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/org/dashbuilder/client/kieserver/resources/i18n/KieServerClientConstants_es.properties ================================================ # # Copyright 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # remoteDataSetEditor=Servidor de ejecución remoteDataSetEditorDescription=El proveedor del servidor de ejecución permite consumir datos mediante la función de consultas personalizadas del servidor de ejecución remoteQueryTarget=Seleccione el objetivo de la consulta remoteQueryTargetHint=Seleccione el objetivo de la consulta remoteServerTemplateHint=Seleccione la configuración del servidor remoteServerTemplate=Plantilla de servidor remoto remoteServerTemplateDescription=Configuración del servidor remoteDatasourceDescription=Fuente de datos remoteQueryTargetDescription=Objetivo de la consulta que se ejecutará en el servidor Kie remoteSourceDescription=Fuente del nodo remoteQueryPlaceHolder=seleccione * de ProcessInstanceLog remoteSqlSource=Fuente remoteSqlDatasource=Fuente de datos utilizada para ejecutar las consultas ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/org/dashbuilder/client/kieserver/resources/i18n/KieServerClientConstants_fr.properties ================================================ # # Copyright 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # remoteDataSetEditor=Serveur d''exécution remoteDataSetEditorDescription=Le fournisseur du serveur d''exécution autorise la consommation de données via la fonctionnalité de requêtes personnalisées du serveur d''exécution remoteQueryTarget=Cible d''interrogation à distance remoteQueryTargetHint=Sélectionner la cible de la requête remoteServerTemplateHint=Sélectionner la configuration du serveur remoteServerTemplate=Modèle de serveur à distance remoteServerTemplateDescription=Configuration de serveur remoteDatasourceDescription=Source de données remoteQueryTargetDescription=Cible de la requête qui sera exécutée sur le serveur Kie remoteSourceDescription=La source remoteQueryPlaceHolder=sélectionnez * dans ProcessInstanceLog remoteSqlSource=Source remoteSqlDatasource=Source de données utilisée pour effectuer des recherches ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/org/dashbuilder/client/kieserver/resources/i18n/KieServerClientConstants_it.properties ================================================ # # Copyright 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # remoteDataSetEditor=Esecuzione Server remoteDataSetEditorDescription=Il provider Esecuzione Server consente di consumare dati tramite la funzionalità di query personalizzate del Server di Esecuzione remoteQueryTarget=Target di query remoto remoteQueryTargetHint=Seleziona il target di query remoteServerTemplateHint=Seleziona la configurazione del server remoteServerTemplate=Modello Server Remoto remoteServerTemplateDescription=Configurazione del server remoteDatasourceDescription=Base dati remoteQueryTargetDescription=Target di query che verrà eseguito su Kie Server remoteSourceDescription=La Base dati remoteQueryPlaceHolder=seleziona * da ProcessInstanceLog remoteSqlSource=Base dati remoteSqlDatasource=La base dati utilizzata per eseguire le query ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-kie-server-client/src/main/resources/org/dashbuilder/client/kieserver/resources/i18n/KieServerClientConstants_ja.properties ================================================ # # Copyright 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # remoteDataSetEditor=実行サーバー remoteDataSetEditorDescription=実行サーバープロバイダーは、実行サーバーのカスタムクエリー機能でデータを使用できるようにします。 remoteQueryTarget=リモートクエリーターゲット remoteQueryTargetHint=クエリーターゲットを選択してください remoteServerTemplateHint=サーバー設定を選択してください remoteServerTemplate=リモートサーバーテンプレート remoteServerTemplateDescription=サーバー設定 remoteDatasourceDescription=データソース remoteQueryTargetDescription=KIE Server で実行されるクエリーターゲット remoteSourceDescription=ソース remoteQueryPlaceHolder=select * from ProcessInstanceLog remoteSqlSource=ソース remoteSqlDatasource=クエリーの実行に使用されるデータソース ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-navigation-client jar Dashbuilder Navigation Client Dashbuilder Navigation Client org.dashbuilder dashbuilder-common-client provided org.dashbuilder dashbuilder-navigation-api org.jboss.errai errai-common org.jboss.errai errai-bus org.jboss.errai errai-ioc org.jboss.errai errai-ui org.uberfire uberfire-api org.uberfire uberfire-client-api org.uberfire uberfire-workbench-client provided org.uberfire uberfire-widgets-commons provided org.uberfire uberfire-widgets-security-management provided org.uberfire uberfire-servlet-security org.uberfire uberfire-layout-editor-api org.uberfire uberfire-layout-editor-client org.uberfire uberfire-runtime-plugins-api org.uberfire uberfire-runtime-plugins-client org.uberfire uberfire-commons-editor-client org.dashbuilder dashbuilder-widgets com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 com.google.gwt.gwtmockito gwtmockito test org.uberfire uberfire-testing-utils test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/NavBarHelper.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuFactory.MenuBuilder; import org.uberfire.workbench.model.menu.MenuFactory.TopLevelMenusBuilder; import org.uberfire.workbench.model.menu.MenuItem; @ApplicationScoped public class NavBarHelper { // code taken from DefaultWorkbenchFeaturesMenusHelper public TopLevelMenusBuilder buildMenusFromNavTree(NavTree navTree) { if (navTree == null) { return null; } MenuBuilder> builder = null; for (NavItem navItem : navTree.getRootItems()) { // Skip dividers if (navItem instanceof NavDivider) { continue; } // AF-953: Ignore empty groups if (navItem instanceof NavGroup && ((NavGroup) navItem).getChildren().isEmpty()) { continue; } // Build a top level menu entry if (builder == null) { builder = MenuFactory.newTopLevelMenu(navItem.getName()); } else { builder = builder.endMenu().newTopLevelMenu(navItem.getName()); } // Append its children if (navItem instanceof NavGroup) { List childItems = buildMenuItemsFromNavGroup((NavGroup) navItem); if (!childItems.isEmpty()) { builder.withItems(childItems); } } // Append the place request NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); if (navCtx.getResourceId() != null && ActivityResourceType.PERSPECTIVE.equals(navCtx.getResourceType())) { PlaceRequest placeRequest = resolvePlaceRequest(navCtx.getResourceId()); builder = builder.place(placeRequest); } } return builder != null ? builder.endMenu() : null; } private List buildMenuItemsFromNavGroup(NavGroup navGroup) { List result = new ArrayList<>(); for (NavItem navItem : navGroup.getChildren()) { // Skip dividers if (navItem instanceof NavDivider) { continue; } // Append its children MenuBuilder builder = MenuFactory.newSimpleItem(navItem.getName()); if (navItem instanceof NavGroup) { List childItems = buildMenuItemsFromNavGroup((NavGroup) navItem); if (!childItems.isEmpty()) { builder.withItems(childItems); } } // Append the place request NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); if (navCtx.getResourceId() != null && ActivityResourceType.PERSPECTIVE.equals(navCtx.getResourceType())) { PlaceRequest placeRequest = resolvePlaceRequest(navCtx.getResourceId()); builder.place(placeRequest); } // Build the menu item & continue with the next one MenuItem menuItem = builder.endMenu().build().getItems().get(0); result.add(menuItem); } return result; } public PlaceRequest resolvePlaceRequest(String perspectiveId) { return new DefaultPlaceRequest(perspectiveId); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/NavigationManager.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation; import java.util.List; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.uberfire.mvp.Command; public interface NavigationManager { void init(Command afterInit); void setDefaultNavTree(NavTree navTree); NavTree getDefaultNavTree(); NavTree getNavTree(); boolean hasNavTree(); void saveNavTree(NavTree navTree, Command afterSave); NavTree secure(NavTree navTree, boolean removeEmptyGroups); void secure(List itemList, boolean removeEmptyGroups); void navItemClicked(NavItem navItem); void update(NavTree navTree); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/event/NavItemEditCancelledEvent.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.event; import org.dashbuilder.client.navigation.widget.editor.NavItemEditor; /** * Event fired when a {@link NavItemEditor} cancels the edition of an item */ public class NavItemEditCancelledEvent { private NavItemEditor navItemEditor; public NavItemEditCancelledEvent(NavItemEditor navItemEditor) { this.navItemEditor = navItemEditor; } public NavItemEditor getNavItemEditor() { return navItemEditor; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/event/NavItemEditStartedEvent.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.event; import org.dashbuilder.client.navigation.widget.editor.NavItemEditor; /** * Event fired when a {@link NavItemEditor} starts the edition of an item */ public class NavItemEditStartedEvent { private NavItemEditor navItemEditor; public NavItemEditStartedEvent(NavItemEditor navItemEditor) { this.navItemEditor = navItemEditor; } public NavItemEditor getNavItemEditor() { return navItemEditor; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/event/NavItemGotoEvent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.event; import org.dashbuilder.client.navigation.widget.NavWidget; import org.dashbuilder.navigation.NavItem; /** * Event fired when a {@link NavItem} has been clicked on a {@link NavWidget} */ public class NavItemGotoEvent { private NavItem navItem; public NavItemGotoEvent(NavItem navItem) { this.navItem = navItem; } public NavItem getNavItem() { return navItem; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/event/NavTreeLoadedEvent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.event; import org.dashbuilder.navigation.NavTree; /** * Event fired when the application navigation tree is loaded from backend */ public class NavTreeLoadedEvent { private NavTree navTree; public NavTreeLoadedEvent(NavTree navTree) { this.navTree = navTree; } public NavTree getNavTree() { return navTree; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/impl/NavigationManagerImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.impl; import java.util.List; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.event.NavItemGotoEvent; import org.dashbuilder.navigation.event.NavTreeChangedEvent; import org.dashbuilder.client.navigation.event.NavTreeLoadedEvent; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.service.NavigationServices; import org.dashbuilder.navigation.workbench.NavSecurityController; import org.jboss.errai.common.client.api.Caller; import org.uberfire.mvp.Command; @ApplicationScoped public class NavigationManagerImpl implements NavigationManager { private Caller navServices; private Event navItemGotoEvent; private Event navTreeLoadedEvent; private Event navTreeChangedEvent; private NavSecurityController navController; private NavTree navTree; private NavTree defaultNavTree; @Inject public NavigationManagerImpl(Caller navServices, NavSecurityController navController, Event navTreeLoadedEvent, Event navTreeChangedEvent, Event navItemGotoEvent) { this.navServices = navServices; this.navController = navController; this.navTreeLoadedEvent = navTreeLoadedEvent; this.navTreeChangedEvent = navTreeChangedEvent; this.navItemGotoEvent = navItemGotoEvent; } @Override public void init(Command afterInit) { navServices.call((NavTree n) -> { navTree = n; if (afterInit != null) { afterInit.execute(); } navTreeLoadedEvent.fire(new NavTreeLoadedEvent(getNavTree())); }).loadNavTree(); } @Override public NavTree getDefaultNavTree() { return defaultNavTree; } @Override public void setDefaultNavTree(NavTree defaultNavTree) { this.defaultNavTree = defaultNavTree; } @Override public NavTree getNavTree() { return !hasNavTree() ? defaultNavTree : navTree; } @Override public boolean hasNavTree() { return Optional.ofNullable(navTree).isPresent(); } @Override public void saveNavTree(NavTree newTree, Command afterSave) { navServices.call((Void v) -> { navTree = newTree; navTreeChangedEvent.fire(new NavTreeChangedEvent(newTree)); if (afterSave != null) { afterSave.execute(); } }).saveNavTree(newTree); } @Override public NavTree secure(NavTree navTree, boolean removeEmptyGroups) { return navController.secure(navTree, removeEmptyGroups); } @Override public void secure(List itemList, boolean removeEmptyGroups) { navController.secure(itemList, removeEmptyGroups); } @Override public void navItemClicked(NavItem navItem) { if (navController.canRead(navItem)) { navItemGotoEvent.fire(new NavItemGotoEvent(navItem)); } } @Override public void update(NavTree navTree) { this.defaultNavTree = navTree; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/layout/editor/AbstractNavDragComponent.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.layout.editor; import java.util.Collections; import java.util.List; import java.util.Map; import javax.enterprise.event.Observes; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.navigation.event.NavTreeChangedEvent; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.widget.HasDefaultNavItem; import org.dashbuilder.client.navigation.widget.HasTargetDiv; import org.dashbuilder.client.navigation.widget.NavComponentConfigModal; import org.dashbuilder.client.navigation.widget.NavComponentConfigModalView; import org.dashbuilder.client.navigation.widget.NavWidget; import org.dashbuilder.client.navigation.widget.TargetDivNavWidget; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavTree; import org.gwtbootstrap3.client.ui.Modal; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.layout.editor.client.api.ModalConfigurationContext; import org.uberfire.ext.layout.editor.client.api.RenderingContext; import org.uberfire.ext.plugin.client.perspective.editor.layout.editor.TargetDivList; import static org.dashbuilder.navigation.layout.NavDragComponentSettings.*; public abstract class AbstractNavDragComponent implements NavDragComponent { NavigationManager navigationManager; PerspectivePluginManager pluginManager; NavComponentConfigModal navComponentConfigModal; NavWidget navWidget; String navGroupId = null; LayoutTemplate layoutTemplate; public AbstractNavDragComponent() { } public AbstractNavDragComponent(NavigationManager navigationManager, PerspectivePluginManager pluginManager, NavComponentConfigModal navComponentConfigModal, NavWidget navWidget) { this.navigationManager = navigationManager; this.pluginManager = pluginManager; this.navComponentConfigModal = navComponentConfigModal; this.navWidget = navWidget; this.navWidget.setOnStaleCommand(this::showNavWidget); } @Override public NavWidget getNavWidget() { return navWidget; } @Override public IsWidget getPreviewWidget(RenderingContext ctx) { return getShowWidget(ctx); } @Override public IsWidget getShowWidget(RenderingContext ctx) { Map properties = ctx.getComponent().getProperties(); // Nav group settings NavGroup navGroup = pluginManager.getLastBuildPerspectiveNavGroup(); navGroupId = navGroup != null ? navGroup.getId() : properties.get(NAV_GROUP_ID); navWidget.setHideEmptyGroups(true); // Default item settings if (navWidget instanceof HasDefaultNavItem) { String navItemId = properties.get(NAV_DEFAULT_ID); ((HasDefaultNavItem) navWidget).setDefaultNavItemId(navItemId); } // Target div settings if (navWidget instanceof HasTargetDiv) { String targetDivId = properties.get(TARGET_DIV_ID); ((HasTargetDiv) navWidget).setTargetDivId(targetDivId); ((HasTargetDiv) navWidget).setGotoItemEnabled(true); } this.showNavWidget(); return navWidget; } @Override public Modal getConfigurationModal(ModalConfigurationContext ctx) { List targetDivIdList = TargetDivList.list(ctx.getCurrentLayoutTemplate()); navComponentConfigModal.clear(); navComponentConfigModal.setTargetDivIdList(targetDivIdList); // Nav group settings NavTree navTree = navigationManager.getNavTree(); String groupId = ctx.getComponentProperty(NAV_GROUP_ID); navComponentConfigModal.setNavGroup(navTree.getRootItems(), navTree.getItemById(groupId) != null ? groupId : null); navComponentConfigModal.setNavGroupHelpHint(getDragComponentNavGroupHelp()); // Default item settings boolean supportsDefaultNavItem = navWidget instanceof HasDefaultNavItem; navComponentConfigModal.setDefaultNavItemSupported(supportsDefaultNavItem); if (supportsDefaultNavItem) { String navItemId = ctx.getComponentProperty(NAV_DEFAULT_ID); navComponentConfigModal.setDefaultNavItemId(navItemId); } // Target div settings boolean supportsTargetDiv = navWidget instanceof HasTargetDiv; navComponentConfigModal.setTargetDivSupported(supportsTargetDiv); if (supportsTargetDiv) { String targetDivId = ctx.getComponentProperty(TARGET_DIV_ID); navComponentConfigModal.setTargetDiv(targetDivId); layoutTemplate = ctx.getCurrentLayoutTemplate(); } navComponentConfigModal.setOnOk(() -> navConfigOk(ctx, supportsDefaultNavItem, supportsTargetDiv)); navComponentConfigModal.setOnCancel(() -> navConfigCancel(ctx)); navComponentConfigModal.show(); return ((NavComponentConfigModalView) navComponentConfigModal.getView()).getModal(); } @Override public void dispose() { navWidget.dispose(); } protected void showNavWidget() { if (navGroupId != null) { NavGroup navGroup = (NavGroup) navigationManager.getNavTree().getItemById(navGroupId); navWidget.show(navGroup); } else { navWidget.show(Collections.emptyList()); } } protected void navConfigOk(ModalConfigurationContext ctx, boolean supportsDefaultNavItem, boolean supportsTargetDiv) { navGroupId = navComponentConfigModal.getGroupId(); if (navGroupId != null) { ctx.setComponentProperty(NAV_GROUP_ID, navGroupId); } else { ctx.removeComponentProperty(NAV_GROUP_ID); } String defaultItemId = navComponentConfigModal.getDefaultItemId(); if (supportsDefaultNavItem && defaultItemId != null) { ctx.setComponentProperty(NAV_DEFAULT_ID, defaultItemId); } else { ctx.removeComponentProperty(NAV_DEFAULT_ID); } String targetDivId = navComponentConfigModal.getTargetDivId(); if (supportsTargetDiv && targetDivId != null) { ctx.setComponentProperty(TARGET_DIV_ID, targetDivId); checkLayoutTemplate(); } else { ctx.removeComponentProperty(TARGET_DIV_ID); } ctx.configurationFinished(); } protected void navConfigCancel(ModalConfigurationContext ctx) { ctx.configurationCancelled(); } protected void checkLayoutTemplate() { if ((navWidget instanceof TargetDivNavWidget) && layoutTemplate != null) { pluginManager.getLayoutTemplateInfo(layoutTemplate, layoutTemplateInfo -> { if (!layoutTemplateInfo.getRecursionIssue().isEmpty()) { TargetDivNavWidget targetDivNavWidget = (TargetDivNavWidget) navWidget; targetDivNavWidget.onInfiniteRecursion(layoutTemplateInfo.getRecursionIssue()); } }); } } // Check the layout template every time the navigation tree changes public void onNavTreeChanged(@Observes final NavTreeChangedEvent event) { checkLayoutTemplate(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/layout/editor/NavCarouselDragComponent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.layout.editor; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.client.navigation.widget.NavCarouselWidget; import org.dashbuilder.client.navigation.widget.NavComponentConfigModal; /** * A layout editor's navigation component that a carousel of runtime perspectives */ @Dependent public class NavCarouselDragComponent extends AbstractNavDragComponent { @Inject public NavCarouselDragComponent(NavigationManager navigationManager, PerspectivePluginManager pluginManager, NavComponentConfigModal navComponentConfigModal, NavCarouselWidget navWidget) { super(navigationManager, pluginManager, navComponentConfigModal, navWidget); } @Override public String getDragComponentTitle() { return NavigationConstants.INSTANCE.navCarouselDragComponent(); } @Override public String getDragComponentNavGroupHelp() { return NavigationConstants.INSTANCE.navCarouselDragComponentNavGroupHelp(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/layout/editor/NavDragComponent.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.layout.editor; import org.dashbuilder.client.navigation.widget.NavWidget; import org.uberfire.ext.layout.editor.client.api.HasModalConfiguration; import org.uberfire.ext.plugin.client.perspective.editor.api.PerspectiveEditorNavComponent; public interface NavDragComponent extends PerspectiveEditorNavComponent, HasModalConfiguration { NavWidget getNavWidget(); String getDragComponentNavGroupHelp(); void dispose(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/layout/editor/NavMenuBarDragComponent.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.layout.editor; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.client.navigation.widget.NavComponentConfigModal; import org.dashbuilder.client.navigation.widget.NavMenuBarWidget; /** * A layout editor's navigation component that displays the entries under a given nav tree node as a menu bar */ @Dependent public class NavMenuBarDragComponent extends AbstractNavDragComponent { @Inject public NavMenuBarDragComponent(NavigationManager navigationManager, PerspectivePluginManager pluginManager, NavComponentConfigModal navComponentConfigModal, NavMenuBarWidget navWidget) { super(navigationManager, pluginManager, navComponentConfigModal, navWidget); } @Override public String getDragComponentTitle() { return NavigationConstants.INSTANCE.navMenubarDragComponent(); } @Override public String getDragComponentNavGroupHelp() { return NavigationConstants.INSTANCE.navMenubarDragComponentNavGroupHelp(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/layout/editor/NavTabListDragComponent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.layout.editor; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.client.navigation.widget.NavComponentConfigModal; import org.dashbuilder.client.navigation.widget.NavTabListWidget; /** * A layout editor's navigation component that shows a list of tabs providing links to workbench assets */ @Dependent public class NavTabListDragComponent extends AbstractNavDragComponent { @Inject public NavTabListDragComponent(NavigationManager navigationManager, PerspectivePluginManager pluginManager, NavComponentConfigModal navComponentConfigModal, NavTabListWidget navWidget) { super(navigationManager, pluginManager, navComponentConfigModal, navWidget); } @Override public String getDragComponentTitle() { return NavigationConstants.INSTANCE.navTabListDragComponent(); } @Override public String getDragComponentNavGroupHelp() { return NavigationConstants.INSTANCE.navTabListDragComponentNavGroupHelp(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/layout/editor/NavTilesDragComponent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.layout.editor; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.client.navigation.widget.NavComponentConfigModal; import org.dashbuilder.client.navigation.widget.NavTilesWidget; /** * A layout editor's navigation component that shows a navigation group structure using two tile types: folders * (for nav group items) and links to perspective items. * @see NavTilesWidget */ @Dependent public class NavTilesDragComponent extends AbstractNavDragComponent { @Inject public NavTilesDragComponent(NavigationManager navigationManager, PerspectivePluginManager pluginManager, NavComponentConfigModal navComponentConfigModal, NavTilesWidget navWidget) { super(navigationManager, pluginManager, navComponentConfigModal, navWidget); this.navWidget.setHideEmptyGroups(true); } @Override public String getDragComponentTitle() { return NavigationConstants.INSTANCE.navTilesDragComponent(); } @Override public String getDragComponentNavGroupHelp() { return NavigationConstants.INSTANCE.navTilesDragComponentNavGroupHelp(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/layout/editor/NavTreeDragComponent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.layout.editor; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.client.navigation.widget.NavComponentConfigModal; import org.dashbuilder.client.navigation.widget.NavTreeWidget; @Dependent public class NavTreeDragComponent extends AbstractNavDragComponent { @Inject public NavTreeDragComponent(NavigationManager navigationManager, PerspectivePluginManager pluginManager, NavComponentConfigModal navComponentConfigModal, NavTreeWidget navWidget) { super(navigationManager, pluginManager, navComponentConfigModal, navWidget); } @Override public String getDragComponentTitle() { return NavigationConstants.INSTANCE.navTreeDragComponent(); } @Override public String getDragComponentNavGroupHelp() { return NavigationConstants.INSTANCE.navTreeDragComponentNavGroupHelp(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/plugin/PerspectivePluginEntryPoint.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.plugin; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.jboss.errai.ioc.client.api.EntryPoint; @EntryPoint @ApplicationScoped public class PerspectivePluginEntryPoint { @Inject PerspectivePluginManager perspectivePluginManager; @PostConstruct private void init() { perspectivePluginManager.loadPlugins(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/plugin/PerspectivePluginManager.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.plugin; import java.util.Collection; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.layout.LayoutTemplateInfo; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.mvp.ParameterizedCommand; public interface PerspectivePluginManager { void loadPlugins(); void getPerspectivePlugins(ParameterizedCommand> callback); boolean isRuntimePerspective(Plugin plugin); boolean isRuntimePerspective(NavItem navItem); boolean isRuntimePerspective(String perspectiveId); String getRuntimePerspectiveId(NavItem navItem); boolean existsPerspectivePlugin(String perspectiveName); void getLayoutTemplateInfo(String perspectiveName, ParameterizedCommand callback); void getLayoutTemplateInfo(LayoutTemplate layoutTemplate, ParameterizedCommand callback); void buildPerspectiveWidget(String perspectiveName, LayoutTemplateContext layoutCtx, ParameterizedCommand afterBuild, ParameterizedCommand onInfiniteRecursion); default void buildPerspectiveWidget(String perspectiveName, ParameterizedCommand afterBuild, ParameterizedCommand onInfiniteRecursion) { buildPerspectiveWidget(perspectiveName, null, afterBuild, onInfiniteRecursion); } NavGroup getLastBuildPerspectiveNavGroup(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/plugin/PerspectivePluginManagerImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.plugin; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.navigation.event.PerspectivePluginsChangedEvent; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.layout.LayoutTemplateInfo; import org.dashbuilder.navigation.service.PerspectivePluginServices; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.jboss.errai.ioc.client.api.EntryPoint; import org.uberfire.client.workbench.type.ClientResourceType; import org.uberfire.client.workbench.type.ClientTypeRegistry; import org.uberfire.ext.layout.editor.api.editor.LayoutInstance; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.layout.editor.client.generator.LayoutGenerator; import org.uberfire.ext.plugin.client.type.PerspectiveLayoutPluginResourceType; import org.uberfire.ext.plugin.event.PluginAdded; import org.uberfire.ext.plugin.event.PluginDeleted; import org.uberfire.ext.plugin.event.PluginRenamed; import org.uberfire.ext.plugin.event.PluginSaved; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.workbench.model.ActivityResourceType; import com.google.gwt.user.client.ui.IsWidget; @EntryPoint @ApplicationScoped public class PerspectivePluginManagerImpl implements PerspectivePluginManager { private ClientTypeRegistry clientTypeRegistry; private LayoutGenerator layoutGenerator; private NavigationManager navigationManager; private Caller pluginServices; private Event perspectivesChangedEvent; private Map pluginMap = new HashMap<>(); private boolean pluginsLoaded = false; private Stack navGroupStack = new Stack<>(); @Inject public PerspectivePluginManagerImpl(ClientTypeRegistry clientTypeRegistry, LayoutGenerator layoutGenerator, NavigationManager navigationManager, Caller pluginServices, Event perspectivesChangedEvent) { this.clientTypeRegistry = clientTypeRegistry; this.layoutGenerator = layoutGenerator; this.navigationManager = navigationManager; this.pluginServices = pluginServices; this.perspectivesChangedEvent = perspectivesChangedEvent; } @Override public void getPerspectivePlugins(ParameterizedCommand> callback) { loadPlugins(callback); } @Override public boolean isRuntimePerspective(Plugin plugin) { ClientResourceType type = clientTypeRegistry.resolve(plugin.getPath()); return type != null && type instanceof PerspectiveLayoutPluginResourceType; } @Override public boolean isRuntimePerspective(NavItem navItem) { return getRuntimePerspectiveId(navItem) != null; } @Override public boolean isRuntimePerspective(String perspectiveId) { return pluginMap.containsKey(perspectiveId); } @Override public String getRuntimePerspectiveId(NavItem navItem) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); String resourceId = navCtx.getResourceId(); ActivityResourceType resourceType = navCtx.getResourceType(); boolean isRuntimePerspective = resourceId != null && ActivityResourceType.PERSPECTIVE.equals(resourceType) && isRuntimePerspective(resourceId); return isRuntimePerspective ? resourceId : null; } @Override public boolean existsPerspectivePlugin(String perspectiveName) { return perspectiveName != null && pluginMap.get(perspectiveName) != null; } @Override public void getLayoutTemplateInfo(String perspectiveName, ParameterizedCommand callback) { pluginServices.call((RemoteCallback) callback::execute).getLayoutTemplateInfo(perspectiveName); } @Override public void getLayoutTemplateInfo(LayoutTemplate layoutTemplate, ParameterizedCommand callback) { pluginServices.call((RemoteCallback) callback::execute).getLayoutTemplateInfo(layoutTemplate); } @Override public void buildPerspectiveWidget(String perspectiveName, LayoutTemplateContext layoutCtx, ParameterizedCommand afterBuild, ParameterizedCommand onInfiniteRecursion) { Plugin plugin = pluginMap.get(perspectiveName); pluginServices.call((LayoutTemplateInfo layoutInfo) -> { if (!layoutInfo.getRecursionIssue().isEmpty()) { onInfiniteRecursion.execute(layoutInfo.getRecursionIssue()); } else { String navGroupId = layoutCtx != null && layoutCtx.getNavGroupId() != null ? layoutCtx.getNavGroupId() : null; NavGroup navGroup = navGroupId != null ? (NavGroup) navigationManager.getNavTree().getItemById(navGroupId) : null; try { if (navGroup != null) { navGroupStack.push(navGroup); } LayoutInstance result = layoutGenerator.build(layoutInfo.getLayoutTemplate()); IsWidget widget = ElementWrapperWidget.getWidget(result.getElement()); afterBuild.execute(widget); } finally { if (navGroup != null) { navGroupStack.pop(); } } } }).getLayoutTemplateInfo(plugin, layoutCtx); } /** * Get the last nav group instance passed to the execution of a {@link #buildPerspectiveWidget(String, LayoutTemplateContext, ParameterizedCommand, ParameterizedCommand)} call. * * @return The {@link NavGroup} instance passed to the build method or null if none. */ @Override public NavGroup getLastBuildPerspectiveNavGroup() { return navGroupStack.isEmpty() ? null : navGroupStack.peek(); } // Sync up both the internals plugin & widget registry public void onPlugInAdded(@Observes final PluginAdded event) { Plugin plugin = event.getPlugin(); if (isRuntimePerspective(plugin)) { pluginMap.put(plugin.getName(), plugin); perspectivesChangedEvent.fire(new PerspectivePluginsChangedEvent()); } } public void onPlugInSaved(@Observes final PluginSaved event) { Plugin plugin = event.getPlugin(); if (isRuntimePerspective(plugin)) { pluginMap.put(plugin.getName(), plugin); perspectivesChangedEvent.fire(new PerspectivePluginsChangedEvent()); } } public void onPlugInRenamed(@Observes final PluginRenamed event) { Plugin plugin = event.getPlugin(); if (isRuntimePerspective(plugin)) { pluginMap.remove(event.getOldPluginName()); pluginMap.put(plugin.getName(), plugin); NavWorkbenchCtx ctx = NavWorkbenchCtx.perspective(event.getOldPluginName()); NavWorkbenchCtx newCtx = NavWorkbenchCtx.perspective(event.getPlugin().getName()); List itemsToRename = navigationManager.getNavTree().searchItems(ctx); for (NavItem navItem : itemsToRename) { navItem.setContext(newCtx.toString()); } if (!itemsToRename.isEmpty()) { navigationManager.saveNavTree(navigationManager.getNavTree(), () -> { }); } perspectivesChangedEvent.fire(new PerspectivePluginsChangedEvent()); } } public void onPlugInDeleted(@Observes final PluginDeleted event) { String pluginName = event.getPluginName(); pluginMap.remove(pluginName); NavWorkbenchCtx ctx = NavWorkbenchCtx.perspective(pluginName); NavTree navTree = navigationManager.getNavTree(); List itemsToDelete = navTree.searchItems(ctx); for (NavItem item : itemsToDelete) { navTree.deleteItem(item.getId()); } if (!itemsToDelete.isEmpty()) { navigationManager.saveNavTree(navTree, null); } perspectivesChangedEvent.fire(new PerspectivePluginsChangedEvent()); } @Override public void loadPlugins() { loadPlugins(plugins -> { }); } private void loadPlugins(ParameterizedCommand> callback) { if (pluginsLoaded) { callback.execute(pluginMap.values()); } else { pluginServices.call(((Collection plugins) -> { pluginMap.clear(); plugins.stream().filter(this::isRuntimePerspective).forEach(p -> pluginMap.put(p.getName(), p)); pluginsLoaded = true; callback.execute(pluginMap.values()); })).listPlugins(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface NavigationConstants extends Messages { NavigationConstants INSTANCE = GWT.create(NavigationConstants.class); String newItem(String itemName); String newItemName(String itemName); String itemMenuTitle(); String editItem(); String deleteItem(); String pageIconTitle(); String perspectiveIconTitle(); String moveUp(); String moveDown(); String moveFirst(); String moveLast(); String gotoItem(String itemName); String saveChanges(); String save(); String cancel(); String navMenubarDragComponent(); String navTabListDragComponent(); String navTreeDragComponent(); String navTilesDragComponent(); String navCarouselDragComponent(); String navMenubarDragComponentNavGroupHelp(); String navTabListDragComponentNavGroupHelp(); String navTreeDragComponentNavGroupHelp(); String navTilesDragComponentNavGroupHelp(); String navCarouselDragComponentNavGroupHelp(); String navGroupEmptyError(); String navCarouselDragComponentEmptyError(); String navTilesDragComponentInfiniteRecursion(); String navCarouselDragComponentInfiniteRecursion(); String targetDivIdPerspectiveInfiniteRecursion(); String navWidgetTargetDivMissing(); String navGroupNotFound(); String navItemsEmpty(); String openNavItem(String itemName); String gotoNavItem(String itemName); String showNavItem(String itemName); String navConfigHeader(); String navGroupLabel(); String navGroupHelp(); String navGroupSelectorHint(); String defaultItemLabel(); String defaultItemHelp(); String defaultItemSelectorHint(); String defaultItemsNotFound(); String targetDivLabel(); String targetDivHelp(); String targetDivSelectorHint(); String targetDivsNotFound(); String navItemEditorPerspectiveHelp(); String navItemEditorGroupHelp(); String navRefPerspective(String name); String navRefGroupDefined(String name); String navRefGroupContext(String name); String navRefPerspectiveFound(String name); String navRefPerspectiveDefault(String name); String navRefPerspectiveInGroup(String name); String navRefComponent(String name); String navRefDefaultItemDefined(String name); String navRefDefaultItemFound(String name); String navRefPerspectiveRecursionEnd(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/BaseNavWidget.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.ArrayList; import java.util.List; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.navigation.event.NavTreeChangedEvent; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.uberfire.ext.security.management.client.widgets.management.events.SaveGroupEvent; import org.uberfire.ext.security.management.client.widgets.management.events.SaveRoleEvent; import org.uberfire.mvp.Command; public abstract class BaseNavWidget implements NavWidget { NavigationManager navigationManager; boolean secure = true; boolean hideEmptyGroups = true; Command onItemSelectedCommand; Command onStaleCommand; NavItem itemSelected; NavGroup navGroup; NavWidget parent; NavWidgetView view; int maxLevels = -1; List navItemList = null; NavWidget activeNavSubgroup = null; List navSubgroupList = new ArrayList<>(); @Inject public BaseNavWidget(NavWidgetView view, NavigationManager navigationManager) { this.view = view; this.navigationManager = navigationManager; view.init(this); } public NavigationManager getNavigationManager() { return navigationManager; } @Override public Widget asWidget() { return view.asWidget(); } @Override public void setSecure(boolean secure) { this.secure = secure; } @Override public void setHideEmptyGroups(boolean hide) { this.hideEmptyGroups = hide; } @Override public void setOnItemSelectedCommand(Command onItemSelected) { this.onItemSelectedCommand = onItemSelected; } @Override public void setOnStaleCommand(Command onStaleCommand) { this.onStaleCommand = onStaleCommand; } public NavItem getItem(String id) { if (navItemList == null || id == null) { return null; } for (NavItem navItem : navItemList) { if (id.equals(navItem.getId())) { return navItem; } } return null; } @Override public int getLevel() { int level = 0; NavWidget root = parent; while (root != null) { level++; root = root.getParent(); } return level; } @Override public NavWidget getParent() { return parent; } @Override public void setParent(NavWidget parent) { this.parent = parent; } @Override public int getMaxLevels() { return maxLevels; } @Override public void setMaxLevels(int maxLevels) { this.maxLevels = maxLevels; } @Override public NavGroup getNavGroup() { return navGroup; } public boolean areSubGroupsSupported() { return maxLevels < 1 || getLevel() < maxLevels-1; } protected NavWidget getSubgroupNavWidget(String groupId) { for (NavWidget navWidget : navSubgroupList) { if (navWidget.getNavGroup().getId().equals(groupId)) { return navWidget; } } return null; } protected NavWidget lookupNavGroupWidget() { return null; } @Override public void hide() { view.clearItems(); navSubgroupList.forEach(NavWidget::hide); } @Override public void show(NavGroup navGroup) { this.navGroup = navGroup; if (navGroup == null) { view.errorNavGroupNotFound(); } else { this.show(navGroup.getChildren()); } } @Override public void show(NavTree navTree) { if (navTree == null) { view.errorNavItemsEmpty(); } else { this.show(navTree.getRootItems()); } } @Override public void show(List itemList) { this.hide(); this.navItemList = itemList; this.navSubgroupList.clear(); // Make sure the items shown comply with the authz policy defined if (secure) { navItemList = new ArrayList<>(itemList); navigationManager.secure(navItemList, hideEmptyGroups); } if (navItemList.isEmpty()) { view.errorNavItemsEmpty(); } for (NavItem navChild : navItemList) { // A subgroup if (navChild instanceof NavGroup) { // Ensure to not exceed the maximum number of levels if (areSubGroupsSupported()) { showGroup((NavGroup) navChild); } else { showItem(navChild); } } // A divider else if (navChild instanceof NavDivider) { view.addDivider(); } // A regular item else { showItem(navChild); } } } protected void showGroup(NavGroup navGroup) { NavWidget subGroupNavWidget = lookupNavGroupWidget(); if (subGroupNavWidget != null) { subGroupNavWidget.setParent(this); subGroupNavWidget.setMaxLevels(maxLevels > 0 ? maxLevels - 1 : -1); subGroupNavWidget.setSecure(secure); subGroupNavWidget.setHideEmptyGroups(hideEmptyGroups); subGroupNavWidget.setOnItemSelectedCommand(() -> onSubGroupItemClicked(subGroupNavWidget)); subGroupNavWidget.show(navGroup); navSubgroupList.add(subGroupNavWidget); view.addGroupItem(navGroup.getId(), navGroup.getName(), navGroup.getDescription(), subGroupNavWidget); } } protected void showItem(NavItem navItem) { view.addItem(navItem.getId(), navItem.getName(), navItem.getDescription(), () -> { onItemClicked(navItem); }); } @Override public NavItem getItemSelected() { return itemSelected; } @Override public boolean setSelectedItem(String id) { clearSelectedItem(); NavItem navItem = getItem(id); if (navItem != null) { itemSelected = navItem; view.setSelectedItem(navItem.getId()); return true; } for (NavWidget navWidget : navSubgroupList) { if (navWidget.setSelectedItem(id)) { itemSelected = navWidget.getItemSelected(); activeNavSubgroup = navWidget; return true; } } return false; } @Override public void clearSelectedItem() { itemSelected = null; view.clearSelectedItem(); if (activeNavSubgroup != null) { activeNavSubgroup.clearSelectedItem(); activeNavSubgroup = null; } } public void onSubGroupItemClicked(NavWidget subGroup) { if (activeNavSubgroup != null && activeNavSubgroup != subGroup) { activeNavSubgroup.clearSelectedItem(); } activeNavSubgroup = subGroup; view.clearSelectedItem(); view.setSelectedItem(subGroup.getNavGroup().getId()); itemSelected = subGroup.getItemSelected(); if (onItemSelectedCommand != null) { onItemSelectedCommand.execute(); } } public void onItemClicked(NavItem navItem) { clearSelectedItem(); itemSelected = navItem; view.setSelectedItem(navItem.getId()); navigationManager.navItemClicked(navItem); if (onItemSelectedCommand != null) { onItemSelectedCommand.execute(); } } protected void refresh() { if (onStaleCommand != null) { onStaleCommand.execute(); } } @Override public void dispose() { view.clearItems(); navSubgroupList.forEach(NavWidget::dispose); } // Listen to changes in the navigation tree public void onNavTreeChanged(@Observes final NavTreeChangedEvent event) { navigationManager.update(event.getNavTree()); refresh(); } // Listen to authorization policy changes as it might impact the menu items shown public void onAuthzPolicyChanged(@Observes final SaveRoleEvent event) { if (secure) { refresh(); } } public void onAuthzPolicyChanged(@Observes final SaveGroupEvent event) { if (secure) { refresh(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/BaseNavWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.common.client.dom.Node; import org.uberfire.mvp.Command; public abstract class BaseNavWidgetView extends Composite implements NavWidgetView { protected Node navWidget = null; protected Element selectedItem = null; protected Map itemMap = new HashMap<>(); protected Set widgetSet = new HashSet<>(); protected void appendWidgetToElement(HTMLElement element, IsWidget widget) { DOMUtil.appendWidgetToElement(element, widget); widgetSet.add(widget); } @Override public void clearItems() { DOMUtil.removeAllChildren(navWidget); widgetSet.forEach(DOMUtil::removeFromParent); } @Override public void addGroupItem(String id, String name, String description, IsWidget widget) { Element el = widget.asWidget().getElement(); navWidget.appendChild((Node) el); } @Override public void addItem(String id, String name, String description, Command onItemSelected) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.setInnerText(name); if (description != null && !description.equals(name)) { anchor.setTitle(description); } LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); navWidget.appendChild((Node) li); itemMap.put(id, li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if (Event.ONCLICK == event.getTypeInt()) { onItemSelected.execute(); } }); } @Override public void setSelectedItem(String id) { Element el = itemMap.get(id); if (el != null) { clearSelectedItem(); selectedItem = el; setSelectedEnabled(true); } } @Override public void clearSelectedItem() { if (selectedItem != null) { setSelectedEnabled(false); selectedItem = null; } } protected void setSelectedEnabled(boolean enabled) { if (enabled) { selectedItem.setClassName("active"); } else { selectedItem.setClassName(""); } } @Override public void errorNavGroupNotFound() { addItem("error", NavigationConstants.INSTANCE.navGroupNotFound(), null, () -> {}); } @Override public void errorNavItemsEmpty() { addItem("error", NavigationConstants.INSTANCE.navItemsEmpty(), null, () -> {}); } // LayoutRecursionIssueI18n public String navRefPerspectiveI18n(String name) { return NavigationConstants.INSTANCE.navRefPerspective(name); } public String navRefPerspectiveFoundI18n(String name) { return NavigationConstants.INSTANCE.navRefPerspectiveFound(name); } public String navRefPerspectiveDefaultI18n(String name) { return NavigationConstants.INSTANCE.navRefPerspectiveDefault(name); } public String navRefPerspectiveInGroupI18n(String name) { return NavigationConstants.INSTANCE.navRefPerspectiveInGroup(name); } public String navRefComponentI18n(String name) { return NavigationConstants.INSTANCE.navRefComponent(name); } public String navRefGroupDefinedI18n(String name) { return NavigationConstants.INSTANCE.navRefGroupDefined(name); } public String navRefGroupContextI18n(String name) { return NavigationConstants.INSTANCE.navRefGroupContext(name); } public String navRefDefaultItemDefinedI18n(String name) { return NavigationConstants.INSTANCE.navRefDefaultItemDefined(name); } public String navRefDefaultItemFoundI18n(String name) { return NavigationConstants.INSTANCE.navRefDefaultItemFound(name); } public String navRefPerspectiveRecursionEndI18n() { return NavigationConstants.INSTANCE.navRefPerspectiveRecursionEnd(); } public String navMenubarDragComponentI18n() { return NavigationConstants.INSTANCE.navMenubarDragComponent(); } public String navTreeDragComponentI18n() { return NavigationConstants.INSTANCE.navTreeDragComponent(); } public String navTilesDragComponentI18n() { return NavigationConstants.INSTANCE.navTilesDragComponent(); } public String navTabListDragComponentI18n() { return NavigationConstants.INSTANCE.navTabListDragComponent(); } public String navCarouselDragComponentI18n() { return NavigationConstants.INSTANCE.navCarouselDragComponent(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/HasDefaultNavItem.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; /** * Interface implemented for those {@link NavWidget} implementations that allows for * the definition of a default nav item to display. */ public interface HasDefaultNavItem { String getDefaultNavItemId(); void setDefaultNavItemId(String navItemId); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/HasTargetDiv.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; /** * Interface implemented for those {@link NavWidget} implementations that accept a target div as the location to * display the content of the nav items clicked by the user. */ public interface HasTargetDiv { String getTargetDivId(); void setTargetDivId(String targetDivId); void setGotoItemEnabled(boolean gotoDefaultItem); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavCarouselWidget.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutRecursionIssueI18n; import org.uberfire.ext.plugin.event.PluginSaved; import org.uberfire.ext.plugin.model.Plugin; @Dependent public class NavCarouselWidget extends BaseNavWidget implements HasDefaultNavItem { public interface View extends NavWidgetView, LayoutRecursionIssueI18n { void addContentSlide(IsWidget widget); void infiniteRecursionError(String cause); } View view; PerspectivePluginManager perspectivePluginManager; List perspectiveIds = new ArrayList<>(); String defaultNavItemId = null; @Inject public NavCarouselWidget(View view, NavigationManager navigationManager, PerspectivePluginManager perspectivePluginManager) { super(view, navigationManager); this.view = view; this.perspectivePluginManager = perspectivePluginManager; super.setMaxLevels(1); } @Override public boolean areSubGroupsSupported() { return false; } @Override public String getDefaultNavItemId() { return defaultNavItemId; } @Override public void setDefaultNavItemId(String defaultNavItemId) { this.defaultNavItemId = defaultNavItemId; } @Override public void show(List itemList) { // Discard everything but runtime perspectives List itemsFiltered = itemList.stream() .filter(perspectivePluginManager::isRuntimePerspective) .collect(Collectors.toList()); // Get the default item configured (if any) NavItem defaultNavItem = null; if (defaultNavItemId != null) { for (NavItem navItem : itemsFiltered) { if (defaultNavItemId.equals(navItem.getId())) { defaultNavItem = navItem; } } } // Place the default item at the beginning of the carousel if (defaultNavItem != null) { itemsFiltered.remove(defaultNavItem); itemsFiltered.add(0, defaultNavItem); } perspectiveIds.clear(); super.show(itemsFiltered); } @Override protected void showItem(NavItem navItem) { // Only runtime perspectives can be displayed String perspectiveId = perspectivePluginManager.getRuntimePerspectiveId(navItem); if (perspectiveId != null) { perspectiveIds.add(perspectiveId); perspectivePluginManager.buildPerspectiveWidget(perspectiveId, view::addContentSlide, this::onInfiniteRecursion); } } public void onInfiniteRecursion(LayoutRecursionIssue issue) { String cause = issue.printReport(navigationManager.getNavTree(), view); view.infiniteRecursionError(cause); } // Catch changes on runtime perspectives so as to display the most up to date changes private void onPerspectiveChanged(@Observes PluginSaved event) { Plugin plugin = event.getPlugin(); String pluginName = plugin.getName(); if (perspectiveIds.contains(pluginName)) { super.refresh(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavCarouselWidgetView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavCarouselWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.common.client.widgets.AlertBox; import org.jboss.errai.common.client.dom.CSSStyleDeclaration; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Window; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class NavCarouselWidgetView extends BaseNavWidgetView implements NavCarouselWidget.View { @Inject @DataField Div mainDiv; @Inject @DataField Div carouselDiv; @Inject @DataField Div slidesDiv; NavCarouselWidget presenter; AlertBox alertBox; @Inject public NavCarouselWidgetView(AlertBox alertBox) { this.alertBox = alertBox; alertBox.setLevel(AlertBox.Level.WARNING); alertBox.setCloseEnabled(false); alertBox.getElement().getStyle().setProperty("width", "96%"); } @Override public void init(NavCarouselWidget presenter) { this.presenter = presenter; super.navWidget = slidesDiv; } @Override public void addDivider() { // Useless in a tab list } @Override public void addContentSlide(IsWidget widget) { DOMUtil.removeAllChildren(mainDiv); mainDiv.appendChild(carouselDiv); Div div = (Div) Window.getDocument().createElement("div"); div.setClassName(slidesDiv.getChildNodes().getLength() == 0 ? "item active" : "item"); super.appendWidgetToElement(div, widget); slidesDiv.appendChild(div); } @Override public void errorNavGroupNotFound() { DOMUtil.removeAllChildren(mainDiv); alertBox.setMessage(NavigationConstants.INSTANCE.navGroupNotFound()); mainDiv.appendChild(alertBox.getElement()); } @Override public void errorNavItemsEmpty() { DOMUtil.removeAllChildren(mainDiv); alertBox.setMessage(NavigationConstants.INSTANCE.navCarouselDragComponentEmptyError()); mainDiv.appendChild(alertBox.getElement()); } @Override public void infiniteRecursionError(String cause) { Div div = (Div) Window.getDocument().createElement("div"); div.setClassName(slidesDiv.getChildNodes().getLength() == 0 ? "item active" : "item"); alertBox.setMessage(NavigationConstants.INSTANCE.navCarouselDragComponentInfiniteRecursion() + " " + cause); div.appendChild(alertBox.getElement()); slidesDiv.appendChild(div); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavComponentConfigModal.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.uberfire.client.mvp.UberView; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.plugin.client.perspective.editor.layout.editor.TargetDivList; import org.uberfire.mvp.Command; @Dependent public class NavComponentConfigModal implements IsWidget { public interface View extends UberView { void clearNavGroupItems(); void setNavGroupEnabled(boolean enabled); void addNavGroupItem(String name, Command onSelect); void setNavGroupSelection(String name, Command onReset); void setNavGroupHelpText(String text); void setDefaultNavItemEnabled(boolean enabled); void setDefaultNavItemVisible(boolean enabled); void clearDefaultItems(); void defaultItemsNotFound(); void setDefaultItemSelection(String name, Command onReset); void addDefaultItem(String name, Command onSelect); void setTargetDivVisible(boolean enabled); void clearTargetDivItems(); void targetDivsNotFound(); void addTargetDivItem(String name, Command onSelect); void setTargetDivSelection(String name, Command onReset); void show(); void hide(); } View view; String groupId = null; NavGroup group = null; String defaultItemId = null; String targetDivId = null; List navItemList = null; List targetDivIdList = null; Command onOk = null; Command onCancel = null; @Inject public NavComponentConfigModal(View view) { this.view = view; this.view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public View getView() { return view; } public void setTargetDivIdList(List targetDivIdList) { this.targetDivIdList = targetDivIdList; } public void setOnOk(Command onOk) { this.onOk = onOk; } public void setOnCancel(Command onCancel) { this.onCancel = onCancel; } public void setNavGroupHelpHint(String text) { view.setNavGroupHelpText(text); } public String getGroupId() { return groupId; } public String getDefaultItemId() { return defaultItemId; } public String getTargetDivId() { return targetDivId; } public void setTargetDivSupported(boolean supported) { view.setTargetDivVisible(supported); } public void setTargetDiv(String targetDivId) { this.targetDivId = targetDivId; } public void setDefaultNavItemSupported(boolean supported) { view.setDefaultNavItemVisible(supported); } public void setDefaultNavItemId(String navItemId) { defaultItemId = navItemId; } public void setNavGroup(List navItemList, String selectedGroupId) { this.navItemList = navItemList; this.groupId = selectedGroupId; this.group = null; } private void updateNavGroups() { group = null; view.clearNavGroupItems(); if (navItemList != null) { updateNavGroups(navItemList); } } private void updateNavGroups(List navItemList) { navItemList.stream() .filter(navItem -> navItem instanceof NavGroup) .forEach(this::addNavGroup); } private void addNavGroup(NavItem navItem) { String fullPath = calculateFullPath(navItem); if (groupId == null || navItem.getId().equals(groupId)) { groupId = navItem.getId(); group = (NavGroup) navItem; view.setNavGroupSelection(fullPath, () -> {}); } else { view.addNavGroupItem(fullPath, () -> onGroupSelected(navItem.getId())); } // Add the children items updateNavGroups(((NavGroup) navItem).getChildren()); } private void updateDefaultItems() { view.clearDefaultItems(); view.setDefaultNavItemEnabled(group != null); if (group == null || group.getChildren().isEmpty()) { view.defaultItemsNotFound(); } else { NavGroup clone = (NavGroup) group.cloneItem(); clone.setParent(null); updateDefaultItems(clone, 1); } } private void updateDefaultItems(NavGroup navGroup, int level) { for (NavItem navItem : navGroup.getChildren()) { // Divider N/A if (navItem instanceof NavDivider) { continue; } // Add the default item. Skip groups. if (!(navItem instanceof NavGroup)) { String fullPath = calculateFullPath(navItem); if (defaultItemId != null && navItem.getId().equals(defaultItemId)) { view.setDefaultItemSelection(fullPath, () -> onDefaultItemSelected(null)); } else { view.addDefaultItem(fullPath, () -> onDefaultItemSelected(navItem.getId())); } } // Append children if (navItem instanceof NavGroup) { updateDefaultItems((NavGroup) navItem, level+1); } } } private void updateTargetDivs() { view.clearTargetDivItems(); if (targetDivIdList == null || targetDivIdList.isEmpty()) { view.targetDivsNotFound(); } else { for (String divId : targetDivIdList) { if (targetDivId == null || !targetDivIdList.contains(targetDivId) || divId.equals(targetDivId)) { targetDivId = divId; view.setTargetDivSelection(divId, () -> onTargetDivSelected(null)); } else { view.addTargetDivItem(divId, () -> onTargetDivSelected(divId)); } } } } public String calculateFullPath(NavItem navItem) { StringBuilder out = new StringBuilder(); NavItem parent = navItem.getParent(); while (parent != null) { out.insert(0, parent.getName() + ">"); parent = parent.getParent(); } out.append(navItem.getName()); return out.toString(); } public void clear() { groupId = null; group = null; defaultItemId = null; targetDivId = null; navItemList = null; targetDivIdList = null; view.clearNavGroupItems(); view.clearDefaultItems(); view.clearTargetDivItems(); } public void show() { updateNavGroups(); updateDefaultItems(); updateTargetDivs(); view.show(); } // View callbacks public void onGroupSelected(String id) { groupId = id; defaultItemId = null; updateNavGroups(); updateDefaultItems(); } public void onDefaultItemSelected(String id) { defaultItemId = id; updateDefaultItems(); } public void onTargetDivSelected(String id) { targetDivId = id; updateTargetDivs(); } public void onOk() { if (groupId != null) { view.hide(); if (onOk != null) { onOk.execute(); } } } public void onCancel() { view.hide(); if (onCancel != null) { onCancel.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavComponentConfigModalView.css ================================================ .uf-navconfig-body { margin: 15px; } .uf-navconfig-selector-button { min-width: 200px; text-align: left; } .uf-navconfig-selector-menu { margin-left: 20px; min-width: 200px; } .uf-navconfig-selector-caret { float: right; margin-top: 5px; } .uf-navconfig-disabled { opacity: .5; pointer-events: none; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavComponentConfigModalView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavComponentConfigModalView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.gwtbootstrap3.client.ui.Modal; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Input; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.TemplateWidgetMapper; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.SinkNative; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.editor.commons.client.file.popups.CommonModalBuilder; import org.uberfire.ext.widgets.common.client.common.popups.BaseModal; import org.uberfire.ext.widgets.common.client.common.popups.ButtonPressed; import org.uberfire.mvp.Command; @Templated public class NavComponentConfigModalView implements NavComponentConfigModal.View { NavComponentConfigModal presenter; BaseModal modal; ButtonPressed buttonPressed = ButtonPressed.CLOSE; @Inject @DataField Div body; @Inject @DataField Div footer; @Inject @DataField Div navGroupDiv; @Inject @DataField Span navGroupLabel; @DataField @Inject Span navGroupHelp; @DataField @Inject Span navGroupSelection; @DataField @Inject UnorderedList navGroupItems; @Inject @DataField Div defaultItemDiv; @Inject @DataField Span defaultItemLabel; @DataField @Inject Span defaultItemHelp; @DataField @Inject Span defaultItemSelection; @DataField @Inject UnorderedList defaultItems; @Inject @DataField Div targetDivDiv; @Inject @DataField Span targetDivLabel; @DataField @Inject Span targetDivHelp; @DataField @Inject Span targetDivSelection; @DataField @Inject UnorderedList targetDivItems; @Override public void init(NavComponentConfigModal presenter) { this.presenter = presenter; navGroupLabel.setTextContent(NavigationConstants.INSTANCE.navGroupLabel()); navGroupHelp.setTitle(NavigationConstants.INSTANCE.navGroupHelp()); navGroupSelection.setTextContent(NavigationConstants.INSTANCE.navGroupSelectorHint()); defaultItemLabel.setTextContent(NavigationConstants.INSTANCE.defaultItemLabel()); defaultItemHelp.setTitle(NavigationConstants.INSTANCE.defaultItemHelp()); defaultItemSelection.setTextContent(NavigationConstants.INSTANCE.defaultItemSelectorHint()); targetDivLabel.setTextContent(NavigationConstants.INSTANCE.targetDivLabel()); targetDivHelp.setTitle(NavigationConstants.INSTANCE.targetDivHelp()); targetDivSelection.setTextContent(NavigationConstants.INSTANCE.targetDivSelectorHint()); modal = new CommonModalBuilder() .addHeader(NavigationConstants.INSTANCE.navConfigHeader()) .addBody( body ) .addFooter( footer ) .build(); modal.addHiddenHandler(hiddenEvent -> { if (ButtonPressed.CLOSE.equals(buttonPressed)) { presenter.onCancel(); } }); modal.setWidth( "960px" ); } public Modal getModal() { return modal; } @Override public Widget asWidget() { return TemplateWidgetMapper.get(modal); } @Override public void show() { modal.show(); } @Override public void hide() { modal.hide(); } @Override public void setNavGroupEnabled(boolean enabled) { navGroupDiv.setClassName("form-group" + (enabled ? "" : " uf-navconfig-disabled")); } @Override public void clearNavGroupItems() { DOMUtil.removeAllChildren(navGroupItems); navGroupSelection.setTextContent(NavigationConstants.INSTANCE.navGroupSelectorHint()); } @Override public void setNavGroupHelpText(String text) { navGroupHelp.setTitle(text); } @Override public void setNavGroupSelection(String name, Command onReset) { navGroupSelection.setTextContent(name); addItem(navGroupItems, name, true, onReset); } @Override public void addNavGroupItem(String name, Command onSelect) { addItem(navGroupItems, name, false, onSelect); } @Override public void setDefaultNavItemVisible(boolean enabled) { defaultItemDiv.setHidden(!enabled); } @Override public void setDefaultNavItemEnabled(boolean enabled) { defaultItemDiv.setClassName("form-group" + (enabled ? "" : " uf-navconfig-disabled")); } @Override public void clearDefaultItems() { DOMUtil.removeAllChildren(defaultItems); defaultItemSelection.setTextContent(NavigationConstants.INSTANCE.defaultItemSelectorHint()); } @Override public void defaultItemsNotFound() { clearDefaultItems(); addDefaultItem(NavigationConstants.INSTANCE.defaultItemsNotFound(), () -> {}); } @Override public void setDefaultItemSelection(String name, Command onReset) { defaultItemSelection.setTextContent(name); addItem(defaultItems, name, true, onReset); } @Override public void addDefaultItem(String name, Command onSelect) { addItem(defaultItems, name, false, onSelect); } @Override public void setTargetDivVisible(boolean enabled) { targetDivDiv.setHidden(!enabled); } @Override public void clearTargetDivItems() { DOMUtil.removeAllChildren(targetDivItems); targetDivSelection.setTextContent(NavigationConstants.INSTANCE.targetDivSelectorHint()); } @Override public void targetDivsNotFound() { clearTargetDivItems(); addTargetDivItem(NavigationConstants.INSTANCE.targetDivsNotFound(), () -> {}); } @Override public void addTargetDivItem(String name, Command onSelect) { addItem(targetDivItems, name, false, onSelect); } @Override public void setTargetDivSelection(String name, Command onReset) { targetDivSelection.setTextContent(name); addItem(targetDivItems, name, true, onReset); } private void addItem(UnorderedList unorderedList, String name, boolean selected, Command onSelect) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.setInnerText(name); LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); li.setClassName(selected ? "selected" : ""); unorderedList.appendChild((Node) li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if(Event.ONCLICK == event.getTypeInt()) { onSelect.execute(); } }); } @SinkNative(Event.ONCLICK) @EventHandler("okButton") public void okClick(final Event event) { buttonPressed = ButtonPressed.OK; presenter.onOk(); } @SinkNative(Event.ONCLICK) @EventHandler("cancelButton") public void cancelClick(final Event event) { buttonPressed = ButtonPressed.CANCEL; presenter.onCancel(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavDropDownWidget.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.jboss.errai.ioc.client.container.SyncBeanManager; @Dependent public class NavDropDownWidget extends BaseNavWidget { public interface View extends NavWidgetView { void setDropDownName(String name); void showAsSubmenu(boolean enabled); void setActive(boolean active); } View view; SyncBeanManager beanManager; @Inject public NavDropDownWidget(View view, SyncBeanManager beanManager, NavigationManager navigationManager) { super(view, navigationManager); this.view = view; this.beanManager = beanManager; } @Override public NavWidget lookupNavGroupWidget() { return beanManager.lookupBean(NavDropDownWidget.class).newInstance(); } @Override public void show(NavGroup navGroup) { if (navGroup == null) { view.errorNavGroupNotFound(); } else { view.setDropDownName(navGroup.getName()); view.showAsSubmenu(getLevel() > 1); super.show(navGroup); } } @Override public void onItemClicked(NavItem navItem) { super.onItemClicked(navItem); setActive(true); } @Override public void onSubGroupItemClicked(NavWidget subGroup) { super.onSubGroupItemClicked(subGroup); setActive(true); } @Override public boolean setSelectedItem(String id) { boolean enabled = super.setSelectedItem(id); setActive(enabled); return enabled; } @Override public void clearSelectedItem() { super.clearSelectedItem(); setActive(false); } private void setActive(boolean enabled) { // Disable for subgroups, as it is not working well view.setActive(enabled && getLevel() == 1); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavDropDownWidgetView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavDropDownWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import org.jboss.errai.common.client.dom.Anchor; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.ListItem; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class NavDropDownWidgetView extends BaseNavWidgetView implements NavDropDownWidget.View { @Inject @DataField ListItem dropDownItem; @Inject @DataField Anchor dropDownAnchor; @Inject @DataField Span dropDownName; @Inject @DataField UnorderedList dropDownMenu; NavDropDownWidget presenter; boolean active = false; boolean submenu = false; @Override public void init(NavDropDownWidget presenter) { this.presenter = presenter; super.navWidget = dropDownMenu; } @Override public void setDropDownName(String name) { dropDownName.setTextContent(name); } private String calculateDropDownClassName() { if (submenu) { if (active) { return "dropdown-submenu active"; } else { return "dropdown-submenu"; } } else { if (active) { return "dropdown active"; } else { return "dropdown"; } } } @Override public void showAsSubmenu(boolean enabled) { submenu = enabled; String className = calculateDropDownClassName(); dropDownItem.setClassName(className); if (enabled) { DOMUtil.removeAllChildren(dropDownAnchor); dropDownAnchor.appendChild(dropDownName); } } @Override public void setActive(boolean active) { this.active = active; String className = calculateDropDownClassName(); dropDownItem.setClassName(className); } @Override public void addDivider() { LIElement li = Document.get().createLIElement(); li.setClassName("divider"); dropDownMenu.appendChild((Node) li); } @Override public void errorNavGroupNotFound() { setDropDownName("ERROR: Nav group not found"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavItemTileWidget.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.client.mvp.UberElement; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.ActivityResourceType; /** * A widget that shows a tile representing a {@link NavItem} */ @Dependent public class NavItemTileWidget implements IsElement { public interface View extends UberElement { enum ItemType { GROUP, PERSPECTIVE, RUNTIME_PERSPECTIVE; } void show(String name, String descr, ItemType type); } View view; PerspectivePluginManager perspectivePluginManager; Command onClick = null; @Inject public NavItemTileWidget(View view, PerspectivePluginManager perspectivePluginManager) { this.view = view; this.perspectivePluginManager = perspectivePluginManager; this.view.init(this); } @Override public HTMLElement getElement() { return view.getElement(); } public void setOnClick(Command onClick) { this.onClick = onClick; } public void show(NavItem navItem) { String name = navItem.getName(); String descr = navItem.getDescription(); if (navItem instanceof NavGroup) { view.show(name, descr, View.ItemType.GROUP); } else { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); String resourceId = navCtx.getResourceId(); if (resourceId != null && ActivityResourceType.PERSPECTIVE.equals(navCtx.getResourceType())) { if (perspectivePluginManager.isRuntimePerspective(resourceId)) { view.show(name, descr, View.ItemType.RUNTIME_PERSPECTIVE); } else { view.show(name, descr, View.ItemType.PERSPECTIVE); } } } } // View callbacks void onClick() { if (onClick != null) { onClick.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavItemTileWidgetView.css ================================================ .uf-navitem-tile-body { cursor: pointer; float: left; height: 160px; width: 160px; margin: 0 10px 10px 0; font-size: 16px; position: relative; text-align: center; overflow: hidden; } .uf-navitem-tile-icon { margin-top: 25px; font-size: 46px; color: #FFFFFF; } .uf-navitem-tile-text { color: #FFFFFF; } .uf-navitem-tile-group { background: rgba(76, 98, 154, 0.52); } .uf-navitem-tile-perspective { background: rgba(67, 154, 99, 0.60); } .uf-navitem-tile-runtime-perspective { background: rgba(67, 154, 99, 0.60); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavItemTileWidgetView.html ================================================
Test
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavItemTileWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class NavItemTileWidgetView implements NavItemTileWidget.View, IsElement { @Inject @DataField Div mainDiv; @Inject @DataField Div iconDiv; @Inject @DataField Span iconSpan; @Inject @DataField Span textSpan; NavItemTileWidget presenter; @Override public void init(NavItemTileWidget presenter) { this.presenter = presenter; } @Override public void show(String name, String descr, ItemType type) { textSpan.setTextContent(name); mainDiv.getStyle().setProperty("title", descr); if (ItemType.GROUP == type) { mainDiv.setClassName("uf-navitem-tile-body uf-navitem-tile-group"); iconSpan.setClassName("pficon-folder-open"); mainDiv.setTitle(NavigationConstants.INSTANCE.openNavItem(name)); } else if (ItemType.PERSPECTIVE == type) { mainDiv.setClassName("uf-navitem-tile-body uf-navitem-tile-perspective"); iconSpan.setClassName("pficon-screen"); mainDiv.setTitle(NavigationConstants.INSTANCE.gotoNavItem(name)); } else if (ItemType.RUNTIME_PERSPECTIVE == type) { mainDiv.setClassName("uf-navitem-tile-body uf-navitem-tile-runtime-perspective"); iconSpan.setClassName("pficon-virtual-machine"); mainDiv.setTitle(NavigationConstants.INSTANCE.showNavItem(name)); } } @EventHandler("mainDiv") public void onMainDivClick(ClickEvent event) { presenter.onClick(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavMenuBarWidget.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; @Dependent public class NavMenuBarWidget extends TargetDivNavWidget { public interface View extends TargetDivNavWidget.View { void setNavHeaderVisible(boolean visible); } View view; SyncBeanManager beanManager; @Inject public NavMenuBarWidget(View view, SyncBeanManager beanManager, PerspectivePluginManager pluginManager, PlaceManager placeManager, NavigationManager navigationManager) { super(view, pluginManager, placeManager, navigationManager); this.view = view; this.beanManager = beanManager; } @Override public NavWidget lookupNavGroupWidget() { return beanManager.lookupBean(NavDropDownWidget.class).newInstance(); } public void setNavHeaderVisible(boolean visible) { view.setNavHeaderVisible(visible); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavMenuBarWidgetView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavMenuBarWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.inject.Named; import org.dashbuilder.common.client.widgets.AlertBox; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class NavMenuBarWidgetView extends TargetDivNavWidgetView implements NavMenuBarWidget.View { @Inject @DataField Div mainDiv; @Inject @DataField UnorderedList navBar; @Inject @DataField @Named("nav") HTMLElement nav; NavMenuBarWidget presenter; @Inject public NavMenuBarWidgetView(AlertBox alertBox) { super(alertBox); } @Override public void init(NavMenuBarWidget presenter) { this.presenter = presenter; super.navWidget = navBar; setNavHeaderVisible(true); } @Override public void addDivider() { // Useless in a menu bar } @Override public void clearItems() { super.clearItems(); DOMUtil.removeAllChildren(mainDiv); mainDiv.appendChild(navBar.getParentElement().getParentElement()); } @Override public void error(String message) { DOMUtil.removeAllChildren(mainDiv); alertBox.setMessage(message); mainDiv.appendChild(alertBox.getElement()); } @Override public void setNavHeaderVisible(boolean visible) { nav.setClassName(visible ? "navbar navbar-default navbar-pf" : ""); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTabListWidget.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavItem; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; @Dependent public class NavTabListWidget extends TargetDivNavWidget { public interface View extends TargetDivNavWidget.View { void clearChildrenTabs(); void showChildrenTabs(IsWidget tabListWidget); void showAsSubmenu(boolean enabled); } View view; SyncBeanManager beanManager; @Inject public NavTabListWidget(View view, SyncBeanManager beanManager, PerspectivePluginManager pluginManager, PlaceManager placeManager, NavigationManager navigationManager) { super(view, pluginManager, placeManager, navigationManager); this.view = view; this.beanManager = beanManager; } @Override protected NavWidget lookupNavGroupWidget() { return beanManager.lookupBean(NavTabListWidget.class).newInstance(); } @Override public boolean setSelectedItem(String id) { boolean selected = super.setSelectedItem(id); if (selected && activeNavSubgroup != null) { view.setSelectedItem(activeNavSubgroup.getNavGroup().getId()); view.showChildrenTabs(activeNavSubgroup); } return selected; } @Override public void show(List itemList) { view.showAsSubmenu(getLevel() > 0); super.show(itemList); } @Override public void onItemClicked(NavItem navItem) { view.clearChildrenTabs(); super.onItemClicked(navItem); } // View callbacks void onGroupTabClicked(String id) { TargetDivNavWidget navGroupWidget = (TargetDivNavWidget) super.getSubgroupNavWidget(id); if (navGroupWidget != null) { super.onItemClicked(navGroupWidget.getNavGroup()); view.showChildrenTabs(navGroupWidget); navGroupWidget.gotoDefaultItem(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTabListWidgetView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTabListWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.common.client.widgets.AlertBox; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class NavTabListWidgetView extends TargetDivNavWidgetView implements NavTabListWidget.View { @Inject @DataField Div mainDiv; @Inject @DataField Div tabsDiv; @Inject @DataField UnorderedList tabList; @Inject @DataField Div childrenDiv; NavTabListWidget presenter; @Inject public NavTabListWidgetView(AlertBox alertBox) { super(alertBox); } @Override public void init(NavTabListWidget presenter) { this.presenter = presenter; super.navWidget = tabList; } @Override public void addDivider() { // Useless in a tab list } @Override public void addGroupItem(String id, String name, String description, IsWidget widget) { this.addItem(id, name, description, () -> presenter.onGroupTabClicked(id)); } @Override public void showAsSubmenu(boolean enabled) { tabList.setClassName("nav nav-tabs" + (enabled ? " nav-tabs-pf" : "")); } @Override public void clearChildrenTabs() { DOMUtil.removeAllChildren(childrenDiv); } @Override public void showChildrenTabs(IsWidget tabListWidget) { DOMUtil.removeAllChildren(childrenDiv); super.appendWidgetToElement(childrenDiv, tabListWidget); if (presenter.getLevel() == 0) { childrenDiv.getStyle().setProperty("margin-left", "15px"); } } @Override public void clearItems() { super.clearItems(); DOMUtil.removeAllChildren(mainDiv); mainDiv.appendChild(tabsDiv); } @Override public void error(String message) { DOMUtil.removeAllChildren(mainDiv); alertBox.setMessage(message); mainDiv.appendChild(alertBox.getElement()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTilesWidget.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.List; import java.util.Stack; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutRecursionIssueI18n; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.plugin.event.PluginSaved; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.ActivityResourceType; /** * A navigation widget that displays a set of navigation items using a navigable tile based approach where * {@link NavGroup} instances are displayed as folders and {@link NavItem} are shown as links to a specific * target asset (f.i: a perspective). */ @Dependent public class NavTilesWidget extends BaseNavWidget { public interface View extends NavWidgetView, LayoutRecursionIssueI18n { void addTileWidget(IsElement tileWidget); void showTileContent(IsWidget tileContent); void clearBreadcrumb(); void addBreadcrumbItem(String navItemName); void addBreadcrumbItem(String navItemName, Command onClicked); void infiniteRecursionError(String cause); } View view; PerspectivePluginManager perspectivePluginManager; PlaceManager placeManager; SyncBeanManager beanManager; NavItem currentPerspectiveNavItem = null; Stack navItemStack = new Stack<>(); @Inject public NavTilesWidget(View view, NavigationManager navigationManager, PerspectivePluginManager perspectivePluginManager, PlaceManager placeManager, SyncBeanManager beanManager) { super(view, navigationManager); this.view = view; this.perspectivePluginManager = perspectivePluginManager; this.placeManager = placeManager; this.beanManager = beanManager; } public Stack getNavItemStack() { return navItemStack; } @Override public void show(NavGroup navGroup) { this.show(navGroup, true); } @Override public void show(List itemList) { currentPerspectiveNavItem = null; super.show(itemList); } public void show(NavGroup navGroup, boolean clearBreadcrumb) { if (navGroup == null) { view.errorNavGroupNotFound(); } else { NavGroup clone = (NavGroup) navGroup.cloneItem(); clone.setParent(null); if (clearBreadcrumb) { navItemStack.clear(); updateBreadcrumb(); } currentPerspectiveNavItem = null; super.show(clone); } } @Override protected void showItem(NavItem navItem) { NavItemTileWidget tileWidget = beanManager.lookupBean(NavItemTileWidget.class).getInstance(); tileWidget.setOnClick(() -> this.openItem(navItem)); tileWidget.show(navItem); view.addTileWidget(tileWidget); } @Override protected void showGroup(NavGroup navGroup) { showItem(navGroup); } public void openItem(NavItem navItem) { NavItem parent = navItem.getParent(); if (navItemStack.isEmpty()) { if (parent != null) { navItemStack.add(parent); navItemStack.add(navItem); } } else { navItemStack.add(navItem); } this.updateBreadcrumb(); if (navItem instanceof NavGroup) { this.show((NavGroup) navItem, false); } else { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); String resourceId = navCtx.getResourceId(); if (resourceId != null && ActivityResourceType.PERSPECTIVE.equals(navCtx.getResourceType())) { // Runtime perspectives are displayed inline if (perspectivePluginManager.isRuntimePerspective(resourceId)) { openPerspective(navItem); } // Classic UF perspectives take over the entire window else { placeManager.goTo(resourceId); } } } } protected void openPerspective(NavItem perspectiveItem) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(perspectiveItem); String perspectiveId = navCtx.getResourceId(); String navRootId = navCtx.getNavGroupId(); currentPerspectiveNavItem = perspectiveItem; LayoutTemplateContext layoutCtx = new LayoutTemplateContext(navRootId); perspectivePluginManager.buildPerspectiveWidget(perspectiveId, layoutCtx, view::showTileContent, this::onInfiniteRecursion); } public void onInfiniteRecursion(LayoutRecursionIssue issue) { String cause = issue.printReport(navigationManager.getNavTree(), view); view.infiniteRecursionError(cause); } protected void updateBreadcrumb() { view.clearBreadcrumb(); for (int i=0; i gotoBreadcrumbItem(navItem)); } } } public void gotoBreadcrumbItem(NavItem navItem) { while (navItemStack.peek() != navItem) { navItemStack.pop(); } // Re-open the item if (!navItemStack.isEmpty()) { navItemStack.pop(); } openItem(navItem); } // Catch changes on runtime perspectives so as to display the most up to date changes private void onPerspectiveChanged(@Observes PluginSaved event) { if (currentPerspectiveNavItem != null) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(currentPerspectiveNavItem); String perspectiveId = navCtx.getResourceId(); if (event.getPlugin().getName().equals(perspectiveId)) { openPerspective(currentPerspectiveNavItem); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTilesWidgetView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTilesWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.common.client.widgets.AlertBox; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.OrderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.mvp.Command; @Dependent @Templated public class NavTilesWidgetView extends BaseNavWidgetView implements NavTilesWidget.View { @Inject @DataField Div mainDiv; @Inject @DataField Div contentDiv; @Inject @DataField Div tilesDiv; @Inject @DataField("breadcrumb") OrderedList breadcrumb; NavTilesWidget presenter; AlertBox alertBox; @Inject public NavTilesWidgetView(AlertBox alertBox) { this.alertBox = alertBox; alertBox.setLevel(AlertBox.Level.WARNING); alertBox.setCloseEnabled(false); alertBox.getElement().getStyle().setProperty("width", "96%"); } @Override public void init(NavTilesWidget presenter) { this.presenter = presenter; super.navWidget = tilesDiv; } @Override public void addDivider() { // Useless in tile navigator } @Override public void addTileWidget(IsElement tileWidget) { DOMUtil.removeAllChildren(mainDiv); mainDiv.appendChild(contentDiv); tilesDiv.appendChild(tileWidget.getElement()); } @Override public void showTileContent(IsWidget tileContent) { DOMUtil.removeAllChildren(tilesDiv); super.appendWidgetToElement(tilesDiv, tileContent); } @Override public void errorNavItemsEmpty() { DOMUtil.removeAllChildren(mainDiv); alertBox.setMessage(NavigationConstants.INSTANCE.navGroupEmptyError()); mainDiv.appendChild(alertBox.getElement()); } @Override public void errorNavGroupNotFound() { DOMUtil.removeAllChildren(mainDiv); alertBox.setMessage(NavigationConstants.INSTANCE.navGroupNotFound()); mainDiv.appendChild(alertBox.getElement()); } @Override public void infiniteRecursionError(String cause) { DOMUtil.removeAllChildren(tilesDiv); alertBox.setMessage(NavigationConstants.INSTANCE.navTilesDragComponentInfiniteRecursion() + cause); tilesDiv.appendChild(alertBox.getElement()); } @Override public void clearBreadcrumb() { DOMUtil.removeAllChildren(breadcrumb); } @Override public void addBreadcrumbItem(String navItemName) { addBreadcrumbItem(navItemName, null); } @Override public void addBreadcrumbItem(String navItemName, Command onClicked) { LIElement li = Document.get().createLIElement(); breadcrumb.appendChild((Node) li); if (onClicked != null) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.setInnerText(navItemName); li.appendChild(anchor); li.getStyle().setCursor(Style.Cursor.POINTER); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if (Event.ONCLICK == event.getTypeInt()) { onClicked.execute(); } }); } else { ((Node) li).setTextContent(navItemName); li.setClassName("active"); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTreeWidget.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.mvp.Command; @Dependent public class NavTreeWidget extends TargetDivNavWidget { public interface View extends TargetDivNavWidget.View { void setLevel(int level); void addRuntimePerspective(String id, String name, String description, Command onClicked); void addPerspective(String id, String name, String description, Command onClicked); } View view; SyncBeanManager beanManager; @Inject public NavTreeWidget(View view, SyncBeanManager beanManager, PerspectivePluginManager pluginManager, PlaceManager placeManager, NavigationManager navigationManager) { super(view, pluginManager, placeManager, navigationManager); this.view = view; this.beanManager = beanManager; } @Override protected NavWidget lookupNavGroupWidget() { return beanManager.lookupBean(NavTreeWidget.class).newInstance(); } @Override public void show(List itemList) { view.setLevel(getLevel()); super.show(itemList); } @Override protected void showItem(NavItem navItem) { NavWorkbenchCtx ctx = NavWorkbenchCtx.get(navItem); if (pluginManager.isRuntimePerspective(ctx.getResourceId())) { view.addRuntimePerspective(navItem.getId(), navItem.getName(), navItem.getDescription(), () -> { onItemClicked(navItem); }); } else { view.addPerspective(navItem.getId(), navItem.getName(), navItem.getDescription(), () -> { onItemClicked(navItem); }); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTreeWidgetView.css ================================================ .uf-navtree-widget-icon { font-size: larger; margin-right: 5px; } .uf-navtree-widget-non-clickable { font-size: larger; color: black; } .uf-navtree-widget-non-clicked { font-size: larger; color: black; cursor: pointer; } .uf-navtree-widget-clicked { font-size: larger; color: black; text-decoration: underline; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTreeWidgetView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavTreeWidgetView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.SpanElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.common.client.widgets.AlertBox; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.mvp.Command; @Dependent @Templated public class NavTreeWidgetView extends TargetDivNavWidgetView implements NavTreeWidget.View { @Inject @DataField Div mainDiv; NavTreeWidget presenter; @Inject public NavTreeWidgetView(AlertBox alertBox) { super(alertBox); } @Override public void init(NavTreeWidget presenter) { this.presenter = presenter; super.navWidget = mainDiv; } @Override public void addDivider() { // Useless in a tree } @Override public void setLevel(int level) { int margin = level*10; mainDiv.getStyle().setProperty("margin-left", margin + "px"); if (level == 0) { mainDiv.getStyle().setProperty("padding", "10px"); } } @Override public void addRuntimePerspective(String id, String name, String description, Command onClicked) { this.addItem("pficon-virtual-machine", id, name, description, onClicked); } @Override public void addPerspective(String id, String name, String description, Command onClicked) { this.addItem("pficon-screen", id, name, description, onClicked); } @Override public void addGroupItem(String id, String name, String description, IsWidget widget) { this.addItem("pficon-folder-open",id, name, description, null); super.addGroupItem(id, name, description, widget); } @Override protected void setSelectedEnabled(boolean enabled) { String cname = selectedItem.getClassName(); if (!cname.equals("uf-navtree-widget-non-clickable")) { if (enabled) { selectedItem.setClassName("uf-navtree-widget-clicked"); } else { selectedItem.setClassName("uf-navtree-widget-non-clicked"); } } } protected void addItem(String iconClass, String id, String name, String description, Command onClicked) { Element nameEl = onClicked != null ? Document.get().createAnchorElement() : Document.get().createSpanElement(); nameEl.setInnerText(name); nameEl.setClassName(onClicked != null ? "uf-navtree-widget-non-clicked" : "uf-navtree-widget-non-clickable"); if (description != null && !description.equals(name)) { nameEl.setTitle(description); } SpanElement iconSpan = Document.get().createSpanElement(); iconSpan.setClassName("uf-navtree-widget-icon " + iconClass); DivElement div = Document.get().createDivElement(); div.appendChild(iconSpan); div.appendChild(nameEl); navWidget.appendChild((Node) div); itemMap.put(id, nameEl); if (onClicked != null) { Event.sinkEvents(nameEl, Event.ONCLICK); Event.setEventListener(nameEl, event -> { if (Event.ONCLICK == event.getTypeInt()) { onClicked.execute(); } }); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavWidget.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.List; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.uberfire.mvp.Command; /** * Interface for widgets in charge of the display of navigation items */ public interface NavWidget extends IsWidget { void hide(); void show(NavTree navTree); void show(NavGroup navGroup); void show(List itemList); void setSecure(boolean secure); void setHideEmptyGroups(boolean hide); void setOnItemSelectedCommand(Command onItemSelected); void setOnStaleCommand(Command onStaleStatusCommand); NavWidget getParent(); void setParent(NavWidget parent); int getLevel(); int getMaxLevels(); void setMaxLevels(int maxLevels); NavGroup getNavGroup(); NavItem getItemSelected(); boolean setSelectedItem(String id); void clearSelectedItem(); void dispose(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/NavWidgetView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; public interface NavWidgetView extends UberView { void clearItems(); void addGroupItem(String id, String name, String description, IsWidget widget); void addItem(String id, String name, String description, Command onItemSelected); void addDivider(); void setSelectedItem(String id); void clearSelectedItem(); void errorNavGroupNotFound(); void errorNavItemsEmpty(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/TargetDivNavWidget.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.List; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutRecursionIssueI18n; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.plugin.event.PluginSaved; import org.uberfire.ext.plugin.model.Plugin; /** * Base class for nav widgets that uses a target div to show a nav item's content once clicked. */ public abstract class TargetDivNavWidget extends BaseNavWidget implements HasTargetDiv, HasDefaultNavItem { public interface View extends NavWidgetView, LayoutRecursionIssueI18n { void clearContent(String targetDivId); void showContent(String targetDivId, IsWidget content); void infiniteRecursionError(String targetDivId, String cause); } View view; PerspectivePluginManager pluginManager; PlaceManager placeManager; String targetDivId = null; String defaultNavItemId = null; boolean gotoItemEnabled = false; @Inject public TargetDivNavWidget(View view, PerspectivePluginManager pluginManager, PlaceManager placeManager, NavigationManager navigationManager) { super(view, navigationManager); this.view = view; this.pluginManager = pluginManager; this.placeManager = placeManager; } public View getView() { return view; } public void setGotoItemEnabled(boolean enabled) { this.gotoItemEnabled = enabled; } @Override public String getTargetDivId() { return targetDivId; } @Override public void setTargetDivId(String targetDivId) { this.targetDivId = targetDivId; } @Override public String getDefaultNavItemId() { return defaultNavItemId; } @Override public void setDefaultNavItemId(String defaultNavItemId) { this.defaultNavItemId = defaultNavItemId; } @Override public void show(List itemList) { super.show(itemList); if (parent == null && gotoItemEnabled) { gotoDefaultItem(); } } protected boolean gotoDefaultItem() { boolean gotoItem = _gotoDefaultItem(); if (!gotoItem) { defaultNavItemId = getFirstRuntimePerspective(navItemList); gotoItem = _gotoDefaultItem(); } return gotoItem; } protected boolean _gotoDefaultItem() { if (defaultNavItemId != null) { if (setSelectedItem(defaultNavItemId)) { gotoNavItem(true); if (parent != null && onItemSelectedCommand != null) { onItemSelectedCommand.execute(); } return true; } } return false; } protected String getFirstRuntimePerspective(List itemList) { if (itemList.isEmpty()) { return null; } for (NavItem navItem : itemList) { if (pluginManager.isRuntimePerspective(navItem)) { return navItem.getId(); } if (navItem instanceof NavGroup) { String result = getFirstRuntimePerspective(((NavGroup) navItem).getChildren()); if (result != null) { return result; } } } return null; } @Override public void onItemClicked(NavItem navItem) { super.onItemClicked(navItem); this.gotoNavItem(false); } @Override public void onSubGroupItemClicked(NavWidget subGroup) { super.onSubGroupItemClicked(subGroup); this.gotoNavItem(false); } protected void gotoNavItem(boolean onlyRuntimePerspectives) { if (parent == null && gotoItemEnabled) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(getItemSelected()); String resourceId = navCtx.getResourceId(); String navRootId = navCtx.getNavGroupId(); if (resourceId != null) { if (pluginManager.isRuntimePerspective(resourceId)) { LayoutTemplateContext layoutCtx = new LayoutTemplateContext(navRootId); pluginManager.buildPerspectiveWidget(resourceId, layoutCtx, w -> view.showContent(targetDivId, w), this::onInfiniteRecursion); } else if (!onlyRuntimePerspectives) { placeManager.goTo(resourceId); } } else { view.clearContent(targetDivId); } } } public void onInfiniteRecursion(LayoutRecursionIssue issue) { String cause = issue.printReport(navigationManager.getNavTree(), view); view.infiniteRecursionError(targetDivId, cause); } // Catch changes on runtime perspectives so as to display the most up to date changes private void onPluginSaved(@Observes PluginSaved event) { Plugin plugin = event.getPlugin(); String pluginName = plugin.getName(); String selectedPerspectiveId = pluginManager.getRuntimePerspectiveId(itemSelected); if (selectedPerspectiveId != null && selectedPerspectiveId.equals(pluginName)) { gotoNavItem(true); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/TargetDivNavWidgetView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import java.util.function.Consumer; import com.google.gwt.core.client.Scheduler; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.common.client.widgets.AlertBox; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Element; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.common.client.dom.Window; import org.uberfire.ext.layout.editor.client.generator.AbstractLayoutGenerator; import org.uberfire.mvp.Command; public abstract class TargetDivNavWidgetView extends BaseNavWidgetView implements TargetDivNavWidget.View { AlertBox alertBox; public TargetDivNavWidgetView(AlertBox alertBox) { this.alertBox = alertBox; alertBox.setLevel(AlertBox.Level.WARNING); alertBox.setCloseEnabled(false); alertBox.getElement().getStyle().setProperty("width", "96%"); } @Override public void clearContent(String targetDivId) { Element targetDiv = getTargetDiv(targetDivId); if (targetDiv != null) { DOMUtil.removeAllChildren(targetDiv); } } @Override public void showContent(String targetDivId, IsWidget content) { getTargetDiv(targetDivId, targetDiv -> { DOMUtil.removeAllChildren(targetDiv); Div container = (Div) Window.getDocument().createElement("div"); container.getStyle().setProperty("overflow", "hidden"); targetDiv.appendChild(container); super.appendWidgetToElement(container, content); }, () -> error(NavigationConstants.INSTANCE.navWidgetTargetDivMissing())); } @Override public void errorNavGroupNotFound() { error(NavigationConstants.INSTANCE.navGroupNotFound()); } @Override public void errorNavItemsEmpty() { error(NavigationConstants.INSTANCE.navGroupEmptyError()); } @Override public void infiniteRecursionError(String targetDivId, String cause) { Element targetDiv = getTargetDiv(targetDivId); if (targetDiv != null) { DOMUtil.removeAllChildren(targetDiv); String message = NavigationConstants.INSTANCE.targetDivIdPerspectiveInfiniteRecursion() + cause; alertBox.setMessage(message); targetDiv.appendChild(alertBox.getElement()); } else { error(NavigationConstants.INSTANCE.targetDivIdPerspectiveInfiniteRecursion()); } } public void error(String message) { DOMUtil.removeAllChildren(navWidget); alertBox.setMessage(message); navWidget.appendChild(alertBox.getElement()); } protected Element getLayoutRootElement(Element el) { if (el == null) { return null; } String id = el.getAttribute("id"); if (id != null && (id.equals(AbstractLayoutGenerator.CONTAINER_ID) || id.equals("layout"))) { return el; } else { return getLayoutRootElement(el.getParentElement()); } } public void getTargetDiv(String targetDivId, Consumer divConsumer, Command notFoundDivCallback) { Scheduler.get().scheduleDeferred(() -> { HTMLElement targetDiv = getTargetDiv(targetDivId); if (targetDiv != null) { divConsumer.accept(targetDiv); } else { notFoundDivCallback.execute(); } }); } public HTMLElement getTargetDiv(String targetDivId) { HTMLElement targetDiv = null; if (targetDivId != null) { Element layoutRoot = getLayoutRootElement(navWidget.getParentElement()); if (layoutRoot != null) { targetDiv = (HTMLElement) layoutRoot.querySelector("#" + targetDivId); } } return targetDiv; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavItemDefaultEditor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.client.navigation.event.NavItemEditCancelledEvent; import org.dashbuilder.client.navigation.event.NavItemEditStartedEvent; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.PlaceManager; @Dependent public class NavItemDefaultEditor extends NavItemEditor { @Inject public NavItemDefaultEditor(NavItemDefaultEditorView view, SyncBeanManager beanManager, PlaceManager placeManager, PerspectiveTreeProvider perspectiveTreeProvider, TargetPerspectiveEditor targetPerspectiveEditor, PerspectivePluginManager perspectivePluginManager, Event navItemEditStartedEvent, Event navItemEditCancelledEvent) { super(view, beanManager, placeManager, perspectiveTreeProvider, targetPerspectiveEditor, perspectivePluginManager, navItemEditStartedEvent, navItemEditCancelledEvent); super.setChildEditorClass(NavItemDefaultEditor.class); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavItemDefaultEditorView.css ================================================ .uf-navitem-container { clear: both; } .uf-navitem-name { margin-left: 7px; } .uf-navitem-cog-icon, .uf-navitem-edit-icon, .uf-navitem-delete-icon { margin-left: 5px; visibility: hidden; cursor: pointer; } .uf-navitem-confirm-icon, .uf-navitem-cancel-icon { margin-left: 5px; cursor: pointer; } .uf-navitem-name-div { float: left; } .uf-navitem-name-input { margin-left: 7px; font-size: smaller; float: left; width: 150px; } .uf-navitem-name-error { border-color: #c00; border-width: 1px; } .uf-navitem-edit-div { } .uf-navitem-extra-div { margin-left: 22px; margin-bottom: 10px; display: none; } .uf-navitem-extra-div .dropdown-menu:before, .uf-navitem-extra-div .dropdown-menu:after { content: none; } .uf-navitem-extra-div .dropdown-menu { margin-top: -1px; margin-left: 15px; } .uf-navitem-view-div:hover, .uf-navitem-edit-div:hover { background-color: lightcyan; } .uf-navitem-view-div:hover .uf-navitem-cog-icon, .uf-navitem-view-div:hover .uf-navitem-edit-icon, .uf-navitem-view-div:hover .uf-navitem-delete-icon { visibility: visible; } .uf-navitem-edit-icon:hover, .uf-navitem-confirm-icon:hover, .uf-navitem-cancel-icon:hover { color: #0088ce; } .uf-navitem-delete-icon:hover { color: #990000; } .uf-navitem-children { margin-left: 15px; } .uf-navitem-command-menu { margin-left: 30px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavItemDefaultEditorView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavItemDefaultEditorView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.user.client.Event; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Input; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.mvp.Command; @Templated public class NavItemDefaultEditorView extends NavItemEditorView implements NavItemEditor.View { @Inject @DataField Span itemIcon; @Inject @DataField Span itemMenuIcon; @Inject @DataField Span itemEditIcon; @Inject @DataField Span itemDeleteIcon; @Inject @DataField Span itemConfirmIcon; @Inject @DataField Span itemCancelIcon; @Inject @DataField Span itemName; @Inject @DataField Input itemNameInput; @Inject @DataField Div extraDiv; @Inject @DataField Div itemViewDiv; @Inject @DataField Div itemEditDiv; @Inject @DataField UnorderedList commandMenu; @Inject @DataField Div childrenDiv; NavItemEditor presenter; @Override public void init(NavItemEditor presenter) { this.presenter = presenter; itemViewDiv.setHidden(false); itemEditDiv.setHidden(true); itemMenuIcon.setTitle(i18n.itemMenuTitle()); itemEditIcon.setTitle(i18n.editItem()); itemDeleteIcon.setTitle(i18n.deleteItem()); } @Override public void clearChildren() { DOMUtil.removeAllChildren(childrenDiv); } @Override public void addChild(org.jboss.errai.common.client.api.IsElement editor) { childrenDiv.appendChild(editor.getElement()); } @Override public void setExpandEnabled(boolean enabled) { if (enabled) { itemIcon.getStyle().removeProperty("opacity"); itemIcon.getStyle().removeProperty("pointer-events"); itemIcon.getStyle().setProperty("cursor", "pointer"); itemName.getStyle().setProperty("cursor", "pointer"); } else { itemIcon.getStyle().setProperty("opacity", ".5"); itemIcon.getStyle().setProperty("pointer-events", "none"); itemIcon.getStyle().removeProperty("cursor"); itemName.getStyle().removeProperty("cursor"); } } @Override public void setExpanded(boolean expanded) { itemIcon.setClassName(expanded ? "fa fa-angle-down" : "fa fa-angle-right"); childrenDiv.setHidden(!expanded); } @Override public void setItemName(String name) { itemName.setTextContent(name); itemNameInput.setValue(name); } @Override public String getItemName() { return itemNameInput.getValue(); } @Override public void setItemNameError(boolean hasError) { String classes = "uf-navitem-name-input" + (hasError ? " uf-navitem-name-error" : " form-control"); itemNameInput.setClassName(classes); } @Override public void setItemDescription(String description) { itemName.setTitle(description); } @Override public void setItemType(NavItemEditor.ItemType type) { itemIcon.getStyle().removeProperty("cursor"); if (type == NavItemEditor.ItemType.GROUP) { itemIcon.setClassName("fa fa-angle-right"); itemEditDiv.getStyle().setProperty("height", "25px"); itemIcon.setTitle(""); } else if (type == NavItemEditor.ItemType.DIVIDER) { itemIcon.setClassName("fa fa-minus"); itemIcon.setTitle(""); } else if (type == NavItemEditor.ItemType.PERSPECTIVE) { itemIcon.setClassName("fa fa-file-text-o"); itemIcon.setTitle(NavigationConstants.INSTANCE.perspectiveIconTitle()); } else if (type == NavItemEditor.ItemType.RUNTIME_PERSPECTIVE) { itemIcon.setClassName("fa fa-file-text-o"); itemIcon.setTitle(NavigationConstants.INSTANCE.pageIconTitle()); } } @Override public void addCommand(String name, Command command) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.setInnerText(name); LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); commandMenu.appendChild((Node) li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if(Event.ONCLICK == event.getTypeInt()) { command.execute(); } }); } @Override public void addCommandDivider() { LIElement li = Document.get().createLIElement(); li.setClassName("divider"); commandMenu.appendChild((Node) li); } @Override public void setCommandsEnabled(boolean enabled) { itemMenuIcon.setHidden(!enabled); commandMenu.setHidden(!enabled); } @Override public void clearCommands() { DOMUtil.removeAllChildren(commandMenu); } @Override public void startItemEdition() { itemViewDiv.setHidden(true); itemEditDiv.setHidden(false); itemNameInput.focus(); } @Override public void finishItemEdition() { itemViewDiv.setHidden(false); itemEditDiv.setHidden(true); } @Override public void setContextWidget(IsElement widget) { extraDiv.getStyle().setProperty("display", "block"); DOMUtil.removeAllChildren(extraDiv); extraDiv.appendChild(widget.getElement()); } @Override public void setItemEditable(boolean editable) { if (editable) { itemEditIcon.getStyle().removeProperty("display"); } else { itemEditIcon.getStyle().setProperty("display", "none"); } } @Override public void setItemDeletable(boolean deletable) { if (deletable) { itemDeleteIcon.getStyle().removeProperty("display"); } else { itemDeleteIcon.getStyle().setProperty("display", "none"); } } @EventHandler("itemIcon") public void onItemIconClick(ClickEvent event) { presenter.expandOrCollapse(); } @EventHandler("itemName") public void onItemNameClick(ClickEvent event) { presenter.expandOrCollapse(); } @EventHandler("itemEditIcon") public void onItemEditClick(ClickEvent event) { presenter.startEdition(); } @EventHandler("itemDeleteIcon") public void onItemDeleteClick(ClickEvent event) { presenter.deleteItemCommand(); } @EventHandler("itemConfirmIcon") public void onItemEditOkClick(ClickEvent event) { presenter.onChangesOk(); } @EventHandler("itemCancelIcon") public void onItemEditCancelClick(ClickEvent event) { presenter.cancelEdition(); } @EventHandler("itemNameInput") public void onItemNameInputOver(MouseOverEvent event) { itemNameInput.focus(); } @EventHandler("itemNameInput") public void onItemNameChanged(KeyPressEvent keyEvent) { if (keyEvent.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) { presenter.onChangesOk(); } else { presenter.onItemNameChanged(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavItemEditor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import javax.enterprise.event.Event; import com.google.gwt.core.client.GWT; import org.dashbuilder.client.navigation.event.NavItemEditCancelledEvent; import org.dashbuilder.client.navigation.event.NavItemEditStartedEvent; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.AbstractWorkbenchPerspectiveActivity; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElement; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.ActivityResourceType; public abstract class NavItemEditor implements IsElement { public enum ItemType { DIVIDER, GROUP, PERSPECTIVE, RUNTIME_PERSPECTIVE; } public interface View

extends UberElement

{ void clearChildren(); void addChild(IsElement editor); void setExpandEnabled(boolean enabled); void setExpanded(boolean expanded); void setItemName(String name); String getItemName(); void setItemNameError(boolean hasError); void setItemDescription(String description); void setItemType(ItemType type); void addCommand(String name, Command command); void addCommandDivider(); void setCommandsEnabled(boolean enabled); void clearCommands(); void setItemEditable(boolean editable); void setItemDeletable(boolean deletable); void startItemEdition(); void finishItemEdition(); void setContextWidget(IsElement widget); String i18nNewItem(String item); String i18nNewItemName(String item); String i18nGotoItem(String item); String i18nDeleteItem(); String i18nMoveUp(); String i18nMoveDown(); String i18nMoveFirst(); String i18nMoveLast(); String generateId(); } View view; SyncBeanManager beanManager; PlaceManager placeManager; PerspectiveTreeProvider perspectiveTreeProvider; TargetPerspectiveEditor targetPerspectiveEditor; PerspectivePluginManager perspectivePluginManager; Event navItemEditStartedEvent; Event navItemEditCancelledEvent; boolean creationEnabled = false; boolean moveUpEnabled = true; boolean moveDownEnabled = true; boolean editEnabled = false; boolean deleteEnabled = false; boolean itemNameFromPerspective = false; private NavItemEditorSettings settings; private Class childEditorClass; NavItemEditor parentEditor = null; List childEditorList = new ArrayList<>(); NavItem navItem = null; NavItem navItemBackup = null; ItemType itemType = null; String perspectiveId = null; boolean expanded; Command onUpdateCommand; Command onCancelCommand; Command onMoveUpCommand; Command onMoveDownCommand; Command onMoveFirstCommand; Command onMoveLastCommand; Command onDeleteCommand; Command onExpandCommand; public static final NavigationConstants i18n = NavigationConstants.INSTANCE; public NavItemEditor(View view, SyncBeanManager beanManager, PlaceManager placeManager, PerspectiveTreeProvider perspectiveTreeProvider, TargetPerspectiveEditor targetPerspectiveEditor, PerspectivePluginManager perspectivePluginManager, Event navItemEditStartedEvent, Event navItemEditCancelledEvent) { this.beanManager = beanManager; this.placeManager = placeManager; this.perspectiveTreeProvider = perspectiveTreeProvider; this.targetPerspectiveEditor = targetPerspectiveEditor; this.targetPerspectiveEditor.setOnUpdateCommand(this::onTargetPerspectiveUpdated); this.perspectivePluginManager = perspectivePluginManager; this.navItemEditStartedEvent = navItemEditStartedEvent; this.navItemEditCancelledEvent = navItemEditCancelledEvent; this.view = view; this.view.init(this); } @Override public HTMLElement getElement() { return view.getElement(); } public NavItemEditorSettings getSettings() { if (settings == null) { settings = new NavItemEditorSettings(); } return settings; } public void setSettings(NavItemEditorSettings settings) { this.settings = settings; } public Class getChildEditorClass() { return childEditorClass; } public void setChildEditorClass(Class childEditorClass) { this.childEditorClass = childEditorClass; } public NavItemEditor getParentEditor() { return parentEditor; } public void setParentEditor(NavItemEditor parentEditor) { this.parentEditor = parentEditor; NavItemEditor rootEditor = getRootEditor(); if (rootEditor != null && rootEditor.getNavItem() instanceof NavGroup) { NavGroup rootGroup = (NavGroup) rootEditor.getNavItem(); targetPerspectiveEditor.setNavItemList(rootGroup.getChildren()); } } public NavItemEditor getRootEditor() { return parentEditor == null ? this : parentEditor.getRootEditor(); } public int getLevel() { if (parentEditor == null) { return 0; } return parentEditor.getLevel() + 1; } public boolean isExpanded() { return expanded; } public String getGroupLiteral() { return settings != null ? settings.getLiteralGroup() : "Group"; } public String getNewPerspectiveI18n() { String newItemName = view.i18nNewItemName(getPerspectiveLiteral()); return newItemName != null ? newItemName : "- New Perspective -"; } public String getPerspectiveLiteral() { return settings != null ? settings.getLiteralPerspective() : "Perspective"; } public String getDividerLiteral() { return settings != null ? settings.getLiteralDivider() : "Divider"; } public boolean isNewGroupEnabled() { return (settings == null || settings.isNewGroupEnabled(navItem)) && areSubgroupsAllowed(); } public boolean isNewPerspectiveEnabled() { return (settings == null || settings.isNewPerspectiveEnabled(navItem)) && areChildrenAllowed() && (!getPerspectiveIds(navItem, true).isEmpty()); } public boolean isNewDividerEnabled() { return (settings == null || settings.isNewDividerEnabled(navItem)) && areChildrenAllowed(); } public boolean isGotoPerspectiveEnabled() { return (settings == null || settings.isGotoPerspectiveEnabled(navItem)) && perspectiveId != null; } public boolean isMoveUpEnabled() { return moveUpEnabled; } public void setMoveUpEnabled(boolean moveUpEnabled) { this.moveUpEnabled = moveUpEnabled; } public boolean isMoveDownEnabled() { return moveDownEnabled; } public void setMoveDownEnabled(boolean moveDownEnabled) { this.moveDownEnabled = moveDownEnabled; } public void setOnUpdateCommand(Command onUpdateCommand) { this.onUpdateCommand = onUpdateCommand; } public void setOnCancelCommand(Command onCancelCommand) { this.onCancelCommand = onCancelCommand; } public void setOnMoveFirstCommand(Command onMoveFirstCommand) { this.onMoveFirstCommand = onMoveFirstCommand; } public void setOnMoveLastCommand(Command onMoveLastCommand) { this.onMoveLastCommand = onMoveLastCommand; } public void setOnMoveUpCommand(Command onMoveUpCommand) { this.onMoveUpCommand = onMoveUpCommand; } public void setOnMoveDownCommand(Command onMoveDownCommand) { this.onMoveDownCommand = onMoveDownCommand; } public void setOnDeleteCommand(Command onDeleteCommand) { this.onDeleteCommand = onDeleteCommand; } public void setOnExpandCommand(Command onExpandCommand) { this.onExpandCommand = onExpandCommand; } public NavItem getNavItem() { return navItem; } public void edit(NavItem navItem) { this.clear(); this.navItem = navItem.cloneItem(); this.navItemBackup = navItem; this.doEdit(); } public boolean canBeExpanded() { return ItemType.GROUP.equals(itemType) && !childEditorList.isEmpty(); } public void expand() { if (!expanded && canBeExpanded()) { expanded = true; view.setExpanded(expanded); } } public void collapse() { if (expanded && canBeExpanded()) { expanded = false; view.setExpanded(expanded); } } public void expandAll() { this.expand(); childEditorList.forEach(NavItemEditor::expandAll); } public void collapseAll() { this.collapse(); childEditorList.forEach(NavItemEditor::collapseAll); } public void expandOrCollapse() { if (canBeExpanded()) { if (expanded) { collapse(); } else { expand(); } if (onExpandCommand != null) { onExpandCommand.execute(); } } } public void startEdition() { if (editEnabled) { if (itemNameFromPerspective) { String perspectiveName = targetPerspectiveEditor.getPerspectiveName(perspectiveId); view.setItemName(perspectiveName); } if (settings == null || settings.isPerspectiveContextEnabled(navItem)) { perspectivePluginManager.getLayoutTemplateInfo(perspectiveId, info -> { targetPerspectiveEditor.setNavGroupEnabled(info != null && info.hasNavigationComponents()); view.startItemEdition(); navItemEditStartedEvent.fire(new NavItemEditStartedEvent(this)); }); } else { targetPerspectiveEditor.setNavGroupEnabled(false); view.startItemEdition(); navItemEditStartedEvent.fire(new NavItemEditStartedEvent(this)); } } } public void finishEdition() { view.finishItemEdition(); childEditorList.forEach(NavItemEditor::finishEdition); } public void cancelEdition() { view.finishItemEdition(); edit(navItemBackup); onEditCancelled(); } private void doEdit() { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); if (navItem.getName() != null) { view.setItemName(navItem.getName()); String newPerspectiveI18n = getNewPerspectiveI18n(); itemNameFromPerspective = newPerspectiveI18n.equals(navItem.getName()); } if (navItem.getDescription() != null) { view.setItemDescription(navItem.getDescription()); } creationEnabled = false; editEnabled = navItem.isModifiable(); deleteEnabled = navItem.isModifiable(); // Nav group if (navItem instanceof NavGroup) { view.setItemType(itemType = ItemType.GROUP); view.setExpandEnabled(false); if (areChildrenAllowed()) { view.setExpanded(expanded); creationEnabled = true; NavGroup navGroup = (NavGroup) navItem; registerChildren(navGroup); } } // Divider else if (navItem instanceof NavDivider) { view.setItemType(itemType = ItemType.DIVIDER); view.setItemName("--------------"); editEnabled = false; } else { if (navCtx.getResourceId() != null) { // Nav perspective item if (ActivityResourceType.PERSPECTIVE.equals(navCtx.getResourceType())) { Set visiblePerspectiveIds = getPerspectiveIds(navItem, true); if (visiblePerspectiveIds.isEmpty() || visiblePerspectiveIds.contains(navCtx.getResourceId())) { perspectiveId = navCtx.getResourceId(); } else if (!visiblePerspectiveIds.isEmpty()) { perspectiveId = visiblePerspectiveIds.iterator().next(); navCtx.setResourceId(perspectiveId); navItem.setContext(navCtx.toString()); } Set hiddenPerspectiveIds = getPerspectiveIds(navItem, false); boolean isRuntimePerspective = perspectivePluginManager.isRuntimePerspective(perspectiveId); String selectedNavGroupId = navCtx.getNavGroupId(); targetPerspectiveEditor.clear(); targetPerspectiveEditor.setPerspectiveId(perspectiveId); targetPerspectiveEditor.setNavGroupId(selectedNavGroupId); targetPerspectiveEditor.setPerspectiveIdsExcluded(hiddenPerspectiveIds); targetPerspectiveEditor.show(); view.setItemType(itemType = isRuntimePerspective ? ItemType.RUNTIME_PERSPECTIVE : ItemType.PERSPECTIVE); view.setContextWidget(targetPerspectiveEditor); } } else { // Ignore non supported items } } view.setItemEditable(editEnabled); view.setItemDeletable(deleteEnabled); addCommands(); } public void clear() { navItem = null; perspectiveId = null; view.clearChildren(); view.clearCommands(); } public boolean areChildrenAllowed() { return areChildrenAllowed(0, this); } public boolean areSubgroupsAllowed() { return areSubgroupsAllowed(0, this); } private boolean areChildrenAllowed(int levels, NavItemEditor editor) { if (editor == null) { return settings == null || settings.getMaxLevels() < 0 || levels < settings.getMaxLevels(); } else { int itemMaxLevels = settings != null ? settings.getMaxLevels(editor.getNavItem().getId()) : -1; return itemMaxLevels != -1 ? levels < itemMaxLevels : areChildrenAllowed(levels+1, editor.getParentEditor()); } } private boolean areSubgroupsAllowed(int levels, NavItemEditor editor) { if (editor == null) { return settings == null || settings.getMaxLevels() < 0 || levels < settings.getMaxLevels() - 1; } else { int itemMaxLevels = settings != null ? settings.getMaxLevels(editor.getNavItem().getId()) - 1 : -1; return itemMaxLevels > -1 ? levels < itemMaxLevels : areSubgroupsAllowed(levels+1, editor.getParentEditor()); } } public NavItemEditor createChildEditor(NavItem navItem) { Class childEditorClass = getChildEditorClass(); NavItemEditor navItemEditor = beanManager.lookupBean(childEditorClass).newInstance(); navItemEditor.setParentEditor(this); navItemEditor.setSettings(settings); navItemEditor.setOnUpdateCommand(() -> onUpdateChild(navItem, navItemEditor)); navItemEditor.setOnCancelCommand(() -> onCancelChild(navItem, navItemEditor)); navItemEditor.setOnDeleteCommand(() -> onDeleteChild(navItemEditor)); navItemEditor.setOnMoveFirstCommand(() -> onMoveFirstChild(navItemEditor)); navItemEditor.setOnMoveLastCommand(() -> onMoveLastChild(navItemEditor)); navItemEditor.setOnMoveUpCommand(() -> onMoveUpChild(navItemEditor)); navItemEditor.setOnMoveDownCommand(() -> onMoveDownChild(navItemEditor)); return navItemEditor; } public Set getPerspectiveIds(NavItem navItem, boolean visible) { boolean onlyRuntime = settings == null || settings.onlyRuntimePerspectives(navItem); Set runtimeIds = getRuntimePerspectiveIds(); Set hardCodedIds = getHardCodedPerspectiveIds(); Set excludedIds = perspectiveTreeProvider.getPerspectiveIdsExcluded(); if (visible) { if (!onlyRuntime) { runtimeIds.addAll(hardCodedIds); } return runtimeIds.stream() .filter(id -> !excludedIds.contains(id)) .collect(Collectors.toSet()); } else { if (onlyRuntime) { hardCodedIds.addAll(excludedIds); return hardCodedIds; } return excludedIds; } } private Set getRuntimePerspectiveIds() { Set result = new HashSet<>(); perspectivePluginManager.getPerspectivePlugins(plugins -> { plugins.forEach(p -> { String perspectiveId = p.getName(); result.add(perspectiveId); }); }); return result; } private Set getHardCodedPerspectiveIds() { Set result = new HashSet<>(); Collection> beanDefs = beanManager.lookupBeans(AbstractWorkbenchPerspectiveActivity.class); beanDefs.forEach(beanDef -> { AbstractWorkbenchPerspectiveActivity bean = beanDef.getInstance(); String perspectiveId = bean.getIdentifier(); result.add(perspectiveId); beanManager.destroyBean(bean); }); return result; } // Item commands private void addCommands() { boolean dividerRequired = false; if (creationEnabled) { boolean newGroupEnabled = isNewGroupEnabled(); if (newGroupEnabled) { this.addCommand(view.i18nNewItem(getGroupLiteral()), this::newGroup); dividerRequired = true; } boolean newDividerEnabled = isNewDividerEnabled(); if (newDividerEnabled) { this.addCommand(view.i18nNewItem(getDividerLiteral()), this::newDivider); dividerRequired = true; } boolean newPerspectiveEnabled = isNewPerspectiveEnabled(); if (newPerspectiveEnabled) { this.addCommand(view.i18nNewItem(getPerspectiveLiteral()), this::newPerspective); dividerRequired = true; } } if (moveUpEnabled || moveDownEnabled) { if (dividerRequired) { view.addCommandDivider(); } dividerRequired = true; if (moveUpEnabled) { this.addCommand(view.i18nMoveFirst(), this::moveFirstCommand); this.addCommand(view.i18nMoveUp(), this::moveUpCommand); } if (moveDownEnabled) { this.addCommand(view.i18nMoveDown(), this::moveDownCommand); this.addCommand(view.i18nMoveLast(), this::moveLastCommand); } } if (isGotoPerspectiveEnabled()) { if (dividerRequired) { view.addCommandDivider(); } dividerRequired = true; this.addCommand(view.i18nGotoItem(getPerspectiveLiteral()), this::gotoPerspectiveCommand); } } private void addCommand(String name, Command action) { view.addCommand(name, action); view.setCommandsEnabled(true); } private void refreshCommands() { view.clearCommands(); this.addCommands(); } public NavItemEditor newGroup() { NavGroup navGroup = (NavGroup) navItem; String id = "group_" + view.generateId(); String name = i18n.newItemName(getGroupLiteral()); NavGroup newItem = NavFactory.get().createNavGroup(); newItem.setParent(navGroup); newItem.setId(id); newItem.setName(name); newItem.setModifiable(true); NavItemEditor childEditor = registerChild(newItem); childEditor.startEdition(); this.expand(); return childEditor; } public NavItemEditor newPerspective() { NavGroup navGroup = (NavGroup) navItem; String id = "perspective_" + view.generateId(); String name = i18n.newItemName(getPerspectiveLiteral()); NavItem newItem = NavFactory.get().createNavItem(); newItem.setParent(navGroup); newItem.setId(id); newItem.setName(name); newItem.setModifiable(true); Set visiblePerspectiveIds = getPerspectiveIds(navGroup, true); if (!visiblePerspectiveIds.isEmpty()) { String firstPerspective = visiblePerspectiveIds.iterator().next(); newItem.setContext(NavWorkbenchCtx.perspective(firstPerspective).toString()); } NavItemEditor childEditor = registerChild(newItem); childEditor.startEdition(); this.expand(); return childEditor; } public NavItemEditor newDivider() { NavGroup navGroup = (NavGroup) navItem; String id = "divider_" + view.generateId(); NavDivider newItem = NavFactory.get().createDivider(); newItem.setId(id); newItem.setParent(navGroup); newItem.setModifiable(true); NavItemEditor childEditor = registerChild(newItem); this.onUpdateChild(newItem, childEditor); this.expand(); return childEditor; } void gotoPerspectiveCommand() { if (perspectiveId != null) { placeManager.goTo(perspectiveId); } } void deleteItemCommand() { if (deleteEnabled && onDeleteCommand != null) { onDeleteCommand.execute(); } } void moveUpCommand() { if (onMoveUpCommand != null) { onMoveUpCommand.execute(); } } void moveDownCommand() { if (onMoveDownCommand != null) { onMoveDownCommand.execute(); } } void moveFirstCommand() { if (onMoveFirstCommand != null) { onMoveFirstCommand.execute(); } } void moveLastCommand() { if (onMoveLastCommand != null) { onMoveLastCommand.execute(); } } // Children callbacks void onItemUpdated() { navItemBackup = navItem.cloneItem(); if (onUpdateCommand != null) { onUpdateCommand.execute(); } } void onEditCancelled() { if (onCancelCommand != null) { onCancelCommand.execute(); } } void onMoveUpChild(NavItemEditor navItemEditor) { if (childEditorList.size() > 1) { int idx = childEditorList.indexOf(navItemEditor); if (idx > 0 && idx < childEditorList.size()) { childEditorList.remove(idx); childEditorList.add(idx-1, navItemEditor); refreshChildren(); NavGroup navGroup = (NavGroup) navItem; navGroup.getChildren().remove(idx); navGroup.getChildren().add(idx-1, navItemEditor.getNavItem()); onItemUpdated(); } } } void onMoveDownChild(NavItemEditor navItemEditor) { if (childEditorList.size() > 1) { int idx = childEditorList.indexOf(navItemEditor); if (idx > -1 && idx < childEditorList.size()-1) { childEditorList.remove(idx); childEditorList.add(idx+1, navItemEditor); refreshChildren(); NavGroup navGroup = (NavGroup) navItem; navGroup.getChildren().remove(idx); navGroup.getChildren().add(idx+1, navItemEditor.getNavItem()); onItemUpdated(); } } } void onMoveFirstChild(NavItemEditor navItemEditor) { if (childEditorList.size() > 1) { int idx = childEditorList.indexOf(navItemEditor); if (idx > 0 && idx < childEditorList.size()) { childEditorList.remove(idx); childEditorList.add(0, navItemEditor); refreshChildren(); NavGroup navGroup = (NavGroup) navItem; navGroup.getChildren().remove(idx); navGroup.getChildren().add(0, navItemEditor.getNavItem()); onItemUpdated(); } } } void onMoveLastChild(NavItemEditor navItemEditor) { if (childEditorList.size() > 1) { int idx = childEditorList.indexOf(navItemEditor); if (idx > -1 && idx < childEditorList.size()-1) { childEditorList.remove(idx); childEditorList.add(navItemEditor); refreshChildren(); NavGroup navGroup = (NavGroup) navItem; navGroup.getChildren().remove(idx); navGroup.getChildren().add(navItemEditor.getNavItem()); onItemUpdated(); } } } void onUpdateChild(NavItem oldItem, NavItemEditor childEditor) { NavItem newItem = childEditor.getNavItem(); NavGroup navGroup = (NavGroup) navItem; int idx = navGroup.getChildren().indexOf(oldItem); if (idx != -1) { navGroup.getChildren().remove(idx); navGroup.getChildren().add(idx, newItem); onItemUpdated(); } else { // Creation of a brand new child navGroup.getChildren().add(newItem); onItemUpdated(); } } void onCancelChild(NavItem oldItem, NavItemEditor childEditor) { NavGroup navGroup = (NavGroup) navItem; int idx = navGroup.getChildren().indexOf(oldItem); if (idx == -1) { // Cancel of a brand new child creation childEditorList.remove(childEditor); refreshChildren(); } } void onDeleteChild(NavItemEditor navItemEditor) { NavGroup navGroup = (NavGroup) navItem; navGroup.getChildren().remove(navItemEditor.getNavItem()); childEditorList.remove(navItemEditor); refreshChildren(); onItemUpdated(); } private void registerChildren(NavGroup navGroup) { List oldChildEditorList = new ArrayList<>(childEditorList); childEditorList.clear(); List childList = navGroup.getChildren(); for (int i=0; i result = oldChildEditorList.stream() .filter(editor -> editor.getNavItem().equals(childItem)) .findFirst(); NavItemEditor childEditor = result.isPresent() ? result.get() : createChildEditor(childItem); oldChildEditorList.remove(childEditor); childEditor.edit(childItem); childEditorList.add(childEditor); } // Destroy the remaining editors oldChildEditorList.forEach(beanManager::destroyBean); oldChildEditorList.clear(); // Refresh the children view this.refreshChildren(); } private NavItemEditor registerChild(NavItem item) { NavItemEditor childEditor = createChildEditor(item); childEditor.edit(item); childEditorList.add(childEditor); refreshChildren(); return childEditor; } private void refreshChildren() { view.clearChildren(); view.setExpandEnabled(canBeExpanded()); if (childEditorList.isEmpty()) { expanded = false; view.setExpanded(false); } for (int i = 0; i< childEditorList.size(); i++) { NavItemEditor childEditor = childEditorList.get(i); childEditor.setMoveUpEnabled(i > 0); childEditor.setMoveDownEnabled(i < childEditorList.size()-1); childEditor.refreshCommands(); view.addChild(childEditor); } } // View actions void onChangesOk() { boolean error = false; // Capture name changes String name = view.getItemName(); if (name != null && !name.trim().isEmpty()) { if (!name.equals(navItem.getName())) { navItem.setName(name); view.setItemName(name); String newPerspectiveI18n = getNewPerspectiveI18n(); itemNameFromPerspective = newPerspectiveI18n.equals(name); } } else { error = true; view.setItemNameError(error); } // Capture perspective changes if (!error && ItemType.PERSPECTIVE.equals(itemType) || ItemType.RUNTIME_PERSPECTIVE.equals(itemType)) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); String oldPerspectiveId = navCtx.getResourceId(); String newPerspectiveId = targetPerspectiveEditor.getPerspectiveId(); if (newPerspectiveId != null && !newPerspectiveId.trim().isEmpty()) { if (oldPerspectiveId != null && !oldPerspectiveId.equals(newPerspectiveId)){ navCtx.setResourceId(perspectiveId = newPerspectiveId); navItem.setContext(navCtx.toString()); } } else { error = true; } boolean isRuntimePerspective = perspectivePluginManager.isRuntimePerspective(newPerspectiveId); String newGroupId = isRuntimePerspective ? targetPerspectiveEditor.getNavGroupId() : null; String oldGroupId = navCtx.getNavGroupId(); if ((oldGroupId == null && newGroupId != null) || oldGroupId != null && !oldGroupId.equals(newGroupId)) { navCtx.setNavGroupId(newGroupId); navItem.setContext(navCtx.toString()); } } // Process updates if (!error) { finishEdition(); onItemUpdated(); } } void onItemNameChanged() { itemNameFromPerspective = false; } void onTargetPerspectiveUpdated() { String perspectiveId = targetPerspectiveEditor.getPerspectiveId(); if (itemNameFromPerspective) { String perspectiveName = targetPerspectiveEditor.getPerspectiveName(perspectiveId); view.setItemName(perspectiveName); } if (settings == null || settings.isPerspectiveContextEnabled(navItem)) { perspectivePluginManager.getLayoutTemplateInfo(perspectiveId, info -> { targetPerspectiveEditor.setNavGroupEnabled(info != null && info.hasNavigationComponents()); }); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavItemEditorSettings.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import java.util.HashMap; import java.util.Map; import org.dashbuilder.navigation.NavItem; public class NavItemEditorSettings { private int maxLevels = -1; private String literalGroup = "Group"; private String literalPerspective = "Perspective"; private String literalDivider = "Divider"; private boolean newDividerEnabled = true; private boolean newGroupEnabled = true; private boolean newPerspectiveEnabled = true; private boolean gotoPerspectiveEnabled = false; private boolean perspectiveContextEnabled = true; private boolean onlyRuntimePerspectives = true; private Map maxLevelsMap = new HashMap<>(); private Map flagsMap = new HashMap<>(); public class Flags { public static final String NEW_GROUP = "newGroup"; public static final String NEW_PERSPECTIVE = "newPerspective"; public static final String NEW_DIVIDER = "newDivider"; public static final String ONLY_RUNTIME_PERSPECTIVES = "onlyRuntimePerspectives"; public static final String GOTO_PERSPECTIVE = "gotoPerspective"; public static final String PERSPECTIVE_CONTEXT = "perspectiveContext"; Map flagMap = new HashMap<>(); Map recursiveMap = new HashMap<>(); String lastProp = null; void setFlag(String prop, boolean enabled) { flagMap.put(prop, enabled); lastProp = prop; } boolean isEnabled(String prop) { if (flagMap.containsKey(prop)) { return flagMap.get(prop); } else { return false; } } public void applyToAllChildren() { if (lastProp != null) { recursiveMap.put(lastProp, true); } } } public void setLiteralGroup(String literalGroup) { this.literalGroup = literalGroup; } public void setLiteralPerspective(String literalPerspective) { this.literalPerspective = literalPerspective; } public void setLiteralDivider(String literalDivider) { this.literalDivider = literalDivider; } public String getLiteralGroup() { return literalGroup; } public String getLiteralPerspective() { return literalPerspective; } public String getLiteralDivider() { return literalDivider; } private Flags setNavItemPropertyEnabled(String navItemId, String prop, boolean enabled) { Flags config = flagsMap.get(navItemId); if (config == null) { flagsMap.put(navItemId, config = new Flags()); } config.setFlag(prop, enabled); return config; } private Boolean isNavItemPropertyEnabled(NavItem navItem, String prop) { Flags config = flagsMap.get(navItem.getId()); if (config != null && config.flagMap.get(prop) != null) { return config.flagMap.get(prop); } return isNavAncestorPropertyEnabled(navItem.getParent(), prop); } private Boolean isNavAncestorPropertyEnabled(NavItem navItem, String prop) { if (navItem == null) { return null; } Flags config = flagsMap.get(navItem.getId()); if (config != null && config.flagMap.get(prop) != null && config.recursiveMap.get(prop) != null && config.recursiveMap.get(prop)) { return config.flagMap.get(prop); } else { return isNavAncestorPropertyEnabled(navItem.getParent(), prop); } } public boolean isNewGroupEnabled() { return newGroupEnabled; } public NavItemEditorSettings setNewGroupEnabled(boolean newGroupEnabled) { this.newGroupEnabled = newGroupEnabled; return this; } public boolean isNewGroupEnabled(NavItem navItem) { Boolean enabled = isNavItemPropertyEnabled(navItem, Flags.NEW_GROUP); return enabled != null ? enabled : newGroupEnabled; } public Flags setNewGroupEnabled(String navItemId, boolean enabled) { return setNavItemPropertyEnabled(navItemId, Flags.NEW_GROUP, enabled); } public boolean isNewPerspectiveEnabled() { return newPerspectiveEnabled; } public NavItemEditorSettings setNewPerspectiveEnabled(boolean newPerspectiveEnabled) { this.newPerspectiveEnabled = newPerspectiveEnabled; return this; } public boolean isNewPerspectiveEnabled(NavItem navItem) { Boolean enabled = isNavItemPropertyEnabled(navItem, Flags.NEW_PERSPECTIVE); return enabled != null ? enabled : newPerspectiveEnabled; } public Flags setNewPerspectiveEnabled(String navItemId, boolean enabled) { return setNavItemPropertyEnabled(navItemId, Flags.NEW_PERSPECTIVE, enabled); } public boolean isNewDividerEnabled() { return newDividerEnabled; } public NavItemEditorSettings setNewDividerEnabled(boolean newDividerEnabled) { this.newDividerEnabled = newDividerEnabled; return this; } public boolean isNewDividerEnabled(NavItem navItem) { Boolean enabled = isNavItemPropertyEnabled(navItem, Flags.NEW_DIVIDER); return enabled != null ? enabled : newDividerEnabled; } public Flags setNewDividerEnabled(String navItemId, boolean enabled) { return setNavItemPropertyEnabled(navItemId, Flags.NEW_DIVIDER, enabled); } public boolean onlyRuntimePerspectives(NavItem navItem) { Boolean enabled = isNavItemPropertyEnabled(navItem, Flags.ONLY_RUNTIME_PERSPECTIVES); return enabled != null ? enabled : onlyRuntimePerspectives; } public Flags setOnlyRuntimePerspectives(String navItemId, boolean enabled) { return setNavItemPropertyEnabled(navItemId, Flags.ONLY_RUNTIME_PERSPECTIVES, enabled); } public boolean isGotoPerspectiveEnabled() { return gotoPerspectiveEnabled; } public NavItemEditorSettings setGotoPerspectiveEnabled(boolean gotoPerspectiveEnabled) { this.gotoPerspectiveEnabled = gotoPerspectiveEnabled; return this; } public boolean isGotoPerspectiveEnabled(NavItem navItem) { Boolean enabled = isNavItemPropertyEnabled(navItem, Flags.GOTO_PERSPECTIVE); return enabled != null ? enabled : gotoPerspectiveEnabled; } public Flags setGotoPerspectiveEnabled(String navItemId, boolean enabled) { return setNavItemPropertyEnabled(navItemId, Flags.GOTO_PERSPECTIVE, enabled); } public boolean isPerspectiveContextEnabled() { return perspectiveContextEnabled; } public NavItemEditorSettings setPerspectiveContextEnabled(boolean perspectiveContextEnabled) { this.perspectiveContextEnabled = perspectiveContextEnabled; return this; } public boolean isPerspectiveContextEnabled(NavItem navItem) { Boolean enabled = isNavItemPropertyEnabled(navItem, Flags.PERSPECTIVE_CONTEXT); return enabled != null ? enabled : perspectiveContextEnabled; } public Flags setPerspectiveContextEnabled(String navItemId, boolean enabled) { return setNavItemPropertyEnabled(navItemId, Flags.PERSPECTIVE_CONTEXT, enabled); } public int getMaxLevels() { return maxLevels; } public NavItemEditorSettings setMaxLevels(String navItemId, int maxLevels) { maxLevelsMap.put(navItemId, maxLevels); return this; } public int getMaxLevels(String navItemId) { if (!maxLevelsMap.containsKey(navItemId)) { return -1; } else { return maxLevelsMap.get(navItemId); } } public NavItemEditorSettings setMaxLevels(int maxLevels) { this.maxLevels = maxLevels; return this; } public boolean isOnlyRuntimePerspectives() { return onlyRuntimePerspectives; } public NavItemEditorSettings setOnlyRuntimePerspectives(boolean onlyRuntimePerspectives) { this.onlyRuntimePerspectives = onlyRuntimePerspectives; return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavItemEditorView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import com.google.gwt.core.client.Duration; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; public abstract class NavItemEditorView

implements org.jboss.errai.ui.client.local.api.IsElement, NavItemEditor.View

{ NavigationConstants i18n = NavigationConstants.INSTANCE; @Override public String i18nNewItem(String item) { return i18n.newItem(item); } @Override public String i18nNewItemName(String item) { return i18n.newItemName(item); } @Override public String i18nGotoItem(String item) { return i18n.gotoItem(item); } @Override public String i18nDeleteItem() { return i18n.deleteItem(); } @Override public String i18nMoveUp() { return i18n.moveUp(); } @Override public String i18nMoveDown() { return i18n.moveDown(); } @Override public String i18nMoveFirst() { return i18n.moveFirst(); } @Override public String i18nMoveLast() { return i18n.moveLast(); } @Override public String generateId() { return Double.toString(Duration.currentTimeMillis()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavRootNodeEditor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.client.navigation.event.NavItemEditCancelledEvent; import org.dashbuilder.client.navigation.event.NavItemEditStartedEvent; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.PlaceManager; /** * An item editor used to handle {@link NavTree} root nodes */ @Dependent public class NavRootNodeEditor extends NavItemEditor { public interface View extends NavItemEditor.View { } NavRootNodeEditorView view; @Inject public NavRootNodeEditor(NavRootNodeEditorView view, SyncBeanManager beanManager, PlaceManager placeManager, PerspectiveTreeProvider perspectiveTreeProvider, TargetPerspectiveEditor targetPerspectiveEditor, PerspectivePluginManager perspectivePluginManager, Event navItemEditStartedEvent, Event navItemEditCancelledEvent) { super(view, beanManager, placeManager, perspectiveTreeProvider, targetPerspectiveEditor, perspectivePluginManager, navItemEditStartedEvent, navItemEditCancelledEvent); this.view = view; this.view.init(this); super.setChildEditorClass(NavItemDefaultEditor.class); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavRootNodeEditorView.css ================================================ .uf-navitem-container { clear: both; } .uf-navitem-name { margin-left: 7px; } .uf-navitem-cog-icon, .uf-navitem-edit-icon, .uf-navitem-delete-icon { margin-left: 5px; visibility: hidden; cursor: pointer; } .uf-navitem-confirm-icon, .uf-navitem-cancel-icon { margin-left: 5px; cursor: pointer; } .uf-navitem-name-div { float: left; } .uf-navitem-name-input { margin-left: 7px; font-size: smaller; float: left; width: 150px; } .uf-navitem-name-error { border-color: #c00; border-width: 1px; } .uf-navitem-edit-div { } .uf-navitem-extra-div { margin-left: 22px; margin-bottom: 10px; display: none; } .uf-navitem-extra-div .dropdown-menu:before, .uf-navitem-extra-div .dropdown-menu:after { content: none; } .uf-navitem-extra-div .dropdown-menu { margin-top: -1px; margin-left: 15px; } .uf-navitem-view-div:hover, .uf-navitem-edit-div:hover { background-color: lightcyan; } .uf-navitem-view-div:hover .uf-navitem-cog-icon, .uf-navitem-view-div:hover .uf-navitem-edit-icon, .uf-navitem-view-div:hover .uf-navitem-delete-icon { visibility: visible; } .uf-navitem-edit-icon:hover, .uf-navitem-confirm-icon:hover, .uf-navitem-cancel-icon:hover { color: #0088ce; } .uf-navitem-delete-icon:hover { color: #990000; } .uf-navitem-children { margin-left: 15px; } .uf-navitem-command-menu { margin-left: 30px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavRootNodeEditorView.html ================================================

================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavRootNodeEditorView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.user.client.Event; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Input; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.mvp.Command; @Templated public class NavRootNodeEditorView extends NavItemEditorView implements NavRootNodeEditor.View { @Inject @DataField Span itemIcon; @Inject @DataField Span itemMenuIcon; @Inject @DataField Span itemEditIcon; @Inject @DataField Span itemDeleteIcon; @Inject @DataField Span itemConfirmIcon; @Inject @DataField Span itemCancelIcon; @Inject @DataField Span itemName; @Inject @DataField Input itemNameInput; @Inject @DataField Div extraDiv; @Inject @DataField Div itemViewDiv; @Inject @DataField Div itemEditDiv; @Inject @DataField UnorderedList commandMenu; @Inject @DataField Div childrenDiv; NavRootNodeEditor presenter; @Override public void init(NavRootNodeEditor presenter) { this.presenter = presenter; itemViewDiv.setHidden(false); itemEditDiv.setHidden(true); itemMenuIcon.setTitle(i18n.itemMenuTitle()); itemEditIcon.setTitle(i18n.editItem()); itemDeleteIcon.setTitle(i18n.deleteItem()); } @Override public void clearChildren() { DOMUtil.removeAllChildren(childrenDiv); } @Override public void addChild(org.jboss.errai.common.client.api.IsElement editor) { childrenDiv.appendChild(editor.getElement()); } @Override public void setExpandEnabled(boolean enabled) { if (enabled) { itemIcon.getStyle().removeProperty("opacity"); itemIcon.getStyle().removeProperty("pointer-events"); itemIcon.getStyle().setProperty("cursor", "pointer"); itemName.getStyle().setProperty("cursor", "pointer"); } else { itemIcon.getStyle().setProperty("opacity", ".5"); itemIcon.getStyle().setProperty("pointer-events", "none"); itemIcon.getStyle().removeProperty("cursor"); itemName.getStyle().removeProperty("cursor"); } } @Override public void setExpanded(boolean expanded) { itemIcon.setClassName(expanded ? "fa fa-angle-down" : "fa fa-angle-right"); childrenDiv.setHidden(!expanded); } @Override public void setItemName(String name) { itemName.setTextContent(name); itemNameInput.setValue(name); } @Override public String getItemName() { return itemNameInput.getValue(); } @Override public void setItemNameError(boolean hasError) { String classes = "uf-navitem-name-input" + (hasError ? " uf-navitem-name-error" : " form-control"); itemNameInput.setClassName(classes); } @Override public void setItemDescription(String description) { itemName.setTitle(description); } @Override public void setItemType(NavItemEditor.ItemType type) { itemIcon.getStyle().removeProperty("cursor"); if (type == NavItemEditor.ItemType.GROUP) { itemIcon.setClassName("fa fa-angle-right"); itemIcon.setTitle(""); } else if (type == NavItemEditor.ItemType.DIVIDER) { itemIcon.setClassName("fa fa-minus"); itemIcon.setTitle(""); } else if (type == NavItemEditor.ItemType.PERSPECTIVE) { itemIcon.setClassName("pficon-screen"); itemIcon.setTitle(NavigationConstants.INSTANCE.perspectiveIconTitle()); } else if (type == NavItemEditor.ItemType.RUNTIME_PERSPECTIVE) { itemIcon.setClassName("pficon-virtual-machine"); itemIcon.setTitle(NavigationConstants.INSTANCE.pageIconTitle()); } } @Override public void addCommand(String name, Command command) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.setInnerText(name); LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); commandMenu.appendChild((Node) li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if(Event.ONCLICK == event.getTypeInt()) { command.execute(); } }); } @Override public void addCommandDivider() { LIElement li = Document.get().createLIElement(); li.setClassName("divider"); commandMenu.appendChild((Node) li); } @Override public void setCommandsEnabled(boolean enabled) { itemMenuIcon.setHidden(!enabled); commandMenu.setHidden(!enabled); } @Override public void clearCommands() { DOMUtil.removeAllChildren(commandMenu); } @Override public void startItemEdition() { itemViewDiv.setHidden(true); itemEditDiv.setHidden(false); itemNameInput.focus(); } @Override public void finishItemEdition() { itemViewDiv.setHidden(false); itemEditDiv.setHidden(true); } @Override public void setContextWidget(IsElement widget) { extraDiv.getStyle().setProperty("display", "block"); DOMUtil.removeAllChildren(extraDiv); extraDiv.appendChild(widget.getElement()); } @Override public void setItemEditable(boolean editable) { if (editable) { itemEditIcon.getStyle().removeProperty("display"); } else { itemEditIcon.getStyle().setProperty("display", "none"); } } @Override public void setItemDeletable(boolean deletable) { if (deletable) { itemDeleteIcon.getStyle().removeProperty("display"); } else { itemDeleteIcon.getStyle().setProperty("display", "none"); } } @EventHandler("itemIcon") public void onItemIconClick(ClickEvent event) { presenter.expandOrCollapse(); } @EventHandler("itemName") public void onItemNameClick(ClickEvent event) { presenter.expandOrCollapse(); } @EventHandler("itemEditIcon") public void onItemEditClick(ClickEvent event) { presenter.startEdition(); } @EventHandler("itemDeleteIcon") public void onItemDeleteClick(ClickEvent event) { presenter.deleteItemCommand(); } @EventHandler("itemConfirmIcon") public void onItemEditOkClick(ClickEvent event) { presenter.onChangesOk(); } @EventHandler("itemCancelIcon") public void onItemEditCancelClick(ClickEvent event) { presenter.cancelEdition(); } @EventHandler("itemNameInput") public void onItemNameInputOver(MouseOverEvent event) { itemNameInput.focus(); } @EventHandler("itemNameInput") public void onItemNameChanged(KeyPressEvent keyEvent) { if (keyEvent.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) { presenter.onChangesOk(); } else { presenter.onItemNameChanged(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavTreeEditor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import java.util.Optional; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.event.NavItemEditCancelledEvent; import org.dashbuilder.client.navigation.event.NavItemEditStartedEvent; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.mvp.Command; @Dependent public class NavTreeEditor extends NavItemEditor { public interface View extends NavItemEditor.View { void setChangedFlag(boolean on); } public static final NavigationConstants i18n = NavigationConstants.INSTANCE; public static final String ROOT_GROUP_ID = "NavTreeEditorRootGroupId"; NavTreeEditorView view; NavigationManager navigationManager; NavTree navTree; Command onSaveCommand; Optional currentlyEditedItem = Optional.empty(); LoadingBox loadingBox; @Inject public NavTreeEditor(NavTreeEditorView view, NavigationManager navigationManager, SyncBeanManager beanManager, PlaceManager placeManager, PerspectiveTreeProvider perspectiveTreeProvider, TargetPerspectiveEditor targetPerspectiveEditor, PerspectivePluginManager perspectivePluginManager, Event navItemEditStartedEvent, Event navItemEditCancelledEvent, LoadingBox loadingBox) { super(view, beanManager, placeManager, perspectiveTreeProvider, targetPerspectiveEditor, perspectivePluginManager, navItemEditStartedEvent, navItemEditCancelledEvent); this.view = view; this.navigationManager = navigationManager; this.loadingBox = loadingBox; this.view.init(this); super.setChildEditorClass(NavItemDefaultEditor.class); } public void setOnSaveCommand(Command onSaveCommand) { this.onSaveCommand = onSaveCommand; } @Override public String getGroupLiteral() { return "Tree"; } public NavTree getNavTree() { return navTree; } public void edit(NavTree navTree) { this.navTree = navTree.cloneTree(); this.currentlyEditedItem = Optional.empty(); view.setChangedFlag(false); NavGroup rootGroup = NavFactory.get().createNavGroup(navTree); rootGroup.setId(ROOT_GROUP_ID); // Only allow the creation of groups in the first tree level getSettings().setNewDividerEnabled(ROOT_GROUP_ID, false); getSettings().setNewPerspectiveEnabled(ROOT_GROUP_ID, false); super.edit(rootGroup); super.expand(); } @Override void onItemUpdated() { view.setChangedFlag(true); currentlyEditedItem = Optional.empty(); super.onItemUpdated(); } public void newTree() { saveDefaultNavTree(); newGroup(); } // View actions void saveDefaultNavTree() { final boolean hasNoSavedTree = !navigationManager.hasNavTree(); if (hasNoSavedTree) { showLoading(); navigationManager.saveNavTree(navigationManager.getNavTree(), this::hideLoading); } } void showLoading() { loadingBox.show(); } void hideLoading() { loadingBox.hide(); } void onSaveClicked() { NavGroup rootGroup = (NavGroup) super.getNavItem(); NavTree modifiedTree = NavFactory.get().createNavTree(rootGroup); navigationManager.saveNavTree(modifiedTree, () -> { navTree = modifiedTree; view.setChangedFlag(false); currentlyEditedItem = Optional.empty(); if (onSaveCommand != null) { onSaveCommand.execute(); } }); } void onCancelClicked() { edit(navTree); } // Keep track of the item under edition so as to avoid editing multiple items simultaneously void onItemEditStarted(@Observes NavItemEditStartedEvent event) { currentlyEditedItem.filter(e -> !e.equals(event.getNavItemEditor())).ifPresent(NavItemEditor::cancelEdition); currentlyEditedItem = Optional.of(event.getNavItemEditor()); } void onItemEditCancelled(@Observes NavItemEditCancelledEvent event) { currentlyEditedItem = Optional.empty(); } NavItemEditor getCurrentlyEditedItem() { return currentlyEditedItem.isPresent() ? currentlyEditedItem.get() : null; } // NavItemEditorSettings proxy methods public NavItemEditorSettings setMaxLevels(String navItemId, int maxLevels) { return getSettings().setMaxLevels(navItemId, maxLevels); } public NavItemEditorSettings.Flags setNewGroupEnabled(String navItemId, boolean enabled) { return getSettings().setNewGroupEnabled(navItemId, enabled); } public NavItemEditorSettings.Flags setNewPerspectiveEnabled(String navItemId, boolean enabled) { return getSettings().setNewPerspectiveEnabled(navItemId, enabled); } public NavItemEditorSettings.Flags setNewDividerEnabled(String navItemId, boolean enabled) { return getSettings().setNewDividerEnabled(navItemId, enabled); } public NavItemEditorSettings.Flags setOnlyRuntimePerspectives(String navItemId, boolean enabled) { return getSettings().setOnlyRuntimePerspectives(navItemId, enabled); } public NavItemEditorSettings.Flags setPerspectiveContextEnabled(String navItemId, boolean enabled) { return getSettings().setPerspectiveContextEnabled(navItemId, enabled); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavTreeEditorView.css ================================================ .uf-cms-nav-tree-panel { overflow: auto; height: 100%; } .uf-cms-nav-alert-panel { margin: 15px; } .uf-cms-nav-children-panel { margin: 10px 0px 5px 15px; font-size: larger; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavTreeEditorView.html ================================================
Save changes?
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/NavTreeEditorView.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.Button; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.mvp.Command; @Templated public class NavTreeEditorView extends NavItemEditorView implements NavTreeEditor.View { @Inject @DataField Div mainDiv; @Inject @DataField Div childrenDiv; @Inject @DataField Div alertDiv; @Inject @DataField Span alertMessage; @Inject @DataField Button saveButton; @Inject @DataField Button cancelButton; NavTreeEditor presenter; @Override public void init(NavTreeEditor presenter) { this.presenter = presenter; alertMessage.setTextContent(i18n.saveChanges()); saveButton.setTextContent(i18n.save()); cancelButton.setTextContent(i18n.cancel()); } @Override public void setExpandEnabled(boolean enabled) { } @Override public void setExpanded(boolean expanded) { childrenDiv.setHidden(!expanded); } @Override public void clearChildren() { DOMUtil.removeAllChildren(childrenDiv); setChangedFlag(false); } @Override public void addChild(IsElement editor) { childrenDiv.appendChild(editor.getElement()); } @Override public void setChangedFlag(boolean on) { if (on) { alertDiv.getStyle().removeProperty("display"); } else { alertDiv.getStyle().setProperty("display", "none"); } } @EventHandler("saveButton") public void onSaveClicked(ClickEvent event) { presenter.onSaveClicked(); } @EventHandler("cancelButton") public void onCancelClicked(ClickEvent event) { presenter.onCancelClicked(); } // N/A: The rest of the NavItemEditorView methods below does not apply since the NavTreeEditor // item is non editable and it only allows for the creation of subgroup items. @Override public void setItemName(String name) { } @Override public String getItemName() { return null; } @Override public void setItemNameError(boolean hasError) { } @Override public void setItemDescription(String description) { } @Override public void setItemType(NavItemEditor.ItemType type) { } @Override public void clearCommands() { } @Override public void addCommand(String name, Command command) { } @Override public void addCommandDivider() { } @Override public void setCommandsEnabled(boolean enabled) { } @Override public void setItemEditable(boolean editable) { } @Override public void setItemDeletable(boolean deletable) { } @Override public void startItemEdition() { } @Override public void finishItemEdition() { } @Override public void setContextWidget(IsElement widget) { } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/TargetPerspectiveEditor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import java.util.List; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.common.client.api.IsElement; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.UberElement; import org.uberfire.ext.widgets.common.client.dropdown.PerspectiveDropDown; import org.uberfire.ext.widgets.common.client.dropdown.PerspectiveNameProvider; import org.uberfire.mvp.Command; @Dependent public class TargetPerspectiveEditor implements IsElement, PerspectiveNameProvider { public interface View extends UberElement { void setPerspectiveSelector(IsWidget perspectiveDropDown); void clearNavGroupItems(); void setNavGroupEnabled(boolean enabled); void addNavGroupItem(String name, Command onSelect); void setNavGroupSelection(String name, Command onReset); } View view; String navGroupId; PerspectiveDropDown perspectiveDropDown; PerspectivePluginManager perspectivePluginManager; PerspectiveTreeProvider perspectiveTreeProvider; List navItemList; Command onUpdateCommand; @Inject public TargetPerspectiveEditor(View view, PerspectiveDropDown perspectiveDropDown, PerspectivePluginManager perspectivePluginManager, PerspectiveTreeProvider perspectiveTreeProvider) { this.view = view; this.perspectiveDropDown = perspectiveDropDown; this.perspectivePluginManager = perspectivePluginManager; this.perspectiveTreeProvider = perspectiveTreeProvider; this.perspectiveDropDown.setPerspectiveNameProvider(this); this.perspectiveDropDown.setMaxItems(50); this.perspectiveDropDown.setWidth(150); this.perspectiveDropDown.setOnChange(this::onPerspectiveChanged); this.view.init(this); } @Override public HTMLElement getElement() { return view.getElement(); } public void setNavItemList(List navItemList) { this.navItemList = navItemList; } public void setOnUpdateCommand(Command onUpdateCommand) { this.onUpdateCommand = onUpdateCommand; } public void setPerspectiveIdsExcluded(Set perspectiveIdsExcluded) { perspectiveDropDown.setPerspectiveIdsExcluded(perspectiveIdsExcluded); } public void setPerspectiveId(String perspectiveId) { perspectiveDropDown.setSelectedPerspective(perspectiveId); } public String getPerspectiveId() { return perspectiveDropDown.getSelectedPerspective().getIdentifier(); } @Override public String getPerspectiveName(String perspectiveId) { if (perspectivePluginManager.isRuntimePerspective(perspectiveId)) { return perspectiveId; } return perspectiveTreeProvider.getPerspectiveName(perspectiveId); } public void setNavGroupEnabled(boolean enabled) { view.setNavGroupEnabled(enabled); } public void setNavGroupId(String navGroupId) { this.navGroupId = navGroupId; } public String getNavGroupId() { return navGroupId; } public void show() { view.setPerspectiveSelector(perspectiveDropDown); updateNavGroups(); } public void clear() { navGroupId = null; perspectiveDropDown.clear(); view.clearNavGroupItems(); } private void updateNavGroups() { view.clearNavGroupItems(); if (navItemList != null) { updateNavGroups(navItemList); } } private void updateNavGroups(List navItemList) { navItemList.stream() .filter(navItem -> navItem instanceof NavGroup) .forEach(this::addNavGroup); } private void addNavGroup(NavItem navItem) { // Discard items with no name if (navItem.getName() != null) { // Check if the group is already selected String fullPath = calculateFullPath(navItem); if (navGroupId != null && navItem.getId().equals(navGroupId)) { view.setNavGroupSelection(fullPath, () -> onGroupSelected(null)); } else { view.addNavGroupItem(fullPath, () -> onGroupSelected(navItem.getId())); } } // Add the children items updateNavGroups(((NavGroup) navItem).getChildren()); } private String calculateFullPath(NavItem navItem) { StringBuilder out = new StringBuilder(); NavItem parent = navItem.getParent(); while (parent != null && parent.getName() != null) { out.insert(0, parent.getName() + ">"); parent = parent.getParent(); } out.append(navItem.getName()); return out.toString(); } // View callbacks public void onGroupSelected(String id) { navGroupId = id; updateNavGroups(); if (onUpdateCommand != null) { onUpdateCommand.execute(); } } public void onPerspectiveChanged() { if (onUpdateCommand != null) { onUpdateCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/TargetPerspectiveEditorView.css ================================================ .uf-tpe-selector-button { width: 150px; text-align: left; } .uf-tpe-selector-menu { margin-left: 37px; width: 150px; overflow: auto; max-height: 250px; } .uf-tpe-help-icon { position: absolute; margin-left: 155px; margin-top: -25px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/TargetPerspectiveEditorView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/java/org/dashbuilder/client/navigation/widget/editor/TargetPerspectiveEditorView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.LIElement; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Node; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.mvp.Command; @Templated public class TargetPerspectiveEditorView implements TargetPerspectiveEditor.View, IsElement { @Inject @DataField Div perspectiveSelectorDiv; @Inject @DataField Div groupSelectorDiv; @Inject @DataField Span navGroupSelection; @Inject @DataField UnorderedList navGroupItems; @Inject @DataField Span perspectiveSelectorHelp; @Inject @DataField Span navGroupSelectorHelp; TargetPerspectiveEditor presenter; @Override public void init(TargetPerspectiveEditor presenter) { this.presenter = presenter; this.perspectiveSelectorHelp.setTitle(NavigationConstants.INSTANCE.navItemEditorPerspectiveHelp()); this.navGroupSelectorHelp.setTitle(NavigationConstants.INSTANCE.navItemEditorGroupHelp()); } @Override public void setPerspectiveSelector(IsWidget perspectiveDropDown) { perspectiveDropDown.asWidget().getElement().getStyle().setWidth(150, Style.Unit.PX); DOMUtil.removeAllChildren(perspectiveSelectorDiv); DOMUtil.appendWidgetToElement(perspectiveSelectorDiv, perspectiveDropDown); } @Override public void clearNavGroupItems() { DOMUtil.removeAllChildren(navGroupItems); navGroupSelection.setTextContent(NavigationConstants.INSTANCE.navGroupSelectorHint()); } @Override public void setNavGroupEnabled(boolean enabled) { if (enabled) { groupSelectorDiv.getStyle().removeProperty("display"); navGroupSelectorHelp.getStyle().removeProperty("display"); } else { groupSelectorDiv.getStyle().setProperty("display", "none"); navGroupSelectorHelp.getStyle().setProperty("display", "none"); } } @Override public void addNavGroupItem(String name, Command onSelect) { addItem(navGroupItems, name, false, onSelect); } @Override public void setNavGroupSelection(String name, Command onReset) { navGroupSelection.setTextContent(name); navGroupSelection.setTitle(name); addItem(navGroupItems, name, true, onReset); } private void addItem(UnorderedList unorderedList, String name, boolean selected, Command onSelect) { AnchorElement anchor = Document.get().createAnchorElement(); anchor.setInnerText(name); LIElement li = Document.get().createLIElement(); li.getStyle().setCursor(Style.Cursor.POINTER); li.appendChild(anchor); li.setClassName(selected ? "selected" : ""); unorderedList.appendChild((Node) li); Event.sinkEvents(anchor, Event.ONCLICK); Event.setEventListener(anchor, event -> { if(Event.ONCLICK == event.getTypeInt()) { onSelect.execute(); } }); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/NavigationClient.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # newItem=+ New {0} gotoItem=Goto {0} itemMenuTitle=Show menu newItemName=- New {0} - editItem=Edit deleteItem=Delete pageIconTitle=A user created page perspectiveIconTitle=A hard-coded static perspective moveUp=Move up moveDown=Move down moveFirst=Move first moveLast=Move last saveChanges=Save changes? save=Save cancel=Cancel navGroupNotFound=The navigation group configured might have been deleted or does not exit. Please, check the configuration of this component. navItemsEmpty=No items found navMenubarDragComponent=Menu Bar navTabListDragComponent=Tab List navTreeDragComponent=Tree navTilesDragComponent=Tile Navigator navCarouselDragComponent=Carousel navMenubarDragComponentNavGroupHelp=The menu bar will display items from the navigation group you select. navTabListDragComponentNavGroupHelp=The navigation group you select is used to retrieve a list of pages, which are displayed in the form of tabs - one page per tab. navTreeDragComponentNavGroupHelp=The tree component will display iems from the navigation group you select. navTilesDragComponentNavGroupHelp=The tile navigator will display items from the navigation group you select. Groups are displayed as folders whereas single items show its content once clicked. navCarouselDragComponentNavGroupHelp=The navigation group you select is used to retrieve a list of pages, which are displayed as an slideshow carousel - one page per slide. navGroupEmptyError=Please, make sure the group configured is not empty. navCarouselDragComponentEmptyError=Please, make sure the group configured contains at least one user created page. navTilesDragComponentInfiniteRecursion=The content is not displayed to avoid an infinite loop. In general the pages in the navigation group you selected for this component must not contain navigation components which refer (directly nor indirectly) to the pages in that same group. Please double check the configuration of both the navigation tree and the navigation components. Reason: navCarouselDragComponentInfiniteRecursion=This carousel slide is not displayed to avoid an infinite loop. In general the pages in the navigation group you selected for this component must not contain navigation components which refer (directly nor indirectly) to the pages in that same group. Please double check the configuration of both the navigation tree and the navigation components. Reason: targetDivIdPerspectiveInfiniteRecursion=The content is not displayed to avoid an infinite loop. In general a page must not contain references (directly nor indirectly) to itself. Please double check the configuration of both the navigation tree and the navigation components. Reason: navWidgetTargetDivMissing=The target div is either not found or not defined. Please, review the component''s configuration. openNavItem=Open {0} gotoNavItem=Go to {0} showNavItem=Show {0} navConfigHeader=Navigation component configuration navGroupLabel=Navigation group navGroupHelp=The navigation component will display items from the selected group. navGroupSelectorHint=-Select group - defaultItemLabel=Default item defaultItemHelp=The item (e.g. a page) the navigation component displays by default. If nothing selected then the first item is taken. defaultItemSelectorHint=-Select default item - defaultItemsNotFound=The selected group has no items targetDivLabel=Target div targetDivHelp=Every time a navigation item is clicked, the content of its associated page is displayed in the target div component you select. targetDivSelectorHint=-Select target div - targetDivsNotFound=No target divs defined navItemEditorPerspectiveHelp=The page to display when this navigation item is clicked from any navigation component: menu bar, tile navigator, tab list, tree, ... navItemEditorGroupHelp=The navigation group to be used by the target page''s navigation components. This setting only makes sense when the page selected above contains navigation components. navRefPerspective=The page {0} navRefPerspectiveDefault=The item points to the page {0}. navRefPerspectiveFound=The item points to the page {0}. navRefPerspectiveInGroup=The group contains at least one item linked to the page {0}. navRefComponent=contains a {0} navRefGroupDefined=displaying items from group {0}. navRefGroupContext=receiving the {0} navigation group. navRefDefaultItemDefined=The default item defined is {0}. navRefDefaultItemFound=The first available item found is {0}. navRefPerspectiveRecursionEnd=which would cause an infinite loop ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants_de.properties ================================================ # translation auto-copied from project jBPM Form Modeler, version 6.0.0, document org.jbpm/jbpm-form-modeler-form-editor/org/jbpm/formModeler/components/editor/messages moveUp=Nach oben # translation auto-copied from project jBPM Form Modeler, version 6.0.0, document org.jbpm/jbpm-form-modeler-form-editor/org/jbpm/formModeler/components/editor/messages moveDown=Nach unten save=Speichern cancel=Abbrechen ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants_es.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # newItem=+ Nuevo {0} gotoItem=Ir a {0} itemMenuTitle=Mostrar menú newItemName=- Nuevo {0} - editItem=Editar deleteItem=Eliminar pageIconTitle=Una página creada por el usuario perspectiveIconTitle=Una perspectiva estática preprogramada moveUp=Mover hacia arriba moveDown=Mover hacia abajo moveFirst=Mover al principio moveLast=Mover al final saveChanges=¿Guardar los cambios? save=Guardar cancel=Cancelar navGroupNotFound=Es posible que el grupo de navegación configurado se haya eliminado o no exista. Compruebe la configuración de este componente. navItemsEmpty=No se encuentran ítems navMenubarDragComponent=Barra de menú navTabListDragComponent=Lista de pestañas navTreeDragComponent=Árbol navTilesDragComponent=Navegador de fichas navCarouselDragComponent=Carrusel navMenubarDragComponentNavGroupHelp=La barra de menú mostrará los ítems del grupo de navegación que seleccione. navTabListDragComponentNavGroupHelp=El grupo de navegación que seleccione se usa para recuperar una lista de páginas, que se muestran en pestañas; una página por pestaña. navTreeDragComponentNavGroupHelp=El componente de árbol mostrará artículos del grupo de navegación que seleccione. navTilesDragComponentNavGroupHelp=El navegador de fichas mostrará ítems del grupo de navegación que seleccione. Los grupos se muestran como carpetas, mientras que los ítems individuales muestran su contenido una vez que se hace clic en ellos. navCarouselDragComponentNavGroupHelp=El grupo de navegación que seleccione se usa para recuperar una lista de páginas, que se muestran como un carrusel de diapositivas; una página por diapositiva. navGroupEmptyError=Asegúrese de que el grupo configurado no esté vacío. navCarouselDragComponentEmptyError=Asegúrese de que el grupo configurado contenga al menos una página creada por el usuario. navTilesDragComponentInfiniteRecursion=El contenido no se muestra para evitar un bucle infinito. Por lo general, las páginas del grupo de navegación que ha seleccionado para este componente no deben contener componentes de navegación que se refieran (directa o indirectamente) a las páginas de ese mismo grupo. Compruebe la configuración del árbol de navegación y de los componentes de navegación. Motivo: navCarouselDragComponentInfiniteRecursion=Esta diapositiva de carrusel no se muestra para evitar un bucle infinito. Por lo general, las páginas del grupo de navegación que ha seleccionado para este componente no deben contener componentes de navegación que se refieran (directa o indirectamente) a las páginas de ese mismo grupo. Compruebe la configuración del árbol de navegación y de los componentes de navegación. Motivo: targetDivIdPerspectiveInfiniteRecursion=El contenido no se muestra para evitar un bucle infinito. En general, una página no debe contener referencias (directas o indirectas) a sí misma. Compruebe la configuración del árbol de navegación y de los componentes de navegación. Motivo: navWidgetTargetDivMissing=El div objetivo no se encuentra o no está definido. Revise la configuración del componente. openNavItem=Abrir {0} gotoNavItem=Ir a {0} showNavItem=Mostrar {0} navConfigHeader=Configuración del componente de navegación navGroupLabel=Grupo de navegación navGroupHelp=El componente de navegación mostrará los ítems del grupo seleccionado. navGroupSelectorHint=-Seleccionar grupo - defaultItemLabel=Ítem predeterminado defaultItemHelp=El ítem (p. ej., una página) que el componente de navegación muestra de forma predeterminada. Si no se selecciona nada, se usa el primer ítem. defaultItemSelectorHint=-Seleccionar el ítem predeterminado - defaultItemsNotFound=El grupo seleccionado no tiene ítems targetDivLabel=Div objetivo targetDivHelp=Cada vez que se hace clic en un ítem de navegación, el contenido de su página asociada se muestra en el componente div objetivo que seleccione. targetDivSelectorHint=-Seleccionar el div objetivo - targetDivsNotFound=No hay divs objetivo definidos navItemEditorPerspectiveHelp=La página que se muestra cuando se hace clic en este ítem de navegación desde cualquier componente de navegación: barra de menú, navegador de fichas, lista de pestañas, árbol… navItemEditorGroupHelp=El grupo de navegación que será usado por los componentes de navegación de la página de destino. Este ajuste solo tiene sentido cuando la página seleccionada anteriormente contiene componentes de navegación. navRefPerspective=La página {0} navRefPerspectiveDefault=El ítem apunta a la página {0}. navRefPerspectiveFound=El ítem apunta a la página {0}. navRefPerspectiveInGroup=El grupo contiene al menos un ítem vinculado a la página {0}. navRefComponent=contiene un {0} navRefGroupDefined=mostrando ítems del grupo {0}. navRefGroupContext=recibiendo el grupo de navegación {0}. navRefDefaultItemDefined=El ítem definido de forma predeterminada es {0}. navRefDefaultItemFound=El primer ítem disponible encontrado es {0}. navRefPerspectiveRecursionEnd=que causaría un bucle infinito ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants_fr.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # newItem=+ Nouveau {0} gotoItem=Aller à {0} itemMenuTitle=Afficher le menu newItemName=- Nouveau {0} - editItem=Modifier deleteItem=Supprimer pageIconTitle=Page créée par l''utilisateur perspectiveIconTitle=Perspective statique codée en dur moveUp=Déplacer vers le haut moveDown=Déplacer vers le bas moveFirst=Placer en premier moveLast=Placer en dernier saveChanges=Enregistrer les modifications ? save=Enregistrer cancel=Annuler navGroupNotFound=Il se peut que le groupe de navigation configuré ait été supprimé ou ne se ferme pas. Veuillez vérifier la configuration de ce composant. navItemsEmpty=Aucun élément trouvé navMenubarDragComponent=Barre de menus navTabListDragComponent=Liste des onglets navTreeDragComponent=Arborescence navTilesDragComponent=Navigateur de vignettes navCarouselDragComponent=Carrousel navMenubarDragComponentNavGroupHelp=La barre de menus affichera les éléments du groupe de navigation que vous avez sélectionnés. navTabListDragComponentNavGroupHelp=Le groupe de navigation sélectionné permet de récupérer une liste de pages, qui s''affichent sous la forme d''onglets ; une page par onglet. navTreeDragComponentNavGroupHelp=Le composant d''arborescence affichera les éléments du groupe de navigation que vous avez sélectionné. navTilesDragComponentNavGroupHelp=Le navigateur de vignettes affichera les éléments du groupe de navigation que vous avez sélectionné. Les groupes sont affichés sous la forme de dossiers, tandis que le contenu des éléments individuels s''affiche lorsque vous cliquez dessus. navCarouselDragComponentNavGroupHelp=Le groupe de navigation sélectionné permet de récupérer une liste de pages, qui s''affichent sous la forme d''un diaporama ; une page par diapositive. navGroupEmptyError=Assurez-vous que le groupe configuré n''est pas vide. navCarouselDragComponentEmptyError=Assurez-vous que le groupe configuré contient au moins une page créée par l''utilisateur. navTilesDragComponentInfiniteRecursion=Le contenu n''est pas affiché pour éviter une boucle infinie. En règle générale, les pages du groupe de navigation que vous avez sélectionnées pour ce composant ne doivent pas contenir de composants de navigation faisant référence (directement ou indirectement) aux pages de ce même groupe. Vérifiez à nouveau la configuration de l''arborescence de navigation et des composants de navigation. Raison : navCarouselDragComponentInfiniteRecursion=Cette diapositive du carrousel n''est pas affichée pour éviter une boucle infinie. En règle générale, les pages du groupe de navigation que vous avez sélectionnées pour ce composant ne doivent pas contenir de composants de navigation faisant référence (directement ou indirectement) aux pages de ce même groupe. Vérifiez à nouveau la configuration de l''arborescence de navigation et des composants de navigation. Raison : targetDivIdPerspectiveInfiniteRecursion=Le contenu n''est pas affiché pour éviter une boucle infinie. En règle générale, une page ne doit pas contenir de références (directes ou indirectes) à elle-même. Vérifiez à nouveau la configuration de l''arborescence de navigation et des composants de navigation. Raison : navWidgetTargetDivMissing=Le composant div cible est introuvable ou n''est pas défini. Vérifiez la configuration du composant. openNavItem=Ouvrir {0} gotoNavItem=Aller à {0} showNavItem=Afficher {0} navConfigHeader=Configuration des composants de navigation navGroupLabel=Groupe de navigation navGroupHelp=Le composant de navigation affichera des éléments du groupe sélectionné. navGroupSelectorHint=- Sélectionner un groupe - defaultItemLabel=Élément par défaut defaultItemHelp=Élément (une page, par exemple) que le composant de navigation affiche par défaut. Si rien n''est sélectionné, le premier élément est choisi. defaultItemSelectorHint=- Sélectionner l''élément par défaut - defaultItemsNotFound=Le groupe sélectionné ne comporte aucun élément targetDivLabel=Div cible targetDivHelp=Chaque fois que vous cliquez sur un élément de navigation, le contenu de la page qui lui est associée s''affiche dans le composant div cible sélectionné. targetDivSelectorHint=- Sélectionner le composant div cible - targetDivsNotFound=Aucun composant div cible défini navItemEditorPerspectiveHelp=Page à afficher lorsque l''utilisateur clique sur cet élément de navigation à partir de n''importe quel composant de navigation : barre de menus, navigateur de vignettes, liste d''onglets, arborescence, ... navItemEditorGroupHelp=Groupe de navigation qui doit être utilisé par les composants de navigation de la page cible. Ce paramètre n''a de sens que si la page sélectionnée ci-dessus contient des composants de navigation. navRefPerspective=La page {0} navRefPerspectiveDefault=L''élément pointe vers la page {0}. navRefPerspectiveFound=L''élément pointe vers la page {0}. navRefPerspectiveInGroup=Le groupe contient au moins un élément lié à la page {0}. navRefComponent=contient un {0} navRefGroupDefined=affiche des éléments du groupe {0}. navRefGroupContext=reçoit le groupe de navigation {0}. navRefDefaultItemDefined=L''élément défini par défaut est {0}. navRefDefaultItemFound=Le premier élément disponible trouvé est {0}. navRefPerspectiveRecursionEnd=ce qui provoquerait une boucle infinie ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants_it.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # newItem=+ Nuovo {0} gotoItem=Vai a {0} itemMenuTitle=Mostra menu newItemName=- Nuovo {0} - editItem=Modifica deleteItem=Elimina pageIconTitle=Una pagina creata dall''utente perspectiveIconTitle=Una prospettiva statica codificata moveUp=Sposta su moveDown=Sposta giù moveFirst=Sposta in prima posizione moveLast=Sposta in ultima posizione saveChanges=Salvare le modifiche? save=Salva cancel=Annulla navGroupNotFound=Il gruppo di navigazione configurato potrebbe essere stato eliminato o non esiste. Si prega di controllare la configurazione di questo componente. navItemsEmpty=Nessun elemento trovato navMenubarDragComponent=Barra dei menu navTabListDragComponent=Elenco schede navTreeDragComponent=Albero navTilesDragComponent=Navigatore a riquadri navCarouselDragComponent=Carosello navMenubarDragComponentNavGroupHelp=La barra dei menu mostrerà gli elementi del gruppo di navigazione che selezioni. navTabListDragComponentNavGroupHelp=Il gruppo di navigazione che selezioni viene utilizzato per recuperare un elenco di pagine, che vengono visualizzate sotto forma di schede - una pagina per scheda. navTreeDragComponentNavGroupHelp=Il componente albero mostrerà gli elementi del gruppo di navigazione che selezioni. navTilesDragComponentNavGroupHelp=Il navigatore a riquadri mostrerà gli elementi del gruppo di navigazione che selezioni. I gruppi vengono visualizzati come cartelle, mentre gli elementi singoli mostrano il loro contenuto una volta cliccati. navCarouselDragComponentNavGroupHelp=Il gruppo di navigazione che selezioni viene utilizzato per recuperare un elenco di pagine, che vengono visualizzate come un carosello - una pagina per slide. navGroupEmptyError,Assicurati che il gruppo configurato non sia vuoto. navCarouselDragComponentEmptyError,Assicurati che il gruppo configurato contenga almeno una pagina creata dall''utente. navTilesDragComponentInfiniteRecursion,Il contenuto non viene visualizzato per evitare un ciclo infinito. In generale, le pagine nel gruppo di navigazione selezionato per questo componente non devono contenere componenti di navigazione che si riferiscono (direttamente o indirettamente) alle pagine nello stesso gruppo. Si prega di controllare la configurazione sia dell''albero di navigazione che dei componenti di navigazione. Motivo: navCarouselDragComponentInfiniteRecursion,Questa slide del carosello non viene visualizzata per evitare un ciclo infinito. In generale, le pagine nel gruppo di navigazione selezionato per questo componente non devono contenere componenti di navigazione che si riferiscono (direttamente o indirettamente) alle pagine nello stesso gruppo. Si prega di controllare la configurazione sia dell''albero di navigazione che dei componenti di navigazione. Motivo: targetDivIdPerspectiveInfiniteRecursion,Il contenuto non viene visualizzato per evitare un ciclo infinito. In generale, una pagina non deve contenere riferimenti (diretti o indiretti) a se stessa. Si prega di controllare la configurazione sia dell''albero di navigazione che dei componenti di navigazione. Motivo: navWidgetTargetDivMissing,Il div di destinazione non viene trovato o non è definito. Si prega di rivedere la configurazione del componente. openNavItem=Apri {0} gotoNavItem=Vai a {0} showNavItem=Mostra {0} navConfigHeader=Configurazione del componente di navigazione navGroupLabel=Gruppo di navigazione navGroupHelp=Il componente di navigazione mostrerà gli elementi del gruppo selezionato. navGroupSelectorHint=- Seleziona gruppo - defaultItemLabel=Elemento predefinito defaultItemHelp=L''elemento (ad esempio una pagina) che il componente di navigazione mostra per impostazione predefinita. Se non viene selezionato nulla, viene preso il primo elemento. defaultItemSelectorHint=- Seleziona elemento predefinito - defaultItemsNotFound=Il gruppo selezionato non ha elementi targetDivLabel=Div di destinazione targetDivHelp=Ogni volta che viene cliccato un elemento di navigazione, il contenuto della pagina associata viene visualizzato nel componente div di destinazione che selezioni. targetDivSelectorHint=- Seleziona div di destinazione - targetDivsNotFound=Nessun div di destinazione definito navItemEditorPerspectiveHelp=La pagina da visualizzare quando viene cliccato questo elemento di navigazione da qualsiasi componente di navigazione: barra dei menu, navigatore a riquadri, elenco schede, albero, ... navItemEditorGroupHelp=Il gruppo di navigazione da utilizzare dai componenti di navigazione della pagina di destinazione. Questa impostazione ha senso solo quando la pagina selezionata sopra contiene componenti di navigazione. navRefPerspective=La pagina {0} navRefPerspectiveDefault=L''elemento punta alla pagina {0}. navRefPerspectiveFound=L''elemento punta alla pagina {0}. navRefPerspectiveInGroup=Il gruppo contiene almeno un elemento collegato alla pagina {0}. navRefComponent=contiene un {0} navRefGroupDefined=mostrando elementi dal gruppo {0}. navRefGroupContext=ricevendo il gruppo di navigazione {0}. navRefDefaultItemDefined=L''elemento predefinito definito è {0}. navRefDefaultItemFound=Il primo elemento disponibile trovato è {0}. navRefPerspectiveRecursionEnd=che causerebbe un ciclo infinito ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants_ja.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # newItem=+ 新規 {0} gotoItem={0} へ移動 itemMenuTitle=メニューを表示 newItemName=- 新規 {0} - editItem=編集 deleteItem=削除 pageIconTitle=ユーザーが作成したページ perspectiveIconTitle=ハードコードの静的パースペクティブ moveUp=上に移動 moveDown=下に移動 moveFirst=最初に移動 moveLast=最後に移動 saveChanges=変更を保存しますか? save=保存 cancel=キャンセル navGroupNotFound=設定されたナビゲーショングループが削除された可能性があるか、終了されません。このコンポーネントの設定を確認してください。 navItemsEmpty=アイテムが見つかりません navMenubarDragComponent=メニューバー navTabListDragComponent=タブリスト navTreeDragComponent=ツリー navTilesDragComponent=タイルナビゲーター navCarouselDragComponent=カルーセル navMenubarDragComponentNavGroupHelp=メニューバーは、選択したナビゲーショングループのアイテムを表示します。 navTabListDragComponentNavGroupHelp=選択したナビゲーショングループは、ページ一覧の検索に使用され、タブ形式で表示されます (タブごとに 1 ページ)。 navTreeDragComponentNavGroupHelp=ツリーコンポーネントは、選択したナビゲーショングループのアイテムを表示します。 navTilesDragComponentNavGroupHelp=タイルナビゲーションは、選択したナビゲーショングループのアイテムを表示します。グループはフォルダーとして表示されますが、単一のアイテムを 1 回クリックするとそのコンテンツが表示されます。 navCarouselDragComponentNavGroupHelp=選択したナビゲーショングループはページの一覧の検索に使用され、スライドショーカルーセルとして表示されます (スライドごとに 1 ページ)。 navGroupEmptyError=設定したグループが空でないことを確認してください。 navCarouselDragComponentEmptyError=設定したグループに、ユーザーが作成したページが 1 つ以上含まれていることを確認します。 navTilesDragComponentInfiniteRecursion=無限ループを避けるためこのコンテンツは表示されません。通常は、このコンポーネントに選択したナビゲーショングループのページには、同じグループ内のページを (直接/間接的に) 参照するナビゲーションコンポーネントを含めないでください。ナビゲーションツリーとナビゲーションコンポーネントの両方の設定を再確認してください。理由: navCarouselDragComponentInfiniteRecursion=無限ループを避けるためこのカルーセルスライドは表示されません。通常は、このコンポーネントに選択したナビゲーショングループのページには、同じグループ内のページを (直接/間接的に) 参照するナビゲーションコンポーネントを含めないでください。ナビゲーションツリーとナビゲーションコンポーネントの両方の設定を再確認してください。理由: targetDivIdPerspectiveInfiniteRecursion=無限ループを避けるためこのコンテンツは表示されません。通常、ページには、そのページ自体への参照を (直接/間接的に) 含めることはできません。ナビゲーションツリーとナビゲーションコンポーネントの両方の設定を再確認してください。理由: navWidgetTargetDivMissing=ターゲットdivが見つからないか、定義されていません。コンポーネントの設定を確認してください。 openNavItem=開く {0} gotoNavItem= {0} へ移動 showNavItem={0} を表示 navConfigHeader=ナビゲーションコンポーネントの設定 navGroupLabel=ナビゲーショングループ navGroupHelp=ナビゲーションコンポーネントは、選択したグループのアイテムを表示します。 navGroupSelectorHint=- グループの選択 - defaultItemLabel=デフォルトのアイテム defaultItemHelp=ナビゲーションコンポーネントがデフォルトで表示するアイテム (例: ページ)。何も選択されていない場合には、最初のアイテムが取得されます。 defaultItemSelectorHint=- デフォルトのアイテムを選択 - defaultItemsNotFound=選択したグループにはアイテムがありません targetDivLabel=ターゲット div targetDivHelp=ナビゲーションアイテムがクリックされると、関連付けられたページのコンテンツが、選択したターゲット div コンポーネントに表示されます。 targetDivSelectorHint=ターゲット div を選択 targetDivsNotFound=ターゲット div が定義されていません navItemEditorPerspectiveHelp=ナビゲーションコンポーネントからこのナビゲーションアイテムをクリックすると表示するページ: メニューバー、タイルナビゲーター、タブリスト、ツリーなど navItemEditorGroupHelp=ターゲットページのナビゲーションコンポーネントで使用されるナビゲーショングループ。この設定は、上記で選択したページにナビゲーションコンポーネントが含まれている場合にのみ意味があります。 navRefPerspective=ページ {0} navRefPerspectiveDefault=このアイテムはページ {0} を指しています。 navRefPerspectiveFound=このアイテムはページ {0} を指しています。 navRefPerspectiveInGroup=グループには、ページ {0} にリンクしているアイテムが 1 つ以上含まれます。 navRefComponent={0} を含む navRefGroupDefined=グループ {0} のアイテムの表示 navRefGroupContext={0} ナビゲーショングループの受信 navRefDefaultItemDefined=定義したデフォルトアイテムは {0} です。 navRefDefaultItemFound=見つかったアイテムで最初に利用可能なものは {0} です。 navRefPerspectiveRecursionEnd=無限ループを発生させるもの ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants_pt_BR.properties ================================================ # translation auto-copied from project jBPM Form Modeler, version 6.0.0, document org.jbpm/jbpm-form-modeler-form-editor/org/jbpm/formModeler/components/editor/messages moveUp=Mover para cima # translation auto-copied from project jBPM Form Modeler, version 6.0.0, document org.jbpm/jbpm-form-modeler-form-editor/org/jbpm/formModeler/components/editor/messages moveDown=Mover para baixo save=Salvar cancel=Cancelar ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/main/resources/org/dashbuilder/client/navigation/resources/i18n/NavigationConstants_zh_CN.properties ================================================ # translation auto-copied from project jBPM Form Modeler, version 6.0.0, document org.jbpm/jbpm-form-modeler-form-editor/org/jbpm/formModeler/components/editor/messages moveUp=上移 # translation auto-copied from project jBPM Form Modeler, version 6.0.0, document org.jbpm/jbpm-form-modeler-form-editor/org/jbpm/formModeler/components/editor/messages moveDown=下移 save=保存 cancel=取消 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/NavComponentConfigModalTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation; import java.util.Arrays; import java.util.List; import org.dashbuilder.client.navigation.widget.NavComponentConfigModal; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class NavComponentConfigModalTest { @Mock NavComponentConfigModal.View view; @Mock Command onOk; NavTree tree; NavComponentConfigModal presenter; @Before public void setUp() throws Exception { tree = new NavTreeBuilder() .item("H1", "H1", null, false) .divider() .group("A", "A", null, false) .item("A1", "A1", null, false) .item("A2", "A2", null, false) .group("B", "B", null, false) .group("C", "C", null, false) .build(); presenter = new NavComponentConfigModal(view); presenter.setOnOk(onOk); } @Test public void testInitDefault() { presenter.setNavGroup(tree.getRootItems(), null); presenter.show(); verify(view).init(presenter); verify(view).clearNavGroupItems(); verify(view).setNavGroupSelection(eq("A"), any()); verify(view).addNavGroupItem(eq("A>B"), any()); verify(view).addNavGroupItem(eq("A>B>C"), any()); verify(view).show(); } @Test public void testInitSelected() { presenter.setNavGroup(tree.getRootItems(), "B"); presenter.show(); verify(view).init(presenter); verify(view).clearNavGroupItems(); verify(view).setNavGroupSelection(eq("A>B"), any()); verify(view).addNavGroupItem(eq("A"), any()); verify(view).addNavGroupItem(eq("A>B>C"), any()); verify(view).show(); } @Test public void testSelectItem() { presenter.setNavGroup(tree.getRootItems(), "A"); presenter.show(); reset(view); presenter.onGroupSelected("B"); assertEquals(presenter.getGroupId(), "B"); verify(view).clearNavGroupItems(); verify(view).setNavGroupSelection(eq("A>B"), any()); verify(view).addNavGroupItem(eq("A"), any()); verify(view).addNavGroupItem(eq("A>B>C"), any()); } @Test public void testDefaultItemsPerGroup() { presenter.setNavGroup(tree.getRootItems(), "A"); presenter.show(); verify(view).setDefaultNavItemEnabled(true); verify(view).clearDefaultItems(); verify(view).addDefaultItem(eq("A>A1"), any()); verify(view).addDefaultItem(eq("A>A2"), any()); verify(view, never()).addDefaultItem(eq("A>B"), any()); verify(view, never()).addDefaultItem(eq("C"), any()); reset(view); presenter.onGroupSelected("C"); verify(view).setDefaultNavItemEnabled(true); verify(view).clearDefaultItems(); verify(view, never()).addDefaultItem(anyString(), any()); } @Test public void testTargetDivList() { List targetDivIdList = Arrays.asList("div1", "div2"); presenter.setTargetDivIdList(targetDivIdList); presenter.show(); verify(view).clearTargetDivItems(); verify(view).setTargetDivSelection(eq("div1"), any()); verify(view).addTargetDivItem(eq("div2"), any()); assertEquals(presenter.getTargetDivId(), "div1"); reset(view); presenter.setTargetDiv("t"); presenter.show(); verify(view).clearTargetDivItems(); verify(view).setTargetDivSelection(eq("div1"), any()); verify(view).addTargetDivItem(eq("div2"), any()); assertEquals(presenter.getTargetDivId(), "div1"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/plugin/PerspectivePluginManagerImplTest.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.plugin; import static org.assertj.core.api.Assertions.assertThat; import static org.dashbuilder.navigation.workbench.NavWorkbenchCtx.perspective; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Collections; import java.util.List; import javax.enterprise.event.Event; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.navigation.event.PerspectivePluginsChangedEvent; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.service.PerspectivePluginServices; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.workbench.type.ClientTypeRegistry; import org.uberfire.ext.plugin.client.type.PerspectiveLayoutPluginResourceType; import org.uberfire.ext.plugin.event.PluginAdded; import org.uberfire.ext.plugin.event.PluginDeleted; import org.uberfire.ext.plugin.event.PluginRenamed; import org.uberfire.ext.plugin.event.PluginSaved; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.ext.plugin.model.PluginType; import org.uberfire.mocks.CallerMock; import org.uberfire.mvp.Command; import org.uberfire.workbench.category.Others; @RunWith(MockitoJUnitRunner.class) public class PerspectivePluginManagerImplTest { private static final String PERSPECTIVE_ID = "Persp1"; private static final NavTree TEST_NAV_TREE = new NavTreeBuilder() .item(PERSPECTIVE_ID, "name1", "description1", true, perspective(PERSPECTIVE_ID)) .build(); @Mock private NavigationManager navigationManager; @Mock private ClientTypeRegistry clientTypeRegistry; @Mock private PerspectivePluginServices pluginServices; @Mock private Event perspectiveChangedEvent; private PluginAdded pluginAddedEvent; private PluginSaved pluginSavedEvent; private PluginRenamed pluginRenamedEvent; private PluginDeleted pluginDeletedEvent; private Plugin perspectivePlugin; private Plugin perspectiveRenamedPlugin; private PerspectivePluginManagerImpl testedPluginManager; @Before public void setUp() { when(clientTypeRegistry.resolve(any())).thenReturn(new PerspectiveLayoutPluginResourceType(new Others())); perspectivePlugin = new Plugin(PERSPECTIVE_ID, PluginType.PERSPECTIVE_LAYOUT, null); perspectiveRenamedPlugin = new Plugin("newName", PluginType.PERSPECTIVE_LAYOUT, null); pluginAddedEvent = new PluginAdded(perspectivePlugin, null); pluginSavedEvent = new PluginSaved(perspectivePlugin, null); pluginRenamedEvent = new PluginRenamed(PERSPECTIVE_ID, perspectiveRenamedPlugin, null); pluginDeletedEvent = new PluginDeleted(perspectivePlugin, null); when(pluginServices.listPlugins()).thenReturn(Collections.emptyList()); testedPluginManager = new PerspectivePluginManagerImpl(clientTypeRegistry, null, navigationManager, new CallerMock<>(pluginServices), perspectiveChangedEvent); testedPluginManager.getPerspectivePlugins(plugins -> {}); } @Test public void testPluginAdded() { testedPluginManager.getPerspectivePlugins(plugins -> assertThat(plugins).isEmpty()); testedPluginManager.onPlugInAdded(pluginAddedEvent); verify(perspectiveChangedEvent).fire(anyObject()); testedPluginManager.getPerspectivePlugins(plugins -> assertThat(plugins).hasSize(1)); } @Test public void testPluginSaved() { assertThat(testedPluginManager.existsPerspectivePlugin(PERSPECTIVE_ID)).isFalse(); testedPluginManager.onPlugInSaved(pluginSavedEvent); verify(perspectiveChangedEvent, times(1)).fire(anyObject()); assertThat(testedPluginManager.existsPerspectivePlugin(PERSPECTIVE_ID)).isTrue(); } @Test public void testPluginRenamed() { NavTree tree = TEST_NAV_TREE.cloneTree(); List items = tree.searchItems(NavWorkbenchCtx.perspective(PERSPECTIVE_ID)); assertThat((items).get(0).getName()).isEqualTo("name1"); assertThat((items).get(0).getContext()).contains("resourceId=" + PERSPECTIVE_ID); when(navigationManager.getNavTree()).thenReturn(tree); testedPluginManager.onPlugInRenamed(pluginRenamedEvent); assertThat(tree.searchItems(NavWorkbenchCtx.perspective(PERSPECTIVE_ID))).isEmpty(); assertThat(tree.searchItems(NavWorkbenchCtx.perspective(perspectiveRenamedPlugin.getName())).get(0).getContext()).contains("resourceId=" + perspectiveRenamedPlugin.getName()); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Command.class); verify(navigationManager, times(1)).saveNavTree(anyObject(), argumentCaptor.capture()); verify(perspectiveChangedEvent).fire(anyObject()); } @Test public void testPluginDeleted() { NavTree testTree = TEST_NAV_TREE.cloneTree(); assertThat(testTree.getItemById(PERSPECTIVE_ID)).isNotNull(); when(navigationManager.getNavTree()).thenReturn(testTree); testedPluginManager.onPlugInDeleted(pluginDeletedEvent); assertThat(testTree.getItemById(PERSPECTIVE_ID)).isNull(); verify(navigationManager).saveNavTree(anyObject(), eq(null)); verify(perspectiveChangedEvent).fire(anyObject()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/widget/NavMenuBarWidgetTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.mvp.PlaceManager; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class NavMenuBarWidgetTest { @Mock NavMenuBarWidget.View view; @Mock NavDropDownWidget.View viewAdmin; @Mock NavDropDownWidget.View viewDashboards; @Mock SyncBeanDef dropDownBean; @Mock PerspectivePluginManager pluginManager; @Mock NavigationManager navigationManager; @Mock SyncBeanManager beanManager; @Mock PlaceManager placeManager; NavDropDownWidget dropDownAdmin; NavDropDownWidget dropDownDashboards; NavMenuBarWidget presenter; NavTree tree; public static final String ITEM_ID_HOME = "home"; public static final String ITEM_ID_GALLERY = "gallery"; public static final String ITEM_ID_ADMIN = "admin"; public static final String ITEM_ID_DATASETS = "datasets"; public static final String ITEM_ID_CONTENTMGMT = "contentmgmt"; public static final String ITEM_ID_DASHBOARDS = "dashboards"; public static final String ITEM_ID_DASHBOARD1 = "dashboard1"; public static final String ITEM_ID_DASHBOARD2 = "dashboard2"; @Before public void setUp() throws Exception { dropDownAdmin = new NavDropDownWidget(viewAdmin, beanManager, navigationManager); dropDownDashboards = new NavDropDownWidget(viewDashboards, beanManager, navigationManager); presenter = new NavMenuBarWidget(view, beanManager, pluginManager, placeManager, navigationManager); tree = new NavTreeBuilder() .item(ITEM_ID_HOME, "Home", null, false, NavWorkbenchCtx.perspective(ITEM_ID_HOME)) .item(ITEM_ID_GALLERY, "Gallery", null, false, NavWorkbenchCtx.perspective(ITEM_ID_GALLERY)) .group(ITEM_ID_ADMIN, "Administration", null, false) .item(ITEM_ID_DATASETS, "Datasets", null, false, NavWorkbenchCtx.perspective(ITEM_ID_DATASETS)) .item(ITEM_ID_CONTENTMGMT, "Content Manager", null, false, NavWorkbenchCtx.perspective(ITEM_ID_CONTENTMGMT)) .endGroup() .group(ITEM_ID_DASHBOARDS, "Dashboards", null, false) .item(ITEM_ID_DASHBOARD1, "Dashboard 1", null, false, NavWorkbenchCtx.perspective(ITEM_ID_DASHBOARD1)) .item(ITEM_ID_DASHBOARD2, "Dashboard 2", null, false, NavWorkbenchCtx.perspective(ITEM_ID_DASHBOARD2)) .endGroup() .build(); when(beanManager.lookupBean(NavDropDownWidget.class)).thenReturn(dropDownBean); when(dropDownBean.newInstance()).thenReturn(dropDownAdmin, dropDownDashboards); } @Test public void testShowMenuBar() { presenter.show(tree); verify(view).init(presenter); verify(view, never()).setSelectedItem(anyString()); verify(view).addItem(eq(ITEM_ID_HOME), anyString(), any(), any()); verify(view).addItem(eq(ITEM_ID_GALLERY), anyString(), any(), any()); verify(view).addGroupItem(eq(ITEM_ID_ADMIN), anyString(), any(), eq(dropDownAdmin)); verify(view).addGroupItem(eq(ITEM_ID_DASHBOARDS), anyString(), any(), eq(dropDownDashboards)); verify(viewAdmin).setDropDownName("Administration"); verify(viewAdmin, never()).setActive(true); verify(viewAdmin).addItem(eq(ITEM_ID_DATASETS), anyString(), any(), any()); verify(viewAdmin).addItem(eq(ITEM_ID_CONTENTMGMT), anyString(), any(), any()); verify(viewDashboards).setDropDownName("Dashboards"); verify(viewDashboards, never()).setActive(true); verify(viewDashboards).addItem(eq(ITEM_ID_DASHBOARD1), anyString(), any(), any()); verify(viewDashboards).addItem(eq(ITEM_ID_DASHBOARD2), anyString(), any(), any()); } @Test public void testSelectRootItem() { presenter.show(tree); reset(view, viewAdmin, viewDashboards); presenter.setSelectedItem(ITEM_ID_HOME); verify(view).setSelectedItem(ITEM_ID_HOME); verify(viewAdmin, never()).setActive(true); verify(viewDashboards, never()).setActive(true); } @Test public void testSelectNestedItem() { presenter.show(tree); reset(view, viewAdmin, viewDashboards); presenter.setSelectedItem(ITEM_ID_CONTENTMGMT); assertEquals(presenter.getItemSelected(), tree.getItemById(ITEM_ID_CONTENTMGMT)); assertEquals(dropDownAdmin.getItemSelected(), tree.getItemById(ITEM_ID_CONTENTMGMT)); assertNull(dropDownDashboards.getItemSelected()); verify(view).clearSelectedItem(); verify(viewAdmin).setActive(true); verify(viewAdmin).setSelectedItem(ITEM_ID_CONTENTMGMT); verify(viewDashboards, never()).setActive(true); } @Test public void testSwitchFromNestedToRoot() { presenter.show(tree); presenter.setSelectedItem(ITEM_ID_CONTENTMGMT); reset(view, viewAdmin, viewDashboards); presenter.onItemClicked(tree.getItemById(ITEM_ID_HOME)); assertEquals(presenter.getItemSelected(), tree.getItemById(ITEM_ID_HOME)); assertNull(dropDownAdmin.getItemSelected()); assertNull(dropDownDashboards.getItemSelected()); verify(view).clearSelectedItem(); verify(view).setSelectedItem(ITEM_ID_HOME); verify(viewAdmin).setActive(false); verify(viewDashboards, never()).setActive(true); } @Test public void testNullNavGroup() { presenter.show((NavGroup) null); verify(view).errorNavGroupNotFound(); } @Test public void testNullNavTree() { presenter.show((NavTree) null); verify(view).errorNavItemsEmpty(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/widget/NavTabListWidgetTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.mvp.PlaceManager; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class NavTabListWidgetTest { @Mock NavTabListWidget.View view; @Mock NavTabListWidget.View viewAdmin; @Mock NavTabListWidget.View viewDashboards; @Mock SyncBeanDef tablistBean; @Mock PerspectivePluginManager pluginManager; @Mock NavigationManager navigationManager; @Mock SyncBeanManager beanManager; @Mock PlaceManager placeManager; NavTabListWidget tabsAdmin; NavTabListWidget tabsDashboards; NavTabListWidget presenter; NavTree tree; public static final String ITEM_ID_HOME = "home"; public static final String ITEM_ID_GALLERY = "gallery"; public static final String ITEM_ID_ADMIN = "admin"; public static final String ITEM_ID_DATASETS = "datasets"; public static final String ITEM_ID_CONTENTMGMT = "contentmgmt"; public static final String ITEM_ID_DASHBOARDS = "dashboards"; public static final String ITEM_ID_DASHBOARD1 = "dashboard1"; public static final String ITEM_ID_DASHBOARD2 = "dashboard2"; @Before public void setUp() throws Exception { tabsAdmin = new NavTabListWidget(viewAdmin, beanManager, pluginManager, placeManager, navigationManager); tabsDashboards = new NavTabListWidget(viewDashboards, beanManager, pluginManager, placeManager, navigationManager); presenter = new NavTabListWidget(view, beanManager, pluginManager, placeManager, navigationManager); presenter.setGotoItemEnabled(true); tree = new NavTreeBuilder() .item(ITEM_ID_HOME, "Home", null, false, NavWorkbenchCtx.perspective(ITEM_ID_HOME)) .item(ITEM_ID_GALLERY, "Gallery", null, false, NavWorkbenchCtx.perspective(ITEM_ID_GALLERY)) .group(ITEM_ID_ADMIN, "Administration", null, false) .item(ITEM_ID_DATASETS, "Datasets", null, false, NavWorkbenchCtx.perspective(ITEM_ID_DATASETS)) .item(ITEM_ID_CONTENTMGMT, "Content Manager", null, false, NavWorkbenchCtx.perspective(ITEM_ID_CONTENTMGMT)) .endGroup() .group(ITEM_ID_DASHBOARDS, "Dashboards", null, false) .item(ITEM_ID_DASHBOARD1, "Dashboard 1", null, false, NavWorkbenchCtx.perspective(ITEM_ID_DASHBOARD1)) .item(ITEM_ID_DASHBOARD2, "Dashboard 2", null, false, NavWorkbenchCtx.perspective(ITEM_ID_DASHBOARD2)) .endGroup() .build(); when(beanManager.lookupBean(NavTabListWidget.class)).thenReturn(tablistBean); when(tablistBean.newInstance()).thenReturn(tabsAdmin, tabsDashboards); when(pluginManager.isRuntimePerspective(any(NavItem.class))).thenReturn(true); } @Test public void testShow() { presenter.show(tree); assertEquals(presenter.getItemSelected(), tree.getItemById(ITEM_ID_HOME)); verify(view).init(presenter); verify(view).addItem(eq(ITEM_ID_HOME), anyString(), any(), any()); verify(view).addItem(eq(ITEM_ID_GALLERY), anyString(), any(), any()); verify(view).addGroupItem(eq(ITEM_ID_ADMIN), anyString(), any(), eq(tabsAdmin)); verify(view).addGroupItem(eq(ITEM_ID_DASHBOARDS), anyString(), any(), eq(tabsDashboards)); verify(view).setSelectedItem(ITEM_ID_HOME); verify(viewAdmin).showAsSubmenu(true); verify(viewAdmin, never()).showChildrenTabs(any()); verify(viewAdmin).addItem(eq(ITEM_ID_DATASETS), anyString(), any(), any()); verify(viewAdmin).addItem(eq(ITEM_ID_CONTENTMGMT), anyString(), any(), any()); verify(viewDashboards).showAsSubmenu(true); verify(viewDashboards, never()).showChildrenTabs(any()); verify(viewDashboards).addItem(eq(ITEM_ID_DASHBOARD1), anyString(), any(), any()); verify(viewDashboards).addItem(eq(ITEM_ID_DASHBOARD2), anyString(), any(), any()); } @Test public void testDefaultNestedItem() { presenter.setDefaultNavItemId(ITEM_ID_DASHBOARD2); presenter.show(tree); assertEquals(presenter.getItemSelected(), tree.getItemById(ITEM_ID_DASHBOARD2)); assertEquals(tabsDashboards.getItemSelected(), tree.getItemById(ITEM_ID_DASHBOARD2)); assertNull(tabsAdmin.getItemSelected()); verify(view, atLeastOnce()).clearSelectedItem(); verify(view, atLeastOnce()).setSelectedItem(ITEM_ID_DASHBOARDS); verify(view).showChildrenTabs(tabsDashboards); verify(viewDashboards).setSelectedItem(ITEM_ID_DASHBOARD2); verify(viewAdmin, never()).showChildrenTabs(any()); } @Test public void testSelectNestedItem() { presenter.show(tree); reset(view, viewAdmin, viewDashboards); presenter.setSelectedItem(ITEM_ID_CONTENTMGMT); assertEquals(presenter.getItemSelected(), tree.getItemById(ITEM_ID_CONTENTMGMT)); assertEquals(tabsAdmin.getItemSelected(), tree.getItemById(ITEM_ID_CONTENTMGMT)); assertNull(tabsDashboards.getItemSelected()); verify(view).clearSelectedItem(); verify(view).showChildrenTabs(any()); verify(viewAdmin).setSelectedItem(ITEM_ID_CONTENTMGMT); verify(viewDashboards, never()).showChildrenTabs(any()); } @Test public void testSwitchFromNestedToRoot() { presenter.show(tree); presenter.setSelectedItem(ITEM_ID_CONTENTMGMT); reset(view, viewAdmin, viewDashboards); presenter.onItemClicked(tree.getItemById(ITEM_ID_HOME)); assertEquals(presenter.getItemSelected(), tree.getItemById(ITEM_ID_HOME)); assertNull(tabsAdmin.getItemSelected()); assertNull(tabsDashboards.getItemSelected()); verify(view).clearSelectedItem(); verify(view).setSelectedItem(ITEM_ID_HOME); verify(view, never()).showChildrenTabs(any()); verify(viewAdmin, never()).showChildrenTabs(any()); verify(viewDashboards, never()).showChildrenTabs(any()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/widget/NavTilesWidgetTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.mvp.PlaceManager; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class NavTilesWidgetTest { @Mock NavTilesWidget.View view; @Mock PerspectivePluginManager pluginManager; @Mock NavigationManager navigationManager; @Mock SyncBeanManager beanManager; @Mock PlaceManager placeManager; @Mock SyncBeanDef tileWidgetBeanDef; @Mock NavItemTileWidget tileWidget; NavTilesWidget presenter; NavTree tree; @Before public void setUp() throws Exception { when(beanManager.lookupBean(NavItemTileWidget.class)).thenReturn(tileWidgetBeanDef); when(tileWidgetBeanDef.getInstance()).thenReturn(tileWidget); presenter = new NavTilesWidget(view, navigationManager, pluginManager, placeManager, beanManager); tree = new NavTreeBuilder() .group("Home", "Home", null, false) .group("A", "A", null, false) .item("A1", "A1", null, false) .item("A2", "A2", null, false) .group("A3", "A3", null, false) .item("A31", "A3", null, false) .build(); } @Test public void testOpenItem() { NavItem navItem = tree.getItemById("A"); presenter.openItem(navItem); assertEquals(presenter.getNavItemStack().size(), 2); verify(view, times(3)).addTileWidget(tileWidget); verify(view).clearBreadcrumb(); verify(view).addBreadcrumbItem(eq("Home"), any()); verify(view).addBreadcrumbItem(eq("A")); reset(view); navItem = tree.getItemById("A3"); presenter.openItem(navItem); assertEquals(presenter.getNavItemStack().size(), 3); verify(view, times(1)).addTileWidget(tileWidget); verify(view).clearBreadcrumb(); verify(view).addBreadcrumbItem(eq("Home"), any()); verify(view).addBreadcrumbItem(eq("A"), any()); verify(view).addBreadcrumbItem(eq("A3")); } @Test public void testGotoHome() { NavItem navItem = tree.getItemById("A"); presenter.openItem(navItem); reset(view); NavItem homeItem = tree.getItemById("Home"); presenter.gotoBreadcrumbItem(homeItem); assertEquals(presenter.getNavItemStack().size(), 0); verify(view, times(1)).addTileWidget(tileWidget); verify(view).clearBreadcrumb(); verify(view, never()).addBreadcrumbItem(any(), any()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/widget/editor/NavItemEditorTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.navigation.event.NavItemEditCancelledEvent; import org.dashbuilder.client.navigation.event.NavItemEditStartedEvent; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(GwtMockitoTestRunner.class) public class NavItemEditorTest { @Mock NavItemDefaultEditorView view; @Mock SyncBeanManager beanManager; @Mock PerspectiveTreeProvider perspectiveTreeProvider; @Mock EventSourceMock navItemEditStartedEvent; @Mock EventSourceMock navItemEditCancelledEvent; @Mock PlaceManager placeManager; @Mock TargetPerspectiveEditor targetPerspectiveEditor; @Mock PerspectivePluginManager perspectivePluginManager; @Mock Command updateCommand; NavItemEditor presenter; static final String NEW_PERSPECTIVE_NAME = "- New Perspective -"; @Before public void setUp() throws Exception { presenter = new NavItemDefaultEditor(view, beanManager, placeManager, perspectiveTreeProvider, targetPerspectiveEditor, perspectivePluginManager, navItemEditStartedEvent, navItemEditCancelledEvent); when(view.i18nNewItemName("Perspective")).thenReturn(NEW_PERSPECTIVE_NAME); presenter.getSettings().setLiteralPerspective("Perspective"); doAnswer(invocationOnMock -> invocationOnMock.getArguments()[0]) .when(targetPerspectiveEditor).getPerspectiveName(anyString()); } @Test public void testChangeGroup() { NavGroup navGroup = NavFactory.get().createNavGroup(); navGroup.setId("id"); navGroup.setName("name"); navGroup.setDescription("description"); navGroup.setModifiable(true); presenter.setOnUpdateCommand(updateCommand); presenter.edit(navGroup); when(view.getItemName()).thenReturn("name"); presenter.onChangesOk(); verify(view).finishItemEdition(); verify(updateCommand).execute(); assertEquals(presenter.getNavItem().getName(), "name"); reset(updateCommand); reset(view); when(view.getItemName()).thenReturn(" \t "); presenter.onChangesOk(); verify(view, never()).finishItemEdition(); verify(updateCommand, never()).execute(); assertEquals(presenter.getNavItem().getName(), "name"); reset(updateCommand); reset(view); when(view.getItemName()).thenReturn("newName"); presenter.onChangesOk(); verify(view).finishItemEdition(); verify(updateCommand).execute(); assertEquals(presenter.getNavItem().getName(), "newName"); } @Test public void testChangePerspective() { NavItem navItem = NavFactory.get().createNavItem(); NavWorkbenchCtx navCtxA = NavWorkbenchCtx.perspective("A"); NavWorkbenchCtx navCtxB = NavWorkbenchCtx.perspective("B"); navItem.setContext(navCtxA.toString()); navItem.setId("id"); navItem.setName("name"); navItem.setDescription("description"); navItem.setModifiable(true); presenter.setOnUpdateCommand(updateCommand); presenter.edit(navItem); // Empty perspective when(view.getItemName()).thenReturn("name"); presenter.onChangesOk(); verify(view, never()).finishItemEdition(); // Perspective changes reset(updateCommand); reset(view); when(view.getItemName()).thenReturn("name"); when(targetPerspectiveEditor.getPerspectiveId()).thenReturn("B"); presenter.onChangesOk(); verify(view).finishItemEdition(); verify(updateCommand).execute(); assertEquals(presenter.getNavItem().getName(), "name"); assertEquals(presenter.getNavItem().getContext(), navCtxB.toString()); // Cancel changes navItem.setContext(navCtxA.toString()); presenter.edit(navItem); reset(updateCommand); reset(targetPerspectiveEditor); reset(view); when(view.getItemName()).thenReturn("newName"); when(targetPerspectiveEditor.getPerspectiveId()).thenReturn("B"); presenter.cancelEdition(); verify(view).finishItemEdition(); verify(view).setItemName("name"); verify(targetPerspectiveEditor).setPerspectiveId("A"); assertEquals(presenter.getNavItem().getName(), "name"); assertEquals(presenter.getNavItem().getContext(), navCtxA.toString()); } @Test public void testEditGroup() { NavGroup navGroup = NavFactory.get().createNavGroup(); navGroup.setId("id"); navGroup.setName("name"); navGroup.setDescription("description"); navGroup.setModifiable(false); presenter.edit(navGroup); verify(view, atLeastOnce()).clearChildren(); verify(view, atLeastOnce()).clearCommands(); verify(view).setItemName("name"); verify(view).setItemDescription("description"); verify(view).setItemEditable(false); verify(view).setItemType(NavItemEditor.ItemType.GROUP); verify(view, atLeastOnce()).setCommandsEnabled(true); verify(view, atLeastOnce()).addCommand(any(), any()); verify(view, never()).setContextWidget(any()); } @Test public void testEditDivider() { NavDivider divider = NavFactory.get().createDivider(); divider.setId("id"); divider.setName("name"); divider.setDescription("description"); divider.setModifiable(true); presenter.edit(divider); verify(view, atLeastOnce()).clearChildren(); verify(view, atLeastOnce()).clearCommands(); verify(view).setItemName("name"); verify(view).setItemDescription("description"); verify(view).setItemEditable(false); verify(view).setItemType(NavItemEditor.ItemType.DIVIDER); verify(view, atLeastOnce()).setCommandsEnabled(true); verify(view, atLeastOnce()).addCommand(any(), any()); verify(view, never()).setContextWidget(any()); reset(view); presenter.startEdition(); verify(view, never()).startItemEdition(); } @Test public void testEditPerspective() { NavItem navItem = NavFactory.get().createNavItem(); navItem.setModifiable(false); navItem.setContext(NavWorkbenchCtx.perspective("p1").toString()); presenter.edit(navItem); verify(view, atLeastOnce()).clearChildren(); verify(view, atLeastOnce()).clearCommands(); verify(view).setItemEditable(false); verify(view).setItemType(NavItemEditor.ItemType.PERSPECTIVE); verify(view, atLeastOnce()).setCommandsEnabled(true); verify(view, atLeastOnce()).addCommand(any(), any()); verify(view).setContextWidget(targetPerspectiveEditor); } @Test public void testCommandsAvailability() { // Disable move actions presenter.setMoveUpEnabled(false); presenter.setMoveDownEnabled(false); // Non-modifiable group (only creation actions available) NavGroup navGroup = NavFactory.get().createNavGroup(); navGroup.setModifiable(false); presenter.edit(navGroup); verify(view, atLeastOnce()).setCommandsEnabled(true); // Modifiable group (creation actions) reset(view); navGroup.setModifiable(true); presenter.edit(navGroup); verify(view, atLeastOnce()).setCommandsEnabled(true); // Non-modifiable perspective (move actions disabled => no actions) reset(view); NavItem navItem = NavFactory.get().createNavItem(); navItem.setContext(NavWorkbenchCtx.perspective("p1").toString()); navItem.setModifiable(false); presenter.edit(navItem); verify(view, never()).setCommandsEnabled(true); // Modifiable perspective (only delete action) reset(view); navItem.setModifiable(true); presenter.edit(navItem); verify(view).setItemEditable(true); verify(view).setItemDeletable(true); verify(view, never()).setCommandsEnabled(true); // Modifiable divider (only delete action) reset(view); NavDivider navDivider = NavFactory.get().createDivider(); navDivider.setModifiable(true); presenter.edit(navDivider); verify(view).setItemEditable(false); verify(view).setItemDeletable(true); verify(view, never()).setCommandsEnabled(true); // Non-modifiable divider (no actions) reset(view); navDivider.setModifiable(false); presenter.edit(navDivider); verify(view, never()).setCommandsEnabled(true); // Move actions available reset(view); presenter.setMoveUpEnabled(true); presenter.setMoveDownEnabled(true); presenter.edit(navItem); verify(view, atLeastOnce()).setCommandsEnabled(true); reset(view); presenter.edit(navDivider); verify(view, atLeastOnce()).setCommandsEnabled(true); reset(view); presenter.edit(navGroup); verify(view, atLeastOnce()).setCommandsEnabled(true); } @Test public void testItemNameFromPerspective() { NavItem navItem = NavFactory.get().createNavItem(); navItem.setId("id"); navItem.setName("name"); navItem.setModifiable(true); navItem.setContext(NavWorkbenchCtx.perspective("A").toString()); // Existing item => The name does not changes on perspective change presenter.edit(navItem); presenter.startEdition(); verify(view).setItemName("name"); when(targetPerspectiveEditor.getPerspectiveId()).thenReturn("B"); presenter.onTargetPerspectiveUpdated(); verify(view, never()).setItemName("B"); // Newly created item => The name always matches the selected perspective reset(view); navItem.setName(NEW_PERSPECTIVE_NAME); presenter.edit(navItem); presenter.startEdition(); verify(view).setItemName("A"); when(targetPerspectiveEditor.getPerspectiveId()).thenReturn("B"); presenter.onTargetPerspectiveUpdated(); verify(view).setItemName("B"); // If user changes the name then the auto-matching is disabled reset(view); presenter.onItemNameChanged(); presenter.onTargetPerspectiveUpdated(); verify(view, never()).setItemName("B"); } @Test public void testCancelRestoresLastBackup() { NavItem navItem = NavFactory.get().createNavItem(); navItem.setId("id"); navItem.setName("name"); navItem.setModifiable(true); navItem.setContext(NavWorkbenchCtx.perspective("A").toString()); // Modify the item when(targetPerspectiveEditor.getPerspectiveId()).thenReturn("A"); presenter.edit(navItem); presenter.startEdition(); when(view.getItemName()).thenReturn("newName"); presenter.onChangesOk(); assertEquals(presenter.getNavItem().getName(), "newName"); // Edit again and cancel edition. The name must match the latest name set. presenter.startEdition(); presenter.cancelEdition(); assertEquals(presenter.getNavItem().getName(), "newName"); // Editing a new item resets the latest backup presenter.edit(navItem); presenter.startEdition(); presenter.cancelEdition(); assertEquals(presenter.getNavItem().getName(), "name"); } @Test public void testBackupIsNotUpdatedOnError() { NavItem navItem = NavFactory.get().createNavItem(); navItem.setId("id"); navItem.setName("name"); navItem.setModifiable(true); navItem.setContext(NavWorkbenchCtx.perspective("A").toString()); // Edit with errors (missing perspective selected) presenter.edit(navItem); presenter.startEdition(); when(view.getItemName()).thenReturn("newName"); presenter.onChangesOk(); assertEquals(presenter.getNavItem().getName(), "newName"); // Cancel edition restores the initial backup presenter.cancelEdition(); assertEquals(presenter.getNavItem().getName(), "name"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/widget/editor/NavTreeEditorTest.java ================================================ package org.dashbuilder.client.navigation.widget.editor; import java.util.Collection; import java.util.HashSet; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.navigation.event.NavItemEditCancelledEvent; import org.dashbuilder.client.navigation.event.NavItemEditStartedEvent; import org.dashbuilder.client.navigation.event.NavItemGotoEvent; import org.dashbuilder.navigation.event.NavTreeChangedEvent; import org.dashbuilder.client.navigation.event.NavTreeLoadedEvent; import org.dashbuilder.client.navigation.impl.NavigationManagerImpl; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.service.NavigationServices; import org.dashbuilder.navigation.workbench.NavSecurityController; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.mocks.CallerMock; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import org.uberfire.mvp.ParameterizedCommand; 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.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class NavTreeEditorTest { @Mock NavTreeEditorView view; @Mock SyncBeanManager beanManager; @Mock PerspectiveTreeProvider perspectiveTreeProvider; @Mock EventSourceMock navItemEditStartedEvent; @Mock EventSourceMock navItemEditCancelledEvent; @Mock LoadingBox loadingBox; @Mock EventSourceMock navItemGotoEvent; @Mock EventSourceMock navTreeLoadedEvent; @Mock EventSourceMock navTreeChangedEvent; @Mock NavigationServices navServices; @Mock NavSecurityController navController; @Mock PlaceManager placeManager; @Mock TargetPerspectiveEditor targetPerspectiveEditor; @Mock PerspectivePluginManager perspectivePluginManager; @Mock NavItemDefaultEditorView navItemEditorView; @Mock NavRootNodeEditorView navRootNodeEditorView; @Mock SyncBeanDef navItemEditorBeanDef; @Mock SyncBeanDef navRootNodeEditorBeanDef; @Mock Command updateCommand; @Mock Plugin perspectivePlugin; Collection perspectivePlugins = new HashSet<>(); NavigationManager navigationManager; NavTreeEditor navTreeEditor; NavItemDefaultEditor navItemEditor; NavRootNodeEditor navRootNodeEditor; NavTree NAV_TREE = new NavTreeBuilder() .group("level1a", "level1a", "level1a", true) .group("level2a", "level2a", "level2a", true) .endGroup() .endGroup() .group("level1b", "level1b", "level1b", true) .group("level2b", "level2b", "level2b", true) .endGroup() .endGroup() .build(); @Before public void setUp() { navigationManager = spy(new NavigationManagerImpl(new CallerMock<>(navServices), navController, navTreeLoadedEvent, navTreeChangedEvent, navItemGotoEvent)); navTreeEditor = spy(new NavTreeEditor(view, navigationManager, beanManager, placeManager, perspectiveTreeProvider, targetPerspectiveEditor, perspectivePluginManager, navItemEditStartedEvent, navItemEditCancelledEvent, loadingBox)); navTreeEditor.setChildEditorClass(NavRootNodeEditor.class); navItemEditor = spy(new NavItemDefaultEditor(navItemEditorView, beanManager, placeManager, perspectiveTreeProvider, targetPerspectiveEditor, perspectivePluginManager, navItemEditStartedEvent, navItemEditCancelledEvent)); navRootNodeEditor = spy(new NavRootNodeEditor(navRootNodeEditorView, beanManager, placeManager, perspectiveTreeProvider, targetPerspectiveEditor, perspectivePluginManager, navItemEditStartedEvent, navItemEditCancelledEvent)); when(beanManager.lookupBean(NavItemDefaultEditor.class)).thenReturn(navItemEditorBeanDef); when(beanManager.lookupBean(NavRootNodeEditor.class)).thenReturn(navRootNodeEditorBeanDef); when(navItemEditorBeanDef.newInstance()).thenReturn(navItemEditor); when(navRootNodeEditorBeanDef.newInstance()).thenReturn(navRootNodeEditor); when(navItemEditorView.getItemName()).thenReturn("editor1"); when(navRootNodeEditorView.getItemName()).thenReturn("editor2"); perspectivePlugins.add(perspectivePlugin); doAnswer(invocationOnMock -> { ParameterizedCommand callback = (ParameterizedCommand) invocationOnMock.getArguments()[0]; callback.execute(perspectivePlugins); return null; }).when(perspectivePluginManager).getPerspectivePlugins(any()); } @Test public void testNewPerspectiveEnabled() { navTreeEditor.getSettings().setNewPerspectiveEnabled(true); assertTrue(navTreeEditor.getSettings().isNewPerspectiveEnabled(NAV_TREE.getItemById("level1b"))); navTreeEditor.setNewPerspectiveEnabled("level1b", false); assertFalse(navTreeEditor.getSettings().isNewPerspectiveEnabled(NAV_TREE.getItemById("level1b"))); assertTrue(navTreeEditor.getSettings().isNewPerspectiveEnabled(NAV_TREE.getItemById("level2b"))); navTreeEditor.setNewPerspectiveEnabled("level1b", false).applyToAllChildren(); assertFalse(navTreeEditor.getSettings().isNewPerspectiveEnabled(NAV_TREE.getItemById("level1b"))); assertFalse(navTreeEditor.getSettings().isNewPerspectiveEnabled(NAV_TREE.getItemById("level2b"))); } @Test public void testNewDividerEnabled() { navTreeEditor.getSettings().setNewDividerEnabled(true); assertTrue(navTreeEditor.getSettings().isNewDividerEnabled(NAV_TREE.getItemById("level1b"))); navTreeEditor.setNewDividerEnabled("level1b", false); assertFalse(navTreeEditor.getSettings().isNewDividerEnabled(NAV_TREE.getItemById("level1b"))); assertTrue(navTreeEditor.getSettings().isNewDividerEnabled(NAV_TREE.getItemById("level2b"))); navTreeEditor.setNewDividerEnabled("level1b", false).applyToAllChildren(); assertFalse(navTreeEditor.getSettings().isNewDividerEnabled(NAV_TREE.getItemById("level1b"))); assertFalse(navTreeEditor.getSettings().isNewDividerEnabled(NAV_TREE.getItemById("level2b"))); } @Test public void testAllSubgroupsAllowed() { navTreeEditor.getSettings().setMaxLevels(-1); navTreeEditor.edit(NAV_TREE); verify(navTreeEditor, times(2)).createChildEditor(any()); verify(navRootNodeEditor, times(2)).createChildEditor(any()); verify(navItemEditor, never()).createChildEditor(any()); } @Test public void testNoSubgroupsAllowed() { navTreeEditor.getSettings().setMaxLevels(1); navTreeEditor.edit(NAV_TREE); NavItem level1a = NAV_TREE.getItemById("level1a"); NavItem level2a = NAV_TREE.getItemById("level2a"); NavItem level1b = NAV_TREE.getItemById("level1b"); NavItem level2b = NAV_TREE.getItemById("level2b"); verify(navTreeEditor, never()).createChildEditor(eq(level1a)); verify(navTreeEditor, never()).createChildEditor(eq(level1b)); verify(navRootNodeEditor, never()).createChildEditor(eq(level2b)); verify(navRootNodeEditor, never()).createChildEditor(eq(level2a)); } @Test public void testSubgroupNotAllowed() { NavItem level1a = NAV_TREE.getItemById("level1a"); NavItem level2a = NAV_TREE.getItemById("level2a"); NavItem level1b = NAV_TREE.getItemById("level1b"); NavItem level2b = NAV_TREE.getItemById("level2b"); navTreeEditor.getSettings().setMaxLevels("level1a", 1); navTreeEditor.edit(NAV_TREE); verify(navTreeEditor).createChildEditor(eq(level1a)); verify(navTreeEditor).createChildEditor(eq(level1b)); verify(navRootNodeEditor).createChildEditor(eq(level2b)); verify(navRootNodeEditor, never()).createChildEditor(eq(level2a)); } @Test public void testOnlyThreeLevelsAllowed() { NavItem level1a = NAV_TREE.getItemById("level1a"); NavItem level2a = NAV_TREE.getItemById("level2a"); NavItem level1b = NAV_TREE.getItemById("level1b"); NavItem level2b = NAV_TREE.getItemById("level2b"); navTreeEditor.getSettings().setMaxLevels("root", 3); navTreeEditor.edit(NAV_TREE); verify(navTreeEditor).createChildEditor(eq(level1a)); verify(navTreeEditor).createChildEditor(eq(level1b)); verify(navTreeEditor, never()).createChildEditor(eq(level2a)); verify(navTreeEditor, never()).createChildEditor(eq(level2b)); } @Test public void testFinishEdition() { navTreeEditor.edit(NAV_TREE); navRootNodeEditor.newGroup(); navRootNodeEditor.finishEdition(); assertNull(navTreeEditor.getCurrentlyEditedItem()); } @Test public void itShouldBeImpossibleToOpenMultipleNavItemEditorInputs() { // DASHBUILDE-217 NavTree tree = NavFactory.get().createNavTree(); navTreeEditor.edit(tree); NavItemEditor first = mock(NavItemEditor.class); NavItemEditor second = mock(NavItemEditor.class); NavItem firstItem = mock(NavItem.class); when(first.getNavItem()).thenReturn(firstItem); navTreeEditor.onItemEditStarted(new NavItemEditStartedEvent(first)); navTreeEditor.onItemEditStarted(new NavItemEditStartedEvent(second)); verify(first).cancelEdition(); } @Test public void whenItemEditFinishedNavTreeEditorCleared() { navTreeEditor.edit(NAV_TREE); // When item editing starts the item is remembered in the tree NavItemEditor navItemEditor = navTreeEditor.newGroup(); navTreeEditor.onItemEditStarted(new NavItemEditStartedEvent(navItemEditor)); assertEquals(navItemEditor, navTreeEditor.currentlyEditedItem.get()); // When item editing finishes, it is cleaned from the navTreeEditor and view resets to "non-editing" state navItemEditor.onItemUpdated(); assertFalse(navTreeEditor.currentlyEditedItem.isPresent()); } @Test public void testNewGroup() { navTreeEditor.setOnUpdateCommand(updateCommand); navTreeEditor.edit(NAV_TREE); navTreeEditor.collapse(); assertFalse(navTreeEditor.isExpanded()); reset(view); NavItemEditor navItemEditor = navTreeEditor.newGroup(); assertEquals(((NavGroup) navTreeEditor.getNavItem()).getChildren().size(), 2); assertTrue(navTreeEditor.isExpanded()); verify(navItemEditor).startEdition(); verify(view, times(3)).addChild(any()); verify(updateCommand, never()).execute(); when(navRootNodeEditorView.getItemName()).thenReturn("A"); navItemEditor.onChangesOk(); verify(updateCommand).execute(); } @Test public void testNewPerspective() { navTreeEditor.setOnUpdateCommand(updateCommand); navTreeEditor.edit(NAV_TREE); navTreeEditor.collapse(); assertFalse(navTreeEditor.isExpanded()); reset(view); NavItemEditor navItemEditor = navTreeEditor.newPerspective(); assertEquals(((NavGroup) navTreeEditor.getNavItem()).getChildren().size(), 2); assertTrue(navTreeEditor.isExpanded()); verify(navItemEditor).startEdition(); verify(view, times(3)).addChild(any()); verify(updateCommand, never()).execute(); } @Test public void testNewDivider() { navTreeEditor.setOnUpdateCommand(updateCommand); navTreeEditor.edit(NAV_TREE); navTreeEditor.collapse(); assertFalse(navTreeEditor.isExpanded()); reset(view); navTreeEditor.newDivider(); assertTrue(navTreeEditor.isExpanded()); assertEquals(((NavGroup) navTreeEditor.getNavItem()).getChildren().size(), 3); verify(view, times(3)).addChild(any()); verify(updateCommand).execute(); } @Test public void testSaveAndCancel() { navTreeEditor.edit(NAV_TREE); NavItemEditor newEditor = navTreeEditor.newGroup(); newEditor.onChangesOk(); navTreeEditor.onSaveClicked(); NavTree navTree = navTreeEditor.getNavTree(); assertNotNull(navTree.getItemById(newEditor.getNavItem().getId())); } @Test public void testNewPerspectiveActionAvailable() { NavItemEditor navItemEditor = navTreeEditor.newGroup(); assertTrue(navItemEditor.isNewPerspectiveEnabled()); perspectivePlugins.clear(); assertFalse(navItemEditor.isNewPerspectiveEnabled()); } @Test public void testCancelLastEditedItem() { NavItemEditor navItemEditorA = mock(NavItemEditor.class); navTreeEditor.onItemEditStarted(new NavItemEditStartedEvent(navItemEditorA)); assertEquals(navTreeEditor.getCurrentlyEditedItem(), navItemEditorA); // No need for cancel if the same item is edited again navTreeEditor.onItemEditStarted(new NavItemEditStartedEvent(navItemEditorA)); verify(navItemEditorA, never()).cancelEdition(); // Last edited item must be cancelled NavItemEditor navItemEditorB = mock(NavItemEditor.class); navTreeEditor.onItemEditStarted(new NavItemEditStartedEvent(navItemEditorB)); assertEquals(navTreeEditor.getCurrentlyEditedItem(), navItemEditorB); verify(navItemEditorA).cancelEdition(); } @Test public void testEditIsNotInvokedTwiceAfterCancel() { navTreeEditor.edit(NAV_TREE); // When edit is cancelled avoid the parent's editor to invoke edit again reset(navItemEditor); navItemEditor.startEdition(); navItemEditor.cancelEdition(); verify(navItemEditor, times(1)).edit(any()); } @Test public void testOnNewTreeClicked() { navTreeEditor.newTree(); verify(navTreeEditor).saveDefaultNavTree(); verify(navTreeEditor).newGroup(); } @Test public void testSaveDefaultNavTreeWhenNavigationManagerDoesNotHaveNavTree() { doReturn(false).when(navigationManager).hasNavTree(); navTreeEditor.saveDefaultNavTree(); verify(navTreeEditor).showLoading(); verify(navigationManager).saveNavTree(any(), any(Command.class)); } @Test public void testSaveDefaultNavTreeWhenNavigationManagerHasNavTree() { doReturn(true).when(navigationManager).hasNavTree(); navTreeEditor.saveDefaultNavTree(); verify(navTreeEditor, never()).showLoading(); verify(navigationManager, never()).saveNavTree(any(NavTree.class), any(Command.class)); } @Test public void testShowLoading() { navTreeEditor.showLoading(); verify(loadingBox).show(); } @Test public void testHideLoading() { navTreeEditor.hideLoading(); verify(loadingBox).hide(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-navigation-client/src/test/java/org/dashbuilder/client/navigation/widget/editor/TargetPerspectiveEditorTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation.widget.editor; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.ext.widgets.common.client.dropdown.PerspectiveDropDown; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class TargetPerspectiveEditorTest { @Mock TargetPerspectiveEditor.View view; @Mock PerspectivePluginManager perspectivePluginManager; @Mock PerspectiveDropDown perspectiveDropDown; @Mock PerspectiveTreeProvider perspectiveTreeProvider; @Mock Command updateCommand; TargetPerspectiveEditor presenter; NavTree NAV_TREE = new NavTreeBuilder() .group("root", "root", "root", true) .group("level1a", "level1a", "level1a", true) .endGroup() .group("level1b", "level1b", "level1b", true) .endGroup() .group("levelnull", null, null, true) .group("level2a", "level2a", "level2a", true) .endGroup() .endGroup() .build(); @Before public void setUp() throws Exception { presenter = new TargetPerspectiveEditor(view, perspectiveDropDown,perspectivePluginManager, perspectiveTreeProvider); presenter.setNavItemList(NAV_TREE.getRootItems()); presenter.setPerspectiveId("A"); presenter.setNavGroupId("level1a"); presenter.setOnUpdateCommand(updateCommand); presenter.show(); } @Test public void testShow() { verify(perspectiveDropDown).setSelectedPerspective("A"); verify(view).setPerspectiveSelector(perspectiveDropDown); verify(view).clearNavGroupItems(); verify(view).setNavGroupSelection(eq("root>level1a"), any()); verify(view).addNavGroupItem(eq("root"), any()); verify(view).addNavGroupItem(eq("root>level1b"), any()); verify(view).addNavGroupItem(eq("level2a"), any()); verify(view, times(3)).addNavGroupItem(anyString(), any()); verify(view, never()).addNavGroupItem(eq("root>level1a"), any()); verify(view, never()).addNavGroupItem(eq("root>null"), any()); verify(view, never()).addNavGroupItem(eq("null"), any()); verify(view, never()).addNavGroupItem(eq("null>level2a"), any()); } @Test public void testGroupChange() { reset(view); presenter.onGroupSelected("level1b"); verify(view).clearNavGroupItems(); verify(view).setNavGroupSelection(eq("root>level1b"), any()); verify(view).addNavGroupItem(eq("root"), any()); verify(view).addNavGroupItem(eq("root>level1a"), any()); verify(view).addNavGroupItem(eq("level2a"), any()); verify(view, times(3)).addNavGroupItem(anyString(), any()); verify(view, never()).addNavGroupItem(eq("root>level1b"), any()); verify(view, never()).addNavGroupItem(eq("root>null"), any()); verify(view, never()).addNavGroupItem(eq("null"), any()); verify(view, never()).addNavGroupItem(eq("null>level2a"), any()); verify(updateCommand).execute(); } @Test public void testPerspectiveName() { when(perspectivePluginManager.isRuntimePerspective("A.1")).thenReturn(true); when(perspectiveTreeProvider.getPerspectiveName("B.1")).thenReturn("Pretty"); assertEquals(presenter.getPerspectiveName("A.1"), "A.1"); assertEquals(presenter.getPerspectiveName("B.1"), "Pretty"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/pom.xml ================================================ dashbuilder-renderers org.dashbuilder 7.75.0-SNAPSHOT 4.0.0 dashbuilder-renderer-c3 jar Dashbuilder Renderer C3 Dashbuilder Renderer for the C3 Chart API org.webjars c3 ${version.org.webjars.bower.c3} org.webjars.npm d3-geo-projection ${version.org.webjars.bower.d3geoprojection} org.webjars c3 org.webjars.npm d3-geo-projection org.webjars.npm d3-geo org.webjars.npm d3-array com.google.gwt gwt-user org.dashbuilder dashbuilder-common-client org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-client com.google.elemental2 elemental2-core com.google.elemental2 elemental2-dom com.google.jsinterop jsinterop-annotations com.google.jsinterop base org.jboss.errai errai-ioc org.jboss.errai errai-ui org.jboss.errai errai-common org.uberfire uberfire-workbench-client-views-patternfly provided org.gwtbootstrap3 gwtbootstrap3 org.uberfire uberfire-testing-utils test org.kie.soup kie-soup-dataset-api test-jar test org.dashbuilder dashbuilder-dataset-client test-jar test org.dashbuilder dashbuilder-displayer-client test-jar test org.apache.maven.plugins maven-dependency-plugin unpack-c3 process-resources unpack org.webjars c3 ${version.org.webjars.bower.c3} jar true ${project.build.directory}/c3 false true unpack-d3-geo-projection process-resources unpack org.webjars.npm d3-geo-projection ${version.org.webjars.bower.d3geoprojection} jar true ${project.build.directory}/d3geoprojection false true org.apache.maven.plugins maven-resources-plugin copy-c3-resources-js process-resources copy-resources ${project.build.outputDirectory}/org/dashbuilder/renderer/c3/client/exports/js ${project.build.directory}/c3/META-INF/resources/webjars/c3/${version.org.webjars.bower.c3} c3.min.js copy-d3geoprojection-resources-js process-resources copy-resources ${project.build.outputDirectory}/org/dashbuilder/renderer/c3/client/exports/js ${project.build.directory}/d3geoprojection/META-INF/resources/webjars/d3-geo-projection/${version.org.webjars.bower.d3geoprojection}/dist/ d3-geo-projection.min.js ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/C3AbstractDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import java.util.List; import java.util.Set; import org.dashbuilder.common.client.widgets.FilterLabel; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.client.AbstractGwtDisplayer; public abstract class C3AbstractDisplayer extends AbstractGwtDisplayer { protected FilterLabelSet filterLabelSet; public C3AbstractDisplayer(FilterLabelSet filterLabelSet) { super(); this.filterLabelSet = filterLabelSet; this.filterLabelSet.setOnClearAllCommand(this::onFilterClearAll); } public interface View

extends AbstractGwtDisplayer.View

{ void noData(); void setSize(int width, int height); void setFilterLabelSet(FilterLabelSet filterLabelSet); void showTitle(String title); } @Override protected void createVisualization() { getView().setFilterLabelSet(filterLabelSet); updateVisualization(); } @Override protected void updateVisualization() { getView().setSize(displayerSettings.getChartWidth(), displayerSettings.getChartHeight()); if (dataSet.getRowCount() == 0) { getView().noData(); } else { updateFilterStatus(); updateVisualizationWithData(); } } protected abstract void updateVisualizationWithData(); void onFilterClearAll() { super.filterReset(); // Update the displayer view in order to reflect the current selection // (only if not has already been redrawn in the previous filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } void onFilterLabelRemoved(String columnId, int row) { super.filterUpdate(columnId, row); // Update the displayer view in order to reflect the current selection // (only if not has already been redrawn in the previous filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } protected void addToSelection(int row) { String columnId = dataSet.getColumns().get(0).getId(); Integer maxSelections = displayerSettings.isFilterSelfApplyEnabled() ? null : dataSet.getRowCount(); filterUpdate(columnId, row, maxSelections); if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } protected void updateFilterStatus() { filterLabelSet.clear(); Set columnFilters = filterColumns(); if (displayerSettings.isFilterEnabled() && !columnFilters.isEmpty()) { for (String columnId : columnFilters) { List selectedValues = filterIntervals(columnId); DataColumn column = dataSet.getColumnById(columnId); for (Interval interval : selectedValues) { String formattedValue = formatInterval(interval, column); FilterLabel filterLabel = filterLabelSet.addLabel(formattedValue); filterLabel.setOnRemoveCommand(() -> onFilterLabelRemoved(columnId, interval.getIndex())); } } } } protected String evaluateValueToString(Object mightBeNull, ColumnSettings settings) { String value = columnValueToString(mightBeNull); return getEvaluator().evalExpression(value, settings.getValueExpression()); } protected String columnValueToString(Object mightBeNull) { return mightBeNull == null ? "" : mightBeNull.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/C3AbstractDisplayerView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.displayer.client.AbstractGwtDisplayerView; import org.dashbuilder.renderer.c3.client.resources.i18n.C3DisplayerConstants; import org.gwtbootstrap3.client.ui.Label; import org.gwtbootstrap3.client.ui.html.Text; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Panel; public abstract class C3AbstractDisplayerView

extends AbstractGwtDisplayerView

implements C3AbstractDisplayer.View

{ protected Panel container = GWT.create(FlowPanel.class); protected Panel displayerPanel = GWT.create(FlowPanel.class); private Panel filterPanel = GWT.create(FlowPanel.class); private Panel dataPanel = GWT.create(FlowPanel.class); private HTML titleHtml = GWT.create(HTML.class); FlexTable dataTable = GWT.create(FlexTable.class); protected int width; protected int height; @Override public void init(P presenter) { super.setPresenter(presenter); super.setVisualization(container); dataPanel.setVisible(false); dataPanel.add(dataTable); container.add(titleHtml); container.add(filterPanel); container.add(displayerPanel); container.add(dataPanel); filterPanel.getElement().setAttribute("cellpadding", "2"); } @Override public void showTitle(String title) { titleHtml.setText(title); } @Override public void setFilterLabelSet(FilterLabelSet widget) { HTMLElement element = widget.getElement(); element.getStyle().setProperty("position", "absolute"); element.getStyle().setProperty("z-index", "20"); filterPanel.clear(); filterPanel.add(ElementWrapperWidget.getWidget(element)); } @Override public void noData() { FlowPanel noDataPanel = GWT.create(FlowPanel.class); noDataPanel.setWidth(width + "px"); noDataPanel.setHeight(height + "px"); Label lblNoData = GWT.create(Label.class); lblNoData.setText(C3DisplayerConstants.INSTANCE.common_noData()); noDataPanel.add(lblNoData); displayerPanel.clear(); displayerPanel.add(noDataPanel); dataTable.clear(); } @Override public void setSize(int width, int height) { this.width = width; this.height = height; } public void setTableData(String[][] data) { dataTable.clear(); for (int i = 0; i < data.length; i++) { for (int j = 0; j < data[i].length; j++) { dataTable.setWidget(j, i, new Text(data[i][j])); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/C3Displayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import java.util.Iterator; import java.util.List; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.Position; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisInfo; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisX; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisY; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartData; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartSize; import org.dashbuilder.renderer.c3.client.jsbinding.C3Color; import org.dashbuilder.renderer.c3.client.jsbinding.C3DataInfo; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; import org.dashbuilder.renderer.c3.client.jsbinding.C3Legend; import org.dashbuilder.renderer.c3.client.jsbinding.C3Padding; import org.dashbuilder.renderer.c3.client.jsbinding.C3Point; import org.dashbuilder.renderer.c3.client.jsbinding.C3Selection; import org.dashbuilder.renderer.c3.client.jsbinding.C3Tick; import com.google.gwt.i18n.client.NumberFormat; import elemental2.core.JsObject; public abstract class C3Displayer extends C3AbstractDisplayer { private static final double DEFAULT_POINT_RADIUS = 2.5; protected C3JsTypesFactory factory; public static final String[] COLOR_PATTERN = { "#0088CE", "#CC0000", "#EC7A08", "#3F9C35", "#F0AB00", "#703FEC", "#007A87", "#92D400", "#35CAED", "#00659C", "#A30000", "#B35C00", "#B58100", "#6CA100", "#2D7623", "#005C66", "#008BAD", "#40199A"}; public interface View

extends C3AbstractDisplayer.View

{ void updateChart(C3ChartConf conf); String getType(); String getGroupsTitle(); String getColumnsTitle(); void showTitle(String title); void setFilterLabelSet(FilterLabelSet filterLabelSet); void setBackgroundColor(String color); void setResizable(int maxWidth, int maxHeight); void setTableData(String[][] data); } public C3Displayer(FilterLabelSet filterLabelSet, C3JsTypesFactory builder) { super(filterLabelSet); this.factory = builder; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(10) .setMinColumns(2) .setExtraColumnsAllowed(true) .setExtraColumnsType(ColumnType.NUMBER) .setColumnTypes(new ColumnType[]{ ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } @Override protected void updateVisualizationWithData() { if (displayerSettings.isResizable()) { getView().setResizable(displayerSettings.getChartWidth(), displayerSettings.getChartHeight()); } C3ChartConf conf = buildConfiguration(); getView().updateChart(conf); applyPropertiesToView(); String[][] tableData = getDataTable(); getView().setTableData(tableData); } protected C3ChartConf buildConfiguration() { C3AxisInfo axis = createAxis(); C3ChartData data = createData(); C3Point point = createPoint(); C3Padding padding = createPadding(); C3Legend legend = factory.c3Legend(displayerSettings.isChartShowLegend(), getLegendPosition()); C3Color color = createColor(); C3ChartSize size = createSize(); return factory.c3ChartConf( size, data, axis, factory.c3Grid(true, true), factory.c3Transition(0), point, padding, legend, color ); } protected C3Color createColor() { return factory.c3Color(COLOR_PATTERN); } protected C3ChartSize createSize() { C3ChartSize size = null; if (! displayerSettings.isResizable()) { size = factory.c3ChartSize(displayerSettings.getChartWidth(), displayerSettings.getChartHeight()); } return size; } protected C3Padding createPadding() { return factory.c3Padding(displayerSettings.getChartMarginTop(), displayerSettings.getChartMarginRight(), displayerSettings.getChartMarginBottom(), displayerSettings.getChartMarginLeft()); } protected C3Point createPoint() { return factory.c3Point(d -> DEFAULT_POINT_RADIUS); } protected C3ChartData createData() { String[][] series = createSeries(); String type = getView().getType(); String[][] groups = createGroups(); JsObject xs = createXs(); C3Selection selection = createSelection(); C3ChartData c3Data = factory.c3ChartData(series, type, groups, xs, selection); if (displayerSettings.isFilterNotificationEnabled()) { c3Data.setOnselected(this::addToSelection); } return c3Data; } protected C3Selection createSelection() { boolean filterEnabled = displayerSettings.isFilterNotificationEnabled(); return factory.c3Selection(filterEnabled, true, false); } protected JsObject createXs() { return null; } protected String[][] createGroups() { return new String[0][0]; } protected C3AxisInfo createAxis() { C3AxisX axisX = createAxisX(); C3AxisY axisY = createAxisY(); return factory.c3AxisInfo(false, axisX, axisY); } protected C3AxisX createAxisX() { String[] categories = createCategories(); C3Tick tick = createTickX(); return factory.c3AxisX("category", categories, tick); } protected C3Tick createTickX() { return factory.createC3Tick(null); } protected C3AxisY createAxisY() { C3Tick tickY = createTickY(); return factory.c3AxisY(true, tickY); } protected C3Tick createTickY() { return factory.createC3Tick(f -> { try { double doubleFormat = Double.parseDouble(f); return NumberFormat.getFormat("#,###.##").format(doubleFormat); } catch(NumberFormatException e) { return f; } }); } /** * This method extracts the categories of a dataset. * For most of the charts the first column of the dataset contains the categories. * * @return */ protected String[] createCategories() { List columns = dataSet.getColumns(); DataColumn dataColumn = columns.get(0); String[] categories = null; if (columns.size() > 0) { List values = dataColumn.getValues(); categories = new String[values.size()]; for (int i = 0; i < categories.length; i++) { Object val = values.get(i); if (val != null) { categories[i] = super.formatValue(val, dataColumn); } else { categories[i] = "cat_" + i; } } } return categories; } /** * Extracts the series of the column 1 and other columns * @return */ protected String[][] createSeries() { List columns = dataSet.getColumns(); String[][] data = null; if (columns.size() > 1) { data = new String[columns.size() - 1][]; for (int i = 1; i < columns.size(); i++) { DataColumn dataColumn = columns.get(i); ColumnSettings columnSettings = displayerSettings.getColumnSettings(dataColumn); List values = dataColumn.getValues(); String[] seriesValues = new String[values.size() + 1]; seriesValues[0] = columnSettings.getColumnName(); for (int j = 0; j < values.size(); j++) { seriesValues[j + 1] = values.get(j).toString(); } data[i - 1] = seriesValues; } } return data; } protected int getSelectedRowIndex(C3DataInfo info) { return info.getIndex(); } protected String getSelectedCategory(C3DataInfo info) { List values = dataSet.getColumns().get(0).getValues(); return values.get(info.getIndex()).toString(); } protected String[][] getDataTable() { List columns = dataSet.getColumns(); String data[][] = new String[columns.size()][]; for (int i = 0; i < columns.size(); i++) { List values = columns.get(i).getValues(); data[i] = new String[values.size()]; for (int j = 0; j < values.size(); j++) { data[i][j] = columnValueToString(values.get(j)); } } return data; } private void addToSelection(C3DataInfo data) { int row = getSelectedRowIndex(data); addToSelection(row); } private void applyPropertiesToView() { if (displayerSettings.isTitleVisible()) { getView().showTitle(displayerSettings.getTitle()); } getView().setBackgroundColor(displayerSettings.getChartBackgroundColor()); } private String getLegendPosition() { Position legendPosition = displayerSettings.getChartLegendPosition(); String c3LegendPosition = C3Legend.convertPosition(legendPosition); return c3LegendPosition; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/C3DisplayerView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import elemental2.dom.DomGlobal; import elemental2.dom.MutationObserver; import elemental2.dom.MutationObserverInit; import elemental2.dom.Node; import jsinterop.base.Js; import org.dashbuilder.renderer.c3.client.jsbinding.C3; import org.dashbuilder.renderer.c3.client.jsbinding.C3Chart; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.dashbuilder.renderer.c3.client.resources.i18n.C3DisplayerConstants; import org.dashbuilder.renderer.c3.mutationobserver.MutationObserverFactory; public abstract class C3DisplayerView

extends C3AbstractDisplayerView

implements C3Displayer.View

{ protected C3Chart chart; @Override public void init(P presenter) { super.init(presenter); } @Override public void updateChart(C3ChartConf conf) { displayerPanel.clear(); conf.setBindto(displayerPanel.getElement()); chart = C3.generate(conf); } @Override public String getGroupsTitle() { return C3DisplayerConstants.INSTANCE.common_Categories(); } @Override public String getColumnsTitle() { return C3DisplayerConstants.INSTANCE.common_Series(); } @Override public void setBackgroundColor(String color) { chart.getElement().getElementsByTagName("svg") .getItem(0).getStyle() .setBackgroundColor(color); } public void setResizable(int maxWidth, int maxHeight) { displayerPanel.setWidth("100%"); displayerPanel.getElement().getStyle().setProperty("maxWidth", maxWidth + "px"); displayerPanel.getElement().getStyle().setProperty("maxHeight", maxHeight + "px"); registerMutationObserver(); } private void registerMutationObserver() { MutationObserver observer = new MutationObserver((records, obs) -> { Node elementalNode = Js.cast(displayerPanel.getElement()); if (DomGlobal.document.body.contains((elementalNode))) { if (chart != null) { chart.flush(); } obs.disconnect(); } return null; }); MutationObserverInit options = new MutationObserverFactory().mutationObserverInit(); options.setChildList(true); observer.observe(DomGlobal.document.body, options); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/C3Renderer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import static org.dashbuilder.displayer.DisplayerSubType.AREA; import static org.dashbuilder.displayer.DisplayerSubType.AREA_STACKED; import static org.dashbuilder.displayer.DisplayerSubType.BAR; import static org.dashbuilder.displayer.DisplayerSubType.BAR_STACKED; import static org.dashbuilder.displayer.DisplayerSubType.COLUMN; import static org.dashbuilder.displayer.DisplayerSubType.COLUMN_STACKED; import static org.dashbuilder.displayer.DisplayerSubType.DONUT; import static org.dashbuilder.displayer.DisplayerSubType.LINE; import static org.dashbuilder.displayer.DisplayerSubType.MAP_MARKERS; import static org.dashbuilder.displayer.DisplayerSubType.MAP_REGIONS; import static org.dashbuilder.displayer.DisplayerSubType.PIE; import static org.dashbuilder.displayer.DisplayerSubType.PIE_3D; import static org.dashbuilder.displayer.DisplayerSubType.SMOOTH; import static org.dashbuilder.displayer.DisplayerType.AREACHART; import static org.dashbuilder.displayer.DisplayerType.BARCHART; import static org.dashbuilder.displayer.DisplayerType.BUBBLECHART; import static org.dashbuilder.displayer.DisplayerType.LINECHART; import static org.dashbuilder.displayer.DisplayerType.MAP; import static org.dashbuilder.displayer.DisplayerType.METERCHART; import static org.dashbuilder.displayer.DisplayerType.PIECHART; import java.util.Arrays; import java.util.Collections; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.AbstractRendererLibrary; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.renderer.c3.client.charts.area.C3AreaChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.bar.C3BarChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.bubble.C3BubbleChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.line.C3LineChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.map.D3MapDisplayer; import org.dashbuilder.renderer.c3.client.charts.meter.C3MeterChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.pie.C3PieChartDisplayer; import org.dashbuilder.renderer.c3.client.exports.ResourcesInjector; import org.jboss.errai.ioc.client.container.SyncBeanManager; @ApplicationScoped public class C3Renderer extends AbstractRendererLibrary { public static final String UUID = "c3"; @PostConstruct public void prepare() { ResourcesInjector.ensureC3Injected(); } @Inject protected SyncBeanManager beanManager; private static List SUPPORTED_TYPES = Arrays.asList(LINECHART, BARCHART, PIECHART, AREACHART, BUBBLECHART, METERCHART, MAP); @Override public String getUUID() { return UUID; } @Override public String getName() { return "C3 Charts"; } @Override public List getSupportedSubtypes(DisplayerType displayerType) { switch (displayerType) { case LINECHART: return Arrays.asList(LINE, SMOOTH); case BARCHART: return Arrays.asList(BAR, BAR_STACKED, COLUMN, COLUMN_STACKED); case PIECHART: return Arrays.asList(PIE, DONUT, PIE_3D); case AREACHART: return Arrays.asList(AREA, AREA_STACKED); case MAP: return Arrays.asList(MAP_MARKERS, MAP_REGIONS); default: return Collections.emptyList(); } } public Displayer lookupDisplayer(DisplayerSettings displayerSettings) { DisplayerType displayerType = displayerSettings.getType(); DisplayerSubType subtype = displayerSettings.getSubtype(); C3AbstractDisplayer displayer; switch (displayerType) { case LINECHART: displayer = getLineChartForSubType(subtype); break; case BARCHART: displayer = createBarChartForSubType(subtype); break; case PIECHART: displayer = getPieChartForSubType(subtype); break; case AREACHART: displayer = getAreaChartForSubType(subtype); break; case BUBBLECHART: displayer = beanManager.lookupBean(C3BubbleChartDisplayer.class).newInstance(); break; case METERCHART: displayer = beanManager.lookupBean(C3MeterChartDisplayer.class).newInstance(); break; case MAP: displayer = createMapChartForSubType(subtype); break; default: return null; } return displayer; } private D3MapDisplayer createMapChartForSubType(DisplayerSubType subtype) { ResourcesInjector.ensureD3GeoProjectionInjected(); D3MapDisplayer displayer = beanManager.lookupBean(D3MapDisplayer.class).newInstance(); if (subtype == MAP_MARKERS) { displayer = displayer.markers(); } else { displayer = displayer.regions(); } return displayer; } private C3Displayer createBarChartForSubType(DisplayerSubType subtype) { C3Displayer displayer; switch (subtype) { case BAR: displayer = beanManager.lookupBean(C3BarChartDisplayer.class) .newInstance() .rotated(); break; case BAR_STACKED: displayer = beanManager.lookupBean(C3BarChartDisplayer.class) .newInstance() .stackedAndRotated(); break; case COLUMN: displayer = beanManager.lookupBean(C3BarChartDisplayer.class) .newInstance() .notRotated(); break; case COLUMN_STACKED: displayer = beanManager.lookupBean(C3BarChartDisplayer.class) .newInstance() .stacked(); break; default: displayer = beanManager.lookupBean(C3BarChartDisplayer.class) .newInstance() .rotated(); break; } return displayer; } private C3Displayer getLineChartForSubType(DisplayerSubType subtype) { C3LineChartDisplayer displayer = beanManager.lookupBean(C3LineChartDisplayer.class) .newInstance(); if (subtype == SMOOTH) { displayer = displayer.smooth(); } return displayer; } private C3Displayer getPieChartForSubType(DisplayerSubType subtype) { C3PieChartDisplayer displayer = beanManager.lookupBean(C3PieChartDisplayer.class) .newInstance(); if (subtype == DONUT) { displayer = displayer.donut(); } return displayer; } private C3Displayer getAreaChartForSubType(DisplayerSubType subtype) { C3AreaChartDisplayer areaChartDisplayer = beanManager.lookupBean(C3AreaChartDisplayer.class) .newInstance(); if (subtype == AREA_STACKED) { areaChartDisplayer = areaChartDisplayer.stacked(); } return areaChartDisplayer; } @Override public List getSupportedTypes() { return SUPPORTED_TYPES; } @Override public boolean isDefault(DisplayerType type) { return SUPPORTED_TYPES.contains(type); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/C3XYDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import java.util.List; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisInfo; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisLabel; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; import org.dashbuilder.renderer.c3.client.jsbinding.C3Tick; public abstract class C3XYDisplayer extends C3Displayer { private static final String DEFAULT_LABEL_POS = "outer-center"; private boolean stacked; public C3XYDisplayer(FilterLabelSet filterLabelSet, C3JsTypesFactory builder) { super(filterLabelSet, builder); } @Override protected C3ChartConf buildConfiguration() { C3ChartConf conf = super.buildConfiguration(); applyPropertiesToAxes(conf.getAxis()); return conf; } protected C3Tick createTickY() { return factory.createC3Tick(f -> { List columns = dataSet.getColumns(); if (columns.size() > 1) { DataColumn dataColumn = columns.get(1); f = super.formatValue(f, dataColumn); } return f; }); } private void applyPropertiesToAxes(C3AxisInfo axis) { axis.getX().getTick().setRotate(displayerSettings.getXAxisLabelsAngle()); if (displayerSettings.isXAxisShowLabels()) { C3AxisLabel xLabel = factory.createC3Label(displayerSettings.getXAxisTitle(), DEFAULT_LABEL_POS); axis.getX().setLabel(xLabel); } if (displayerSettings.isYAxisShowLabels()) { C3AxisLabel yLabel = factory.createC3Label(displayerSettings.getYAxisTitle(), DEFAULT_LABEL_POS); axis.getY().setLabel(yLabel); } } protected String[][] stackedGroups() { String[][] groups; groups = new String[1][]; groups[0] = dataSet.getColumns() .stream().skip(1) .map(displayerSettings::getColumnSettings) .map(ColumnSettings::getColumnName) .toArray(String[]::new); return groups; } @Override protected String[][] createGroups() { String[][] groups = new String[0][0]; if (isStacked()) { groups = stackedGroups(); } return groups; } public boolean isStacked() { return stacked; } public void setStacked(boolean stacked) { this.stacked = stacked; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/CommonC3DisplayerConstants.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; /** * A common class for displayer constraints supported by a C3 displayer. */ public class CommonC3DisplayerConstants { private DataSetLookupConstraints lookupConstraints; public CommonC3DisplayerConstants(DataSetLookupConstraints lookupConstraints) { this.lookupConstraints = lookupConstraints; } public DisplayerConstraints create() { return new DisplayerConstraints(lookupConstraints).supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_RESIZABLE) .supportsAttribute(DisplayerAttributeGroupDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeGroupDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/area/C3AreaChartDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.area; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.renderer.c3.client.C3Displayer; import org.dashbuilder.renderer.c3.client.C3XYDisplayer; import org.dashbuilder.renderer.c3.client.charts.CommonC3DisplayerConstants; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf.RenderedCallback; @Dependent public class C3AreaChartDisplayer extends C3XYDisplayer { public interface View extends C3Displayer.View { public void fixAreaOpacity(); } private View view; RenderedCallback fixAreaOpacityCallback = () -> getView().fixAreaOpacity(); @Inject public C3AreaChartDisplayer(View view, FilterLabelSet filterLabelSet, C3JsTypesFactory factory) { super(filterLabelSet, factory); this.view = view; this.view.init(this); } public C3AreaChartDisplayer stacked() { this.setStacked(true); return this; } @Override protected C3ChartConf buildConfiguration() { C3ChartConf conf = super.buildConfiguration(); conf.setOnrendered(fixAreaOpacityCallback); return conf; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxGroups(1) .setMinColumns(2) .setMaxColumns(10) .setExtraColumnsAllowed(true) .setExtraColumnsType(ColumnType.NUMBER) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new CommonC3DisplayerConstants(lookupConstraints).create() .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } @Override public View getView() { return view; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/area/C3AreaChartView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.area; import org.dashbuilder.renderer.c3.client.C3DisplayerView; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NodeList; public class C3AreaChartView extends C3DisplayerView implements C3AreaChartDisplayer.View { @Override public void updateChart(C3ChartConf conf) { super.updateChart(conf); fixAreaOpacity(); } @Override public String getType() { return "area"; } @Override public void fixAreaOpacity() { // This is a workaround for: https://github.com/c3js/c3/issues/2551 if (chart != null) { NodeList paths = chart.getElement().getElementsByTagName("path"); int n = paths.getLength(); for (int i = 0; i < n; i++) { Element child = paths.getItem(i); String className = child.getAttribute("class"); if (className != null && className.contains("c3-area-")) { child.getStyle().setOpacity(0.2); } } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/bar/C3BarChartDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.bar; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.renderer.c3.client.C3Displayer; import org.dashbuilder.renderer.c3.client.C3XYDisplayer; import org.dashbuilder.renderer.c3.client.charts.CommonC3DisplayerConstants; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisInfo; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; import org.dashbuilder.renderer.c3.client.jsbinding.C3Tick; import com.google.gwt.i18n.client.NumberFormat; @Dependent public class C3BarChartDisplayer extends C3XYDisplayer { public interface View extends C3Displayer.View { } private boolean rotated; private View view; @Inject public C3BarChartDisplayer(View view, FilterLabelSet filterLabelSet, C3JsTypesFactory factory) { super(filterLabelSet, factory); this.view = view; this.view.init(this); } public C3BarChartDisplayer notRotated() { this.setRotated(false); this.setStacked(false); return this; } public C3BarChartDisplayer rotated() { this.setRotated(true); this.setStacked(false); return this; } public C3BarChartDisplayer stacked() { this.setRotated(false); this.setStacked(true); return this; } public C3BarChartDisplayer stackedAndRotated() { this.setRotated(true); this.setStacked(true); return this; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(10) .setMinColumns(2) .setExtraColumnsAllowed(true) .setExtraColumnsType( ColumnType.NUMBER) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new CommonC3DisplayerConstants(lookupConstraints).create() .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } @Override protected C3AxisInfo createAxis() { C3AxisInfo axis = super.createAxis(); axis.setRotated(isRotated()); axis.getY().getTick().setRotate(30); return axis; } public boolean isRotated() { return rotated; } public void setRotated(boolean rotated) { this.rotated = rotated; } @Override public View getView() { return view; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/bar/C3BarChartView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.bar; import org.dashbuilder.renderer.c3.client.C3DisplayerView; public class C3BarChartView extends C3DisplayerView implements C3BarChartDisplayer.View { @Override public String getType() { return "bar"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/bubble/BubbleData.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.bubble; public class BubbleData { public Double x, y; public String category; public BubbleData(Double x, Double y, String category) { super(); this.x = x; this.y = y; this.category = category; } public Double getX() { return x; } public Double getY() { return y; } public String getCategory() { return category; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/bubble/C3BubbleChartDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.bubble; 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 javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.renderer.c3.client.C3Displayer; import org.dashbuilder.renderer.c3.client.C3XYDisplayer; import org.dashbuilder.renderer.c3.client.charts.CommonC3DisplayerConstants; import org.dashbuilder.renderer.c3.client.charts.area.C3AreaChartDisplayer; import org.dashbuilder.renderer.c3.client.jsbinding.C3DataInfo; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; import org.dashbuilder.renderer.c3.client.jsbinding.C3Point; import com.google.gwt.core.shared.GWT; import elemental2.core.JsObject; import jsinterop.base.Any; import jsinterop.base.Js; @Dependent public class C3BubbleChartDisplayer extends C3XYDisplayer { public interface View extends C3Displayer.View { } private static final int X_INDEX = 1; private static final int Y_INDEX = 2; private static final int R_INDEX = 4; private static double MIN_BUBBLE_SIZE = 5; private static double MAX_BUBBLE_SIZE = 45; private View view; @Inject public C3BubbleChartDisplayer(View view, FilterLabelSet filterLabelSet, C3JsTypesFactory factory) { super(filterLabelSet, factory); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(5) .setMinColumns(5) .setExtraColumnsAllowed(false) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTitle(1, "X") .setColumnTitle(2, "Y") .setColumnTitle(3, "Bubble Size") .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER, ColumnType.NUMBER, ColumnType.LABEL, ColumnType.NUMBER}); return new CommonC3DisplayerConstants(lookupConstraints).create() .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } protected String[][] createSeries() { List columns = dataSet.getColumns(); String[] categories = createCategories(); String[][] data = new String[categories.length * 2][]; List bubbleData = new ArrayList<>(); for (int i = 0; i < categories.length; i++) { String x = columns.get(X_INDEX).getValues().get(i).toString(); String y = columns.get(Y_INDEX).getValues().get(i).toString(); bubbleData.add(new BubbleData(Double.valueOf(x), Double.valueOf(y), categories[i])); } Collections.sort(bubbleData, Comparator.comparingDouble(BubbleData::getX)); for (int i = 0, y = 0; i < bubbleData.size(); i++) { BubbleData bData = bubbleData.get(i); String catY = bData.getCategory(); String catX = bData.getCategory() + "_x"; Double xVal = bData.getX(); Double yVal = bData.getY(); data[y] = new String[] {catX, xVal.toString()}; data[y + 1] = new String[] {catY, yVal.toString()}; y+=2; } return data; } @Override protected JsObject createXs() { JsObject xs = JsObject.create(null); String[] categories = createCategories(); for (String category : categories) { Js.cast(xs).asPropertyMap().set(category, category + "_x"); } return xs; } @Override protected C3Point createPoint() { List columns = dataSet.getColumns(); String[] categories = createCategories(); int n = categories.length; Map rValues = new HashMap<>(); List valuesBeforeMap = new ArrayList<>(); for (int i = 0; i < n; i++) { String valueStr = columns.get(R_INDEX).getValues().get(i).toString(); try { valuesBeforeMap.add(Double.parseDouble(valueStr)); } catch (NumberFormatException e) { GWT.log("Not able to retrieve radius values. Exiting radius calculation.", e); return super.createPoint(); } } double min = Collections.min(valuesBeforeMap); double max = Collections.max(valuesBeforeMap); for (int i = 0; i < n; i++) { String cat = categories[i]; double r; if (min == max) { r = (MAX_BUBBLE_SIZE + MIN_BUBBLE_SIZE) / 2; } else { r = map(valuesBeforeMap.get(i), min, max, MIN_BUBBLE_SIZE, MAX_BUBBLE_SIZE); } rValues.put(cat, r); } return factory.c3Point(d -> rValues.get(d.getId())); } @Override protected String getSelectedCategory(C3DataInfo info) { return info.getName(); } @Override protected int getSelectedRowIndex(C3DataInfo info) { String[] categories = createCategories(); return Arrays.asList(categories).indexOf(info.getName()); } private double map(double value, double start1, double stop1, double start2, double stop2) { return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/bubble/C3BubbleChartView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.bubble; import org.dashbuilder.renderer.c3.client.C3DisplayerView; public class C3BubbleChartView extends C3DisplayerView implements C3BubbleChartDisplayer.View { @Override public String getType() { return "scatter"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/line/C3LineChartDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.line; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.renderer.c3.client.C3Displayer; import org.dashbuilder.renderer.c3.client.C3XYDisplayer; import org.dashbuilder.renderer.c3.client.charts.CommonC3DisplayerConstants; import org.dashbuilder.renderer.c3.client.charts.area.C3AreaChartDisplayer; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; @Dependent public class C3LineChartDisplayer extends C3XYDisplayer { public interface View extends C3Displayer.View { void setSmooth(boolean smooth); } private View view; @Inject public C3LineChartDisplayer(View view, FilterLabelSet filterLabelSet, C3JsTypesFactory builder) { super(filterLabelSet, builder); this.view = view; this.view.init(this); } @Override public View getView() { return view; } public C3LineChartDisplayer smooth() { getView().setSmooth(true); return this; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxGroups(1) .setMinColumns(2) .setMaxColumns(10) .setExtraColumnsAllowed(true) .setExtraColumnsType(ColumnType.NUMBER) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new CommonC3DisplayerConstants(lookupConstraints).create() .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/line/C3LineChartView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.line; import org.dashbuilder.renderer.c3.client.C3DisplayerView; public class C3LineChartView extends C3DisplayerView implements C3LineChartDisplayer.View { boolean smooth = false; @Override public void init(C3LineChartDisplayer presenter) { super.init(presenter); } @Override public String getType() { return smooth ? "spline" : "line"; } @Override public void setSmooth(boolean smooth) { this.smooth = smooth; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/D3MapConf.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; import org.dashbuilder.displayer.MapColorScheme; import org.dashbuilder.renderer.c3.client.charts.map.geojson.CountriesGeoJsonService; public class D3MapConf { private String title; private Map data; private boolean markers; private boolean regions; private String backgroundColor = "#DDDDFF"; private CountriesGeoJsonService countriesGeoJsonService; private Function formatter; private Consumer pathClickHandler; private MapColorScheme colorScheme; private boolean showLegend; public D3MapConf(String title, Map data, boolean markers, boolean regions, String backgroundColor, CountriesGeoJsonService countriesGeoJsonService, Function formatter, Consumer pathClickHandler, MapColorScheme colorScheme, boolean showLegend) { this.title = title; this.data = data; this.markers = markers; this.regions = regions; this.backgroundColor = backgroundColor; this.formatter = formatter; this.countriesGeoJsonService = countriesGeoJsonService; this.pathClickHandler = pathClickHandler; this.colorScheme = colorScheme; this.showLegend = showLegend; } public static D3MapConf of(String title, Map data, boolean markers, boolean regions, String backgroundColor, CountriesGeoJsonService countriesGeoJsonService, Function formatter, Consumer pathClickHandler, MapColorScheme colorScheme, boolean showLegend) { return new D3MapConf(title, data, markers, regions, backgroundColor, countriesGeoJsonService, formatter, pathClickHandler, colorScheme, showLegend); } public boolean isMarkers() { return markers; } public boolean isRegions() { return regions; } public Map getData() { return data; } public String getTitle() { return title; } public String getBackgroundColor() { return backgroundColor; } public Function getFormatter() { return formatter; } public CountriesGeoJsonService getCountriesGeoJsonService() { return countriesGeoJsonService; } public Consumer getPathClickHandler() { return pathClickHandler; } public MapColorScheme getColorScheme() { return colorScheme; } public boolean isShowLegend() { return showLegend; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/D3MapDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.MapColorScheme; import org.dashbuilder.renderer.c3.client.C3AbstractDisplayer; import org.dashbuilder.renderer.c3.client.charts.map.geojson.CountriesGeoJsonService; @Dependent public class D3MapDisplayer extends C3AbstractDisplayer { View view; private boolean markers; private boolean regions; private CountriesGeoJsonService geoService; private D3MapConf conf; public interface View extends C3AbstractDisplayer.View { String getColumnsTitle(); String getGroupsTitle(); void createMap(D3MapConf conf); } @Override protected void createVisualization() { getView().setFilterLabelSet(filterLabelSet); super.createVisualization(); } @Inject public D3MapDisplayer(FilterLabelSet filterLabelSet, View view, CountriesGeoJsonService countriesGeoJsonService) { super(filterLabelSet); view.init(this); this.view = view; this.geoService = countriesGeoJsonService; } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMinColumns(2) .setMaxColumns(3) .setExtraColumnsAllowed(true) .setGroupsTitle(getView().getGroupsTitle()) .setColumnsTitle(getView().getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_SHOWLEGEND) .supportsAttribute(DisplayerAttributeGroupDef.MAP_GROUP); } @Override protected void updateVisualizationWithData() { Map data = retrieveData(dataSet); String backgroundColor = displayerSettings.getChartBackgroundColor(); String columnName = getDataColumnName(); MapColorScheme colorScheme = displayerSettings.getMapColorScheme(); conf = D3MapConf.of(columnName, data, markers, regions, backgroundColor, geoService, this::format, this::selectLocation, colorScheme, isShowLegend()); getView().createMap(conf); } private String getDataColumnName() { String name = "Data"; if (dataSet.getColumns().size() > 1) { DataColumn column = dataSet.getColumns().get(1); name = displayerSettings.getColumnSettings(column).getColumnName(); } return name; } protected Map retrieveData(DataSet dataSet) { Map data = new HashMap<>(); List columns = dataSet.getColumns(); List locations = columns.get(0).getValues(); List numbers = columns.get(1).getValues(); int total = locations.size(); for (int i = 0; i < total; i++) { Object locationValue = locations.get(i); Object numberValue = numbers.get(i); String numberStr = columnValueToString(numberValue); String location = columnValueToString(locationValue); Double value = Double.parseDouble(numberStr); data.put(location, value); } return data; } public void selectLocation(String location) { if (displayerSettings.isFilterNotificationEnabled()) { List columns = dataSet.getColumns(); List locations = columns.get(0).getValues(); int rowIndex = locations.indexOf(location); if (rowIndex != -1) { addToSelection(rowIndex); } } } public String format(Double value) { String textValue = value.toString(); List columns = dataSet.getColumns(); if (columns.size() > 1) { textValue = super.formatValue(value, columns.get(1)); } return textValue; } public D3MapDisplayer markers() { this.markers = true; return this; } public D3MapDisplayer regions() { this.regions = true; return this; } public D3MapConf getConf() { return conf; } public boolean isShowLegend() { return displayerSettings.isChartShowLegend(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/D3MapDisplayerView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map; import javax.inject.Inject; import org.dashbuilder.renderer.c3.client.C3AbstractDisplayerView; import org.dashbuilder.renderer.c3.client.charts.map.widgets.D3Map; import jsinterop.base.Js; public class D3MapDisplayerView extends C3AbstractDisplayerView implements D3MapDisplayer.View { D3Map map; @Inject public D3MapDisplayerView(D3Map map) { this.map = map; } @Override public void init(D3MapDisplayer presenter) { super.init(presenter); } @Override public String getColumnsTitle() { return "Columns"; } @Override public String getGroupsTitle() { return "Groups"; } @Override public void createMap(D3MapConf conf) { displayerPanel.getElement().removeAllChildren(); map.generateMap(width, height, conf); displayerPanel.getElement().appendChild(Js.cast( map.getElement())); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/geojson/CountriesGeoJsonService.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map.geojson; import java.util.Map; import java.util.Optional; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.Feature; /** * Class for handling GeoJson files that contains country information */ public interface CountriesGeoJsonService { public Feature[] getCountries(); public String getCountryName(Feature country); public String getCountryNameByCode(String code); public Optional findCountry(String idNameOrLocation); public Optional> findEntry(Map data, Feature feature); public Optional findValue(Map data, Feature feature); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/geojson/GeoJsonLoader.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map.geojson; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.FeatureCollection; @ApplicationScoped public interface GeoJsonLoader { public FeatureCollection load(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/geojson/impl/CountriesGeoJsonServiceImpl.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map.geojson.impl; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.PostConstruct; import javax.inject.Inject; import org.dashbuilder.renderer.c3.client.charts.map.geojson.CountriesGeoJsonService; import org.dashbuilder.renderer.c3.client.charts.map.geojson.GeoJsonLoader; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.Feature; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.FeatureCollection; import org.uberfire.client.views.pfly.widgets.D3; public class CountriesGeoJsonServiceImpl implements CountriesGeoJsonService { static final String COUNTRY_NAME_PROPERTY = "name"; static final String LAT_LONG_REGEX = "\\s*(\\-?\\d+(\\.\\d+)?),\\s*(\\-?\\d+(\\.\\d+)?)\\s*"; @Inject GeoJsonLoader geoJsonLoader; D3 d3; private FeatureCollection featureCollection; @PostConstruct public void setup() { featureCollection = geoJsonLoader.load(); d3 = D3.Builder.get(); } @Override public Feature[] getCountries() { return featureCollection.getFeatures(); } @Override public String getCountryName(Feature country) { Object name = country == null ? null : country.getProperties().get(COUNTRY_NAME_PROPERTY); if (name != null) { return name.toString(); } return ""; } @Override public String getCountryNameByCode(String code) { return Arrays.stream(featureCollection.getFeatures()) .filter(f -> f.getId().equalsIgnoreCase(code)) .map(this::getCountryName) .findFirst().orElse(""); } @Override public Optional> findEntry(Map data, Feature feature) { if (usesLocation(data)) { return entriesByLocation(data, feature).findAny(); } else { return entryByCountry(data, feature); } } @Override public Optional findValue(Map data, Feature feature) { if (usesLocation(data)) { return valueByLocation(data, feature); } return findEntry(data, feature).flatMap(e -> Optional.ofNullable(e.getValue())); } @Override public Optional findCountry(String idNameOrLocation) { if (idNameOrLocation.matches(LAT_LONG_REGEX)) { return countryByLocation(idNameOrLocation); } return countryByIdOrName(idNameOrLocation); } public Optional countryByIdOrName(String idOrName) { return Arrays.stream(featureCollection.getFeatures()) .filter(f -> { String countryName = getCountryName(f); return idOrName.equalsIgnoreCase(f.getId()) || idOrName.equalsIgnoreCase(countryName); }) .findFirst(); } public Optional countryByLocation(String location) { return Arrays.stream(featureCollection.getFeatures()) .filter(f -> containsLocation(location, f)) .findFirst(); } public Optional> entryByCountry(Map data, Feature value) { if (value == null) { return Optional.empty(); } String countryID = value.getId(); String countryName = getCountryName(value); return data.entrySet().stream().filter(k -> k.getKey().equalsIgnoreCase(countryID) || k.getKey().equalsIgnoreCase(countryName)) .findFirst(); } public Optional valueByCountry(Map data, Feature value) { return entryByCountry(data, value).flatMap(e -> Optional.ofNullable(e.getValue())); } public Stream> entriesByLocation(Map data, Feature feature) { return data.entrySet().stream() .filter(e -> e.getKey().matches(LAT_LONG_REGEX)) .filter(e -> containsLocation(e.getKey(), feature)); } public Optional valueByLocation(Map data, Feature feature) { // we may have multiple entries for a given feature (for example, multiple states of a country) // stream not working here for some reason... (applyAsDouble is not a function) // entriesByLocation(data, feature).flatMapToDouble(Entry::getKey).sum(); List values = entriesByLocation(data, feature).map(Entry::getValue).collect(Collectors.toList()); if (values.isEmpty()) { return Optional.empty(); } Double value = 0.0; for (Double v : values) { value += v; } return Optional.of(value); } protected boolean containsLocation(String latitudeLongitudeStr, Feature feature) { if (latitudeLongitudeStr == null || !latitudeLongitudeStr.matches(LAT_LONG_REGEX)) { return false; } // we use lat - long, but d3 considers long-lat Double[] latLong = extractLatLongInfo(latitudeLongitudeStr); Double[] longLat = {latLong[1], latLong[0]}; return d3.geoContains(feature, longLat); } protected Double[] extractLatLongInfo(String value) { return Stream.of(value.replaceAll("\\s", "").split(",")) .map(Double::parseDouble) .toArray(Double[]::new); } private boolean usesLocation(Map data) { if (data.isEmpty()) { return false; } return data.keySet().iterator().next().matches(LAT_LONG_REGEX); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/geojson/impl/GWTGeoJsonLoader.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map.geojson.impl; import org.dashbuilder.renderer.c3.client.charts.map.geojson.GeoJsonLoader; import org.dashbuilder.renderer.c3.client.exports.NativeLibraryResources; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.FeatureCollection; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONValue; import jsinterop.base.Js; public class GWTGeoJsonLoader implements GeoJsonLoader { @Override public FeatureCollection load() { String geoJsonStr = NativeLibraryResources.INSTANCE.countriesgeojson().getText(); JSONValue geoJsonObject = JSONParser.parseStrict(geoJsonStr); return Js.cast(geoJsonObject.isObject().getJavaScriptObject()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/widgets/D3Map.css ================================================ .countries path { stroke: #AAAAAA; stroke-width: 0.4; fill: #D4D4D4; } .map-legend-caption { font: 14px sans-serif; text-anchor: start; font-weight: bold; color: black; } .fill-region { stroke-width: 0.4; } .fill-region:hover { stroke-width: 2.0; stroke: #777777; } .data-circle { fill-opacity: 0.6; stroke: #00DD00; stroke-width: 0.4; } .data-circle:hover { stroke-width: 2.0; } .map-legend-val { font: italic 10px sans-serif; text-anchor: start; font-weight: bold; color: black; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/widgets/D3Map.html ================================================

================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/widgets/D3Map.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map.widgets; import java.util.IntSummaryStatistics; import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.displayer.MapColorScheme; import org.dashbuilder.renderer.c3.client.charts.map.D3MapConf; import org.dashbuilder.renderer.c3.client.charts.map.geojson.CountriesGeoJsonService; import org.dashbuilder.renderer.c3.client.jsbinding.d3.D3PathGenerator; import org.dashbuilder.renderer.c3.client.jsbinding.d3.D3Projection; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.Feature; import org.jboss.errai.common.client.api.elemental2.IsElement; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.views.pfly.widgets.D3; import org.uberfire.client.views.pfly.widgets.D3.Selection; import elemental2.dom.DomGlobal; import elemental2.dom.Element; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; @Templated @Dependent public class D3Map implements IsElement { /** * Colors schemes for the map can be taken from D3 scheme colors and when doing * it we can define which index of scheme we will be getting using the constant * D3_COLOR_SCHEME_TOTAL */ private static final int D3_COLOR_SCHEME_TOTAL = 7; /** * In Marks map the max radius proportion based on the map width. * For example, if 20, then the radius of markers can't be bigger than width / 20. */ private static final int RADIUS_PROPORTION = 20; /** * The smallest radius for markers */ private static final int MIN_RADIUS = 2; private int width; private int height; private D3MapConf conf; private D3.Scale colorScale; private CountriesGeoJsonService countriesGeoJsonService; private Map data; @Inject private MapTooltip mapTooltip; @Inject private HTMLDivElement mapContainer; D3 d3 = D3.Builder.get(); private String[] colorsScheme; @PostConstruct public void init() { addTooltipElement(); } @Override public HTMLElement getElement() { return mapContainer; } public void generateMap(int width, int height, D3MapConf conf) { mapContainer.innerHTML = ""; this.width = width; this.height = height; this.conf = conf; this.countriesGeoJsonService = conf.getCountriesGeoJsonService(); this.data = conf.getData(); this.colorsScheme = getScheme(conf.getColorScheme())[D3_COLOR_SCHEME_TOTAL]; final Element mapSVG = DomGlobal.document.createElementNS("http://www.w3.org/2000/svg", "svg"); final Selection d3Selection = d3.select(mapSVG); final D3PathGenerator pathGenerator = createPathGenerator(); final IntSummaryStatistics statistics = data.values().stream() .mapToInt(v -> v.intValue()).summaryStatistics(); Integer[] domain = new Integer[]{statistics.getMin(), statistics.getMax()}; colorScale = d3.scaleQuantize().domain(domain).range(colorsScheme); D3 map = createMap(d3Selection, pathGenerator); if (conf.isRegions()) { fillRegions(map); } if (conf.isMarkers()) { addMarkers(d3Selection, pathGenerator); } if (conf.isShowLegend()) { createLegend(d3Selection); } mapContainer.appendChild(mapSVG); } private String[][] getScheme(MapColorScheme colorScheme) { switch (colorScheme) { case BLUE: return d3.getSchemeBlues(); case GREEN: return d3.getSchemeGreens(); case RED: return d3.getSchemeReds(); default: return d3.getSchemeGreens(); } } private D3 createMap(Selection d3Selection, D3PathGenerator pathGenerator) { Feature[] countriesFeatures = countriesGeoJsonService.getCountries(); return d3Selection.attr("width", width).attr("height", height) .style("background", conf.getBackgroundColor()) .append("g").attr("class", "countries") .selectAll("path") .data(countriesFeatures) .enter().append("path") .attr("d", pathGenerator); } private void createLegend(D3 d3Selection) { int titleSize = 5; int legendSquareSize = 12; int legendSize = titleSize + (legendSquareSize * colorsScheme.length); AtomicInteger rectPos = new AtomicInteger(); AtomicInteger textPos = new AtomicInteger(legendSquareSize); String translate = "translate(0, " + (height - legendSize - 2) + ")"; D3 legendGroup = d3Selection.append("g").attr("transform", translate); legendGroup.append("text").attr("class", "map-legend-caption") .attr("x", 0).attr("y", titleSize * -1) .text(conf.getTitle()); D3 legendValuesGroup = legendGroup.append("g"); legendValuesGroup.selectAll("rect") .data(colorScale.range()).enter().append("rect") .attr("height", legendSquareSize).attr("width", legendSquareSize) .attr("y", (d, i, el) -> rectPos.getAndAdd(legendSquareSize)) .attr("fill", (d, i, el) -> d) .append("svg:title") .text((d, i, el) -> String.join(" - ", getFormattedBoundaryValues(d))); legendValuesGroup.selectAll("text").data(colorScale.range()).enter().append("text") .attr("class", "map-legend-val").attr("x", legendSquareSize + 2) .attr("y", (d, i, el) -> textPos.getAndAdd(legendSquareSize)).text((d, i, el) -> buildLegendValue(d, i)); } private void fillRegions(D3 map) { Feature[] countriesFeatures = countriesGeoJsonService.getCountries(); map.style("fill", (d, i, el) -> { Optional val = countriesGeoJsonService.findValue(data, countriesFeatures[i]); d3.select(el[i]).attr("class", "fill-region"); if (val.isPresent()) { return colorScale.call(colorScale, val.get()); } return null; }).on("mouseenter", (d, i, el) -> { Optional val = countriesGeoJsonService.findValue(data, countriesFeatures[i]); String countryName = countriesGeoJsonService.getCountryName(countriesFeatures[i]); mapTooltip.show(countryName, conf.getTitle(), val, conf.getFormatter()); return null; }).on("mousemove", (d, i, el) -> { mapTooltip.move(); return null; }).on("mouseleave", (d, i, el) -> { mapTooltip.hide(); return null; }).on("click", (d, i, el) -> { countriesGeoJsonService.findEntry(data, countriesFeatures[i]) .ifPresent(v -> conf.getPathClickHandler().accept(v.getKey())); return null; }); } private void addMarkers(Selection d3Selection, D3PathGenerator pathGenerator) { int maxRadius = width / RADIUS_PROPORTION; if (maxRadius < MIN_RADIUS) { maxRadius = MIN_RADIUS + 1; } D3.Scale radiusScale = d3.scaleSqrt().domain(colorScale.domain()) .range(new Integer[]{MIN_RADIUS, maxRadius}); Object[] countriesNames = data.keySet().toArray(); d3Selection.append("g").selectAll("circle").data(countriesNames).enter().append("circle") .attr("class", "data-circle").style("fill", (d, i, el) -> { double val = data.get(d); return colorScale.call(colorScale, val); }).attr("r", (d, i, el) -> { Optional path = countriesGeoJsonService.findCountry((String) d); if (path.isPresent()) { double val = data.get(d); return radiusScale.call(radiusScale, val); } return 0; }).attr("transform", (d, i, el) -> { String translate = ""; Optional path = countriesGeoJsonService.findCountry((String) d); if (path.isPresent()) { double[] center = pathGenerator.centroid(path.get()); translate = "translate(" + center[0] + ", " + center[1] + ")"; } return translate; }).on("mouseenter", (d, i, el) -> { Optional valOp = Optional.ofNullable(data.get(d)); mapTooltip.show((String) d, conf.getTitle(), valOp, conf.getFormatter()); return null; }).on("mousemove", (d, i, el) -> { mapTooltip.move(); return null; }).on("mouseleave", (d, i, el) -> { mapTooltip.hide(); return null; }).on("click", (d, i, el) -> { conf.getPathClickHandler().accept((String) d); return null; }); } private D3PathGenerator createPathGenerator() { double w = (double) width; double h = (double) height; D3Projection projection = D3Projection.Builder.get().geoNaturalEarth2().scale(w / 5.5d) .translate(new double[]{w / 2d, h / 2d}); return D3PathGenerator.Builder.get().geoPath() .projection(projection); } private void addTooltipElement() { HTMLElement tooltipElement = mapTooltip.getElement(); boolean elementNotAdded = DomGlobal.document.getElementById(tooltipElement.id) == null; if (elementNotAdded) { DomGlobal.document.body.appendChild(tooltipElement); } } private String buildLegendValue(Object d, int index) { String[] values = getFormattedBoundaryValues(d); int totalLegendColors = colorScale.range().length; if (values[0].equals(values[1])) { return values[0]; } else if (index + 1 == totalLegendColors) { return "> " + values[0]; } return "< " + values[1]; } private String[] getFormattedBoundaryValues(Object color) { Object[] values = colorScale.invertExtent(color); String minStr = String.valueOf(values[0]); String maxStr = String.valueOf(values[1]); double max = Double.parseDouble(maxStr); double min = Double.parseDouble(minStr); return new String[]{conf.getFormatter().apply(min), conf.getFormatter().apply(max)}; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/widgets/MapTooltip.css ================================================ .mapTooltipContainer { min-width: 100px; min-height: 50px; position: absolute; pointer-events: none; z-index: 10; background-color: AliceBlue; border-style: groove; border-radius: 8px; position: absolute; font-size: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/widgets/MapTooltip.html ================================================
Country Name
Data123456
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/map/widgets/MapTooltip.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map.widgets; import java.util.Optional; import java.util.function.Function; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import org.jboss.errai.common.client.api.elemental2.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.views.pfly.widgets.D3; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import jsinterop.base.Js; @Templated @ApplicationScoped public class MapTooltip implements IsElement { @Inject @DataField HTMLDivElement mapTooltipContainer; @Inject @DataField @Named("strong") HTMLElement lblTooltipTitle; @Inject @DataField @Named("span") HTMLElement lblTooltipCategory; @Inject @DataField @Named("strong") HTMLElement lblTooltipValue; private D3 d3 = D3.Builder.get(); @PostConstruct public void init() { mapTooltipContainer.style.opacity = Js.cast("0"); } @Override public HTMLElement getElement() { return mapTooltipContainer; } public void show(String title, String category, Optional data, Function formatter) { d3.select(mapTooltipContainer).transition().duration(400).style("opacity", "0.9"); lblTooltipTitle.textContent = title; if (data.isPresent()) { lblTooltipValue.style.visibility = "visible"; lblTooltipCategory.textContent = category + ": "; lblTooltipValue.textContent = formatter.apply(data.get()); } else { lblTooltipCategory.textContent = "No data."; lblTooltipValue.style.visibility = "hidden"; } } public void hide() { d3.select(mapTooltipContainer).transition().duration(500).style("opacity", "0"); } public void move() { int x = d3.getEvent().getPageX() + 10; int y = d3.getEvent().getPageY() - 40; d3.select(mapTooltipContainer).style("left", x + "px").style("top", y + "px"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/meter/C3MeterChartDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.meter; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.renderer.c3.client.C3Displayer; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.dashbuilder.renderer.c3.client.jsbinding.C3Color; import org.dashbuilder.renderer.c3.client.jsbinding.C3Gauge; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; import org.dashbuilder.renderer.c3.client.jsbinding.C3Threshold; import org.dashbuilder.renderer.c3.client.jsbinding.C3Tooltip; @Dependent public class C3MeterChartDisplayer extends C3Displayer { public interface View extends C3Displayer.View { String[] getColorPattern(); } private View view; @Inject public C3MeterChartDisplayer(View view, FilterLabelSet filterLabelSet, C3JsTypesFactory factory) { super(filterLabelSet, factory); this.view = view; this.view.init(this); } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(false) .setGroupAllowed(true) .setGroupColumn(true) .setMaxColumns(2) .setMinColumns(1) .setExtraColumnsAllowed(false) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setFunctionRequired(true) .setColumnTypes(new ColumnType[] {ColumnType.NUMBER}, new ColumnType[] {ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.METER_GROUP); } @Override public View getView() { return view; } @Override protected C3ChartConf buildConfiguration() { C3ChartConf conf = super.buildConfiguration(); C3Gauge gaugeConf = createGauge(); C3Tooltip tooltip = factory.c3Tooltip(this::formatTooltip); conf.setGauge(gaugeConf); conf.setTooltip(tooltip); return conf; } @Override protected String[][] createSeries() { List columns = dataSet.getColumns(); String[][] output = new String[0][0]; if (columns.size() == 1) { output = new String[1][]; output[0] = extractSingleColumnValues(columns.get(0)); } else { DataColumn groupsColumn = columns.get(0); DataColumn valuesColumn = columns.get(1); output = extractGroupingValues(groupsColumn, valuesColumn); } return output; } @Override protected C3Color createColor() { C3Color color = super.createColor(); int[] thresholdValues = { (int) displayerSettings.getMeterWarning(), (int) displayerSettings.getMeterCritical(), (int) displayerSettings.getMeterEnd() }; C3Threshold c3Threshold = factory.c3Threshold(thresholdValues); color.setPattern(getView().getColorPattern()); color.setThreshold(c3Threshold); return color; } private C3Gauge createGauge() { int meterStart = (int) displayerSettings.getMeterStart(); int meterEnd = (int) displayerSettings.getMeterEnd(); return factory.c3Gauge(meterStart, meterEnd); } String[][] extractGroupingValues(DataColumn groupsColumn, DataColumn valuesColumn) { int n = groupsColumn.getValues().size(); ColumnSettings settings = displayerSettings.getColumnSettings(valuesColumn); String[][] output = new String[n][2]; for (int i = 0; i < n; i++) { Object group = groupsColumn.getValues().get(i); Object value = valuesColumn.getValues().get(i); output[i][0] = columnValueToString(group); output[i][1] = evaluateValueToString(value, settings); } return output; } String[] extractSingleColumnValues(DataColumn dataColumn) { List values = dataColumn.getValues(); ColumnSettings settings = displayerSettings.getColumnSettings(dataColumn); String[] data = new String[values.size() + 1]; data[0] = dataColumn.getId(); for (int i = 0; i < values.size(); i++) { Object value = values.get(i); data[i + 1] = evaluateValueToString(value, settings); } return data; } protected Object formatTooltip(Long value, Object threshold, String data) { List columns = dataSet.getColumns(); int size = columns.size(); if (size == 1) { return formatValueForColumn(value, columns.get(0)); } if (size > 1) { return formatValueForColumn(value, columns.get(1)); } return value; } private Object formatValueForColumn(Long value, DataColumn targetColumn) { String pattern = displayerSettings.getColumnSettings(targetColumn).getValuePattern(); return getFormatter().formatNumber(pattern, value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/meter/C3MeterView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.meter; import org.dashbuilder.renderer.c3.client.C3DisplayerView; public class C3MeterView extends C3DisplayerView implements C3MeterChartDisplayer.View { private static final String RED = "#FF0000"; private static final String ORANGE = "#F97600"; private static final String GREEN = "#60B044"; String[] colors = { GREEN, ORANGE, RED }; @Override public String getType() { return "gauge"; } @Override public String[] getColorPattern() { return colors; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/pie/C3PieChartDisplayer.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.pie; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.renderer.c3.client.C3Displayer; import org.dashbuilder.renderer.c3.client.charts.CommonC3DisplayerConstants; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisX; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.dashbuilder.renderer.c3.client.jsbinding.C3Donut; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; @Dependent public class C3PieChartDisplayer extends C3Displayer { public interface View extends C3Displayer.View { void setShowAsDonut(boolean showAsDonut); } private View view; @Override protected C3ChartConf buildConfiguration() { C3ChartConf conf = super.buildConfiguration(); if (DisplayerSubType.DONUT == displayerSettings.getSubtype() && !StringUtils.isBlank(displayerSettings.getDonutHoleTitle())) { C3Donut donutConf = createDonut(); conf.setDonut(donutConf); } return conf; } @Inject public C3PieChartDisplayer(View view, FilterLabelSet filterLabelSet, C3JsTypesFactory builder) { super(filterLabelSet, builder); this.view = view; this.view.init(this); } @Override public View getView() { return view; } public C3PieChartDisplayer donut() { getView().setShowAsDonut(true); return this; } // In C3 we only need the series for PieCharts, categories are not needed @Override protected String[][] createSeries() { List columns = dataSet.getColumns(); String[][] data = null; // first columns hold the pie series name DataColumn categoriesColumn = columns.get(0); List values = categoriesColumn.getValues(); data = new String[values.size()][]; // next columns hold the values for each series for (int i = 0; i < values.size(); i++) { String[] seriesValues = new String[columns.size()]; seriesValues[0] = super.formatValue(values.get(i), categoriesColumn); for (int j = 1; j < columns.size(); j++) { DataColumn dataColumn = columns.get(j); seriesValues[j] = dataColumn.getValues().get(i).toString(); } data[i] = seriesValues; } return data; } @Override protected C3AxisX createAxisX() { return null; } @Override protected String[] createCategories() { return null; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(2) .setMinColumns(2) .setExtraColumnsAllowed(false) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[]{ ColumnType.LABEL, ColumnType.NUMBER}); return new CommonC3DisplayerConstants(lookupConstraints).create() .supportsAttribute(DisplayerAttributeDef.SUBTYPE); } protected C3Donut createDonut() { String donutHoleTitle = displayerSettings.getDonutHoleTitle(); return factory.c3Donut(donutHoleTitle); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/charts/pie/C3PieChartView.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.pie; import org.dashbuilder.renderer.c3.client.C3DisplayerView; public class C3PieChartView extends C3DisplayerView implements C3PieChartDisplayer.View { private boolean showAsDonut; @Override public String getType() { return showAsDonut ? "donut" : "pie"; } @Override public void setShowAsDonut(boolean showAsDonut) { this.showAsDonut = showAsDonut; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/exports/NativeLibraryResources.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.exports; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.TextResource; public interface NativeLibraryResources extends ClientBundle { NativeLibraryResources INSTANCE = GWT.create(NativeLibraryResources.class); @Source("js/c3.min.js") TextResource c3js(); @Source("js/d3-geo-projection.min.js") TextResource d3geoprojectionjs(); @Source("json/countries.geo.json") TextResource countriesgeojson(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/exports/ResourcesInjector.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.exports; import org.uberfire.client.views.pfly.sys.PatternFlyBootstrapper; import com.google.gwt.core.client.ScriptInjector; public class ResourcesInjector { static boolean c3Injected; static boolean d3geoprojectionInjected; public static void ensureC3Injected() { if (!c3Injected) { injectC3Resources(); c3Injected = true; } } public static void ensureD3GeoProjectionInjected() { if (!d3geoprojectionInjected) { injectD3GeoProjectionResources(); d3geoprojectionInjected = true; } } private static void injectC3Resources() { PatternFlyBootstrapper.ensureD3IsAvailable(); ScriptInjector.fromString(NativeLibraryResources.INSTANCE.c3js().getText()) .setWindow(ScriptInjector.TOP_WINDOW) .inject(); } private static void injectD3GeoProjectionResources() { PatternFlyBootstrapper.ensureD3IsAvailable(); ScriptInjector.fromString(NativeLibraryResources.INSTANCE.d3geoprojectionjs().getText()) .setWindow(ScriptInjector.TOP_WINDOW) .inject(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsMethod; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "c3") public class C3 { @JsMethod public static native C3Chart generate(C3ChartConf conf); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3AxisInfo.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3AxisInfo { @JsOverlay static C3AxisInfo create(boolean rotated, C3AxisX x, C3AxisY y) { C3AxisInfo instance = new C3AxisInfo(); instance.setRotated(rotated); instance.setX(x); instance.setY(y); return instance; } @JsProperty public native void setRotated(boolean rotated); @JsProperty public native void setX(C3AxisX x); @JsProperty public native C3AxisX getX(); @JsProperty public native void setY(C3AxisY y); @JsProperty public native C3AxisY getY(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3AxisLabel.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3AxisLabel { @JsOverlay static C3AxisLabel create(String text, String position) { C3AxisLabel instance = new C3AxisLabel(); instance.setText(text); instance.setPosition(position); return instance; } @JsProperty public native void setText(String text); @JsProperty public native void setPosition(String position); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3AxisX.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3AxisX { @JsOverlay static C3AxisX create(String type, String[] categories, C3Tick tick) { C3AxisX instance = new C3AxisX(); instance.setType(type); instance.setCategories(categories); instance.setTick(tick); return instance; } @JsProperty public native void setType(String type); @JsProperty public native void setCategories(String categories[]); @JsProperty public native void setTick(C3Tick tick); @JsProperty public native C3Tick getTick(); @JsProperty public native void setShow(boolean show); @JsProperty public native void setLabel(C3AxisLabel label); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3AxisY.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3AxisY { @JsOverlay static C3AxisY create(boolean show, C3Tick tick) { C3AxisY instance = new C3AxisY(); instance.setShow(show); instance.setTick(tick); return instance; } @JsProperty public native void setShow(boolean show); @JsProperty public native void setTick(C3Tick tick); @JsProperty public native C3Tick getTick(); @JsProperty public native void setLabel(C3AxisLabel label); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Chart.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import com.google.gwt.dom.client.DivElement; import jsinterop.annotations.JsMethod; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Chart { @JsProperty public native DivElement getElement(); @JsProperty public native C3Legend getLegend(); @JsMethod public native void flush(); @JsMethod public native void select(String[] points); public native void focus(String points); @JsMethod public native void defocus(); @JsMethod public native void resize(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3ChartConf.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import com.google.gwt.user.client.Element; import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; /** * Bind the type that should be passed to c3.generate */ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3ChartConf { @JsOverlay static C3ChartConf create(C3ChartSize size, C3ChartData data, C3AxisInfo axis, C3Grid grid, C3Transition transition, C3Point point, C3Padding padding, C3Legend legend, C3Color color) { C3ChartConf instance = new C3ChartConf(); instance.setSize(size); instance.setData(data); instance.setAxis(axis); instance.setGrid(grid); instance.setTransition(transition); instance.setPoint(point); instance.setPadding(padding); instance.setLegend(legend); instance.setColor(color); return instance; } @JsOverlay static C3ChartConf create(C3ChartSize size, C3ChartData data, C3AxisInfo axis, C3Grid grid, C3Transition transition, C3Point point, C3Padding padding, C3Legend legend, C3Color color, C3Tooltip tooltip) { C3ChartConf instance = new C3ChartConf(); instance.setSize(size); instance.setData(data); instance.setAxis(axis); instance.setGrid(grid); instance.setTransition(transition); instance.setPoint(point); instance.setPadding(padding); instance.setLegend(legend); instance.setColor(color); instance.setTooltip(tooltip); return instance; } @JsProperty public native void setBindto(Element element); @JsProperty public native void setSize(C3ChartSize size); @JsProperty public native void setData(C3ChartData data); @JsProperty public native void setAxis(C3AxisInfo axis); @JsProperty public native C3AxisInfo getAxis(); @JsProperty public native void setGrid(C3Grid grid); @JsProperty public native void setTransition(C3Transition transition); @JsProperty public native void setPoint(C3Point point); @JsProperty public native void setPadding(C3Padding padding); @JsProperty public native void setLegend(C3Legend legend); @JsProperty public native void setTooltip(C3Tooltip tooltip); @JsProperty public native void setOnrendered(RenderedCallback callback); @JsFunction @FunctionalInterface public interface RenderedCallback { void callback(); } @JsProperty public native void setColor(C3Color color); @JsProperty public native void setGauge(C3Gauge gauge); @JsProperty public native void setDonut(C3Donut donut); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3ChartData.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import elemental2.core.JsObject; import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3ChartData { @JsOverlay static C3ChartData create(String[][] columns, String type, String[][] groups, JsObject xs, C3Selection selection) { C3ChartData data = new C3ChartData(); data.setColumns(columns); data.setType(type); data.setGroups(groups); data.setXs(xs); data.setSelection(selection); return data; } @JsProperty public native void setColumns(String columns[][]); @JsProperty public native void setType(String type); @JsProperty public native void setGroups(String groups[][]); @JsProperty public native void setXs(JsObject xs); @JsProperty public native void setOrder(String order); @JsProperty public native void setOnselected(SelectCallback callback); @JsProperty public native void setOnunselected(SelectCallback callback); @JsProperty public native void setSelection(C3Selection selection); @JsFunction @FunctionalInterface public static interface SelectCallback { void callback(C3DataInfo data); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3ChartSize.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3ChartSize { @JsOverlay static C3ChartSize create(double width, double height) { C3ChartSize instance = new C3ChartSize(); instance.setWidth(width); instance.setHeight(height); return instance; } @JsProperty public native void setWidth(double width); @JsProperty public native void setHeight(double height); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Color.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Color { @JsOverlay static C3Color create(String[] pattern, C3Threshold threshold) { C3Color color = new C3Color(); color.setPattern(pattern); color.setThreshold(threshold); return color; } @JsOverlay static C3Color create(String[] pattern) { C3Color color = new C3Color(); color.setPattern(pattern); return color; } @JsProperty public native void setPattern(String[] pattern); @JsProperty public native void setThreshold(C3Threshold threshold); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3DataInfo.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3DataInfo { @JsProperty public native String getId(); @JsProperty public native int getIndex(); @JsProperty public native String getX(); @JsProperty public native String getValue(); @JsProperty public native String getName(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Donut.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Donut { @JsOverlay static C3Donut create(String title) { C3Donut data = new C3Donut(); data.setTitle(title); return data; } @JsProperty public native void setTitle(String title); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Format.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; /** * */ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Format { @JsOverlay static C3Format create(FormatCallback callback) { C3Format format = new C3Format(); format.setValue(callback); return format; } @JsProperty public native void setValue(FormatCallback callback); @JsFunction @FunctionalInterface public interface FormatCallback { Object callback(Long value, Object ratio, String data); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Gauge.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Gauge { @JsOverlay static C3Gauge create(int min, int max) { C3Gauge gauge = new C3Gauge(); gauge.setMin(min); gauge.setMax(max); return gauge; } @JsProperty public native void setMin(int min); @JsProperty public native void setMax(int max); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Grid.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Grid { @JsOverlay static C3Grid create(C3GridConf x , C3GridConf y) { C3Grid instance = new C3Grid(); instance.setX(x); instance.setY(y); return instance; } @JsProperty public native void setX(C3GridConf x); @JsProperty public native void setY(C3GridConf y); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3GridConf.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3GridConf { @JsOverlay static C3GridConf create(boolean show) { C3GridConf instance = new C3GridConf(); instance.setShow(show); return instance; } @JsProperty public native void setShow(boolean show); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3JsTypesFactory.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.renderer.c3.client.jsbinding.C3Point.RadiusCallback; import org.dashbuilder.renderer.c3.client.jsbinding.C3Tick.FormatterCallback; import elemental2.core.JsObject; /** * Build C3 JS Types */ @ApplicationScoped public class C3JsTypesFactory { public C3Tick createC3Tick(FormatterCallback callback) { C3Tick instance = new C3Tick(); instance.setFormat(callback); return instance; } public C3Grid c3Grid(boolean showX, boolean showY) { return C3Grid.create(C3GridConf.create(showX), C3GridConf.create(showY)); } public C3Padding c3Padding(int top, int right, int bottom, int left) { return C3Padding.create(top, right, bottom, left); } public C3ChartSize c3ChartSize(double width, double height) { return C3ChartSize.create(width, height); } public C3Selection c3Selection(boolean enabled, boolean multiple, boolean grouped) { return C3Selection.create(enabled, multiple, grouped); } public C3AxisY c3AxisY(boolean show, C3Tick tickY) { return C3AxisY.create(show, tickY); } public C3AxisX c3AxisX(String type, String[] categories, C3Tick tick) { return C3AxisX.create(type, categories, tick); } public C3Legend c3Legend(boolean show, String position) { return C3Legend.create(show, position); } public C3Point c3Point(RadiusCallback r) { return C3Point.create(r); } public C3ChartData c3ChartData(String[][] columns, String type, String[][] groups, JsObject xs, C3Selection selection) { return C3ChartData.create(columns, type, groups, xs, selection); } public C3AxisInfo c3AxisInfo(boolean rotated, C3AxisX axisX, C3AxisY axisY) { return C3AxisInfo.create(rotated, axisX, axisY); } public C3ChartConf c3ChartConf(C3ChartSize size, C3ChartData data, C3AxisInfo axis, C3Grid grid, C3Transition transition, C3Point point, C3Padding padding, C3Legend legend, C3Color color) { return C3ChartConf.create(size, data, axis, grid, transition, point, padding, legend, color); } public C3Transition c3Transition(int duration) { return C3Transition.create(duration); } public C3AxisLabel createC3Label(String text, String position) { return C3AxisLabel.create(text, position); } public C3Color c3Color(String[] pattern) { return C3Color.create(pattern); } public C3Color c3Color(String[] pattern, C3Threshold threshold) { return C3Color.create(pattern, threshold); } public C3Threshold c3Threshold(int[] values) { return C3Threshold.create(values); } public C3Gauge c3Gauge(int min, int max) { return C3Gauge.create(min, max); } public C3Donut c3Donut(String holeTitle) { return C3Donut.create(holeTitle); } public C3Tooltip c3Tooltip(C3Format.FormatCallback callback) { C3Format format = C3Format.create(callback); return C3Tooltip.create(format); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Legend.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import org.dashbuilder.displayer.Position; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Legend { @JsOverlay static C3Legend create(boolean show, String position) { C3Legend instance = new C3Legend(); instance.setShow(show); instance.setPosition(position); return instance; } @JsOverlay public static String convertPosition(Position position) { // Not all positions are supported by C3. switch(position) { case BOTTOM: return position.name().toLowerCase(); case IN: return "inset"; case RIGHT: return position.name().toLowerCase(); default: return ""; } } @JsProperty public native void setShow(boolean show); @JsProperty public native void setPosition(String position); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Padding.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Padding { @JsOverlay static C3Padding create(int top, int right, int bottom, int left ) { C3Padding instance = new C3Padding(); instance.setTop(top); instance.setRight(right); instance.setBottom(bottom); instance.setLeft(left); return instance; } @JsProperty public native void setTop(int top); @JsProperty public native void setRight(int right); @JsProperty public native void setBottom(int bottom); @JsProperty public native void setLeft(int left); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Point.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Point { @JsOverlay static C3Point create(RadiusCallback r) { C3Point instance = new C3Point(); instance.setR(r); return instance; } @JsProperty public native void setR(RadiusCallback callback); @JsFunction @FunctionalInterface public interface RadiusCallback { double callback(C3DataInfo value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Selection.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Selection { @JsOverlay static C3Selection create(boolean enabled, boolean multiple, boolean grouped) { C3Selection c3Selection = new C3Selection(); c3Selection.setEnabled(enabled); c3Selection.setMultiple(multiple); c3Selection.setGrouped(grouped); return c3Selection; } @JsProperty public native void setEnabled(boolean enabled); @JsProperty public native void setMultiple(boolean multiple); @JsProperty public native void setGrouped(boolean grouped); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Threshold.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Threshold { @JsOverlay static C3Threshold create(int[] values) { C3Threshold threshold = new C3Threshold(); threshold.setValues(values); return threshold; } @JsProperty public native void setValues(int[] values); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Tick.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Tick { @JsOverlay static C3Tick create(FormatterCallback callback) { C3Tick instance = new C3Tick(); instance.setFormat(callback); return instance; } @JsProperty public native void setFormat(FormatterCallback callback); @JsProperty public native void setFit(boolean fit); @JsProperty public native void setRotate(int rotate); @JsFunction @FunctionalInterface public interface FormatterCallback { String callback(String value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Tooltip.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Tooltip { @JsOverlay static C3Tooltip create(C3Format format) { C3Tooltip tooltip = new C3Tooltip(); tooltip.setFormat(format); return tooltip; } @JsProperty public native void setFormat(C3Format format); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/C3Transition.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class C3Transition { @JsOverlay public static C3Transition create(int duration) { C3Transition instance = new C3Transition(); instance.setDuration(duration); return instance; } @JsProperty public native void setDuration(int duration); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/d3/D3PathGenerator.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding.d3; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true) public interface D3PathGenerator { D3PathGenerator projection(D3Projection projection); D3PathGenerator geoPath(); double[] centroid(Object path); class Builder { @JsProperty(name = "d3", namespace = JsPackage.GLOBAL) public static native D3PathGenerator get(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/d3/D3Projection.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding.d3; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true) public interface D3Projection { public D3Projection geoNaturalEarth2(); public D3Projection geoCylindricalEqualArea(); public D3Projection geoMercator(); public D3Projection scale(double s); public D3Projection translate(double xy[]); class Builder { @JsProperty(name = "d3", namespace = JsPackage.GLOBAL) public static native D3Projection get(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/geojson/Feature.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding.geojson; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; import jsinterop.base.JsPropertyMap; @JsType(isNative = true) public interface Feature { @JsProperty public String getType(); @JsProperty public Geometry getGeometry(); @JsProperty public JsPropertyMap getProperties(); @JsProperty public String getId(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/geojson/FeatureCollection.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding.geojson; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true) public interface FeatureCollection { @JsProperty public String getType(); @JsProperty public Feature[] getFeatures(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/geojson/Geometry.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding.geojson; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true) public interface Geometry { @JsProperty public GeometryType getType(); @JsProperty public double[][][] getCoordinates(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/jsbinding/geojson/GeometryType.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.jsbinding.geojson; public enum GeometryType { Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, GeometryCollection; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface C3DisplayerConstants extends Messages { public static final C3DisplayerConstants INSTANCE = GWT.create( C3DisplayerConstants.class ); String common_Categories(); String common_Series(); String common_Values(); String common_Value(); String common_Locations(); String common_Rows(); String common_Columns(); String common_noData(); String googleDisplayer_resetAnchor(); String googleBubbleDisplayer_XAxis(); String googleBubbleDisplayer_YAxis(); String googleBubbleDisplayer_BubbleColor(); String googleBubbleDisplayer_BubbleSize(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/java/org/dashbuilder/renderer/c3/mutationobserver/MutationObserverFactory.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.mutationobserver; import javax.enterprise.context.ApplicationScoped; import elemental2.dom.MutationObserver; import elemental2.dom.MutationObserver.MutationObserverCallbackFn; import elemental2.dom.MutationObserverInit; @ApplicationScoped public class MutationObserverFactory { public MutationObserverInit mutationObserverInit() { return MutationObserverInit.create(); } public MutationObserver mutationObserver(MutationObserverCallbackFn callback) { return new MutationObserver(callback); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/C3Renderer.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/exports/json/countries.geo.json ================================================ {"type":"FeatureCollection","features":[ {"type":"Feature","id":"AFG","properties":{"name":"Afghanistan"},"geometry":{"type":"Polygon","coordinates":[[[61.210817,35.650072],[62.230651,35.270664],[62.984662,35.404041],[63.193538,35.857166],[63.982896,36.007957],[64.546479,36.312073],[64.746105,37.111818],[65.588948,37.305217],[65.745631,37.661164],[66.217385,37.39379],[66.518607,37.362784],[67.075782,37.356144],[67.83,37.144994],[68.135562,37.023115],[68.859446,37.344336],[69.196273,37.151144],[69.518785,37.608997],[70.116578,37.588223],[70.270574,37.735165],[70.376304,38.138396],[70.806821,38.486282],[71.348131,38.258905],[71.239404,37.953265],[71.541918,37.905774],[71.448693,37.065645],[71.844638,36.738171],[72.193041,36.948288],[72.63689,37.047558],[73.260056,37.495257],[73.948696,37.421566],[74.980002,37.41999],[75.158028,37.133031],[74.575893,37.020841],[74.067552,36.836176],[72.920025,36.720007],[71.846292,36.509942],[71.262348,36.074388],[71.498768,35.650563],[71.613076,35.153203],[71.115019,34.733126],[71.156773,34.348911],[70.881803,33.988856],[69.930543,34.02012],[70.323594,33.358533],[69.687147,33.105499],[69.262522,32.501944],[69.317764,31.901412],[68.926677,31.620189],[68.556932,31.71331],[67.792689,31.58293],[67.683394,31.303154],[66.938891,31.304911],[66.381458,30.738899],[66.346473,29.887943],[65.046862,29.472181],[64.350419,29.560031],[64.148002,29.340819],[63.550261,29.468331],[62.549857,29.318572],[60.874248,29.829239],[61.781222,30.73585],[61.699314,31.379506],[60.941945,31.548075],[60.863655,32.18292],[60.536078,32.981269],[60.9637,33.528832],[60.52843,33.676446],[60.803193,34.404102],[61.210817,35.650072]]]}}, {"type":"Feature","id":"AGO","properties":{"name":"Angola"},"geometry":{"type":"MultiPolygon","coordinates":[[[[16.326528,-5.87747],[16.57318,-6.622645],[16.860191,-7.222298],[17.089996,-7.545689],[17.47297,-8.068551],[18.134222,-7.987678],[18.464176,-7.847014],[19.016752,-7.988246],[19.166613,-7.738184],[19.417502,-7.155429],[20.037723,-7.116361],[20.091622,-6.94309],[20.601823,-6.939318],[20.514748,-7.299606],[21.728111,-7.290872],[21.746456,-7.920085],[21.949131,-8.305901],[21.801801,-8.908707],[21.875182,-9.523708],[22.208753,-9.894796],[22.155268,-11.084801],[22.402798,-10.993075],[22.837345,-11.017622],[23.456791,-10.867863],[23.912215,-10.926826],[24.017894,-11.237298],[23.904154,-11.722282],[24.079905,-12.191297],[23.930922,-12.565848],[24.016137,-12.911046],[21.933886,-12.898437],[21.887843,-16.08031],[22.562478,-16.898451],[23.215048,-17.523116],[21.377176,-17.930636],[18.956187,-17.789095],[18.263309,-17.309951],[14.209707,-17.353101],[14.058501,-17.423381],[13.462362,-16.971212],[12.814081,-16.941343],[12.215461,-17.111668],[11.734199,-17.301889],[11.640096,-16.673142],[11.778537,-15.793816],[12.123581,-14.878316],[12.175619,-14.449144],[12.500095,-13.5477],[12.738479,-13.137906],[13.312914,-12.48363],[13.633721,-12.038645],[13.738728,-11.297863],[13.686379,-10.731076],[13.387328,-10.373578],[13.120988,-9.766897],[12.87537,-9.166934],[12.929061,-8.959091],[13.236433,-8.562629],[12.93304,-7.596539],[12.728298,-6.927122],[12.227347,-6.294448],[12.322432,-6.100092],[12.735171,-5.965682],[13.024869,-5.984389],[13.375597,-5.864241],[16.326528,-5.87747]]],[[[12.436688,-5.684304],[12.182337,-5.789931],[11.914963,-5.037987],[12.318608,-4.60623],[12.62076,-4.438023],[12.995517,-4.781103],[12.631612,-4.991271],[12.468004,-5.248362],[12.436688,-5.684304]]]]}}, {"type":"Feature","id":"ALB","properties":{"name":"Albania"},"geometry":{"type":"Polygon","coordinates":[[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]}}, {"type":"Feature","id":"ARE","properties":{"name":"United Arab Emirates"},"geometry":{"type":"Polygon","coordinates":[[[51.579519,24.245497],[51.757441,24.294073],[51.794389,24.019826],[52.577081,24.177439],[53.404007,24.151317],[54.008001,24.121758],[54.693024,24.797892],[55.439025,25.439145],[56.070821,26.055464],[56.261042,25.714606],[56.396847,24.924732],[55.886233,24.920831],[55.804119,24.269604],[55.981214,24.130543],[55.528632,23.933604],[55.525841,23.524869],[55.234489,23.110993],[55.208341,22.70833],[55.006803,22.496948],[52.000733,23.001154],[51.617708,24.014219],[51.579519,24.245497]]]}}, {"type":"Feature","id":"ARG","properties":{"name":"Argentina"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-65.5,-55.2],[-66.45,-55.25],[-66.95992,-54.89681],[-67.56244,-54.87001],[-68.63335,-54.8695],[-68.63401,-52.63637],[-68.25,-53.1],[-67.75,-53.85],[-66.45,-54.45],[-65.05,-54.7],[-65.5,-55.2]]],[[[-64.964892,-22.075862],[-64.377021,-22.798091],[-63.986838,-21.993644],[-62.846468,-22.034985],[-62.685057,-22.249029],[-60.846565,-23.880713],[-60.028966,-24.032796],[-58.807128,-24.771459],[-57.777217,-25.16234],[-57.63366,-25.603657],[-58.618174,-27.123719],[-57.60976,-27.395899],[-56.486702,-27.548499],[-55.695846,-27.387837],[-54.788795,-26.621786],[-54.625291,-25.739255],[-54.13005,-25.547639],[-53.628349,-26.124865],[-53.648735,-26.923473],[-54.490725,-27.474757],[-55.162286,-27.881915],[-56.2909,-28.852761],[-57.625133,-30.216295],[-57.874937,-31.016556],[-58.14244,-32.044504],[-58.132648,-33.040567],[-58.349611,-33.263189],[-58.427074,-33.909454],[-58.495442,-34.43149],[-57.22583,-35.288027],[-57.362359,-35.97739],[-56.737487,-36.413126],[-56.788285,-36.901572],[-57.749157,-38.183871],[-59.231857,-38.72022],[-61.237445,-38.928425],[-62.335957,-38.827707],[-62.125763,-39.424105],[-62.330531,-40.172586],[-62.145994,-40.676897],[-62.745803,-41.028761],[-63.770495,-41.166789],[-64.73209,-40.802677],[-65.118035,-41.064315],[-64.978561,-42.058001],[-64.303408,-42.359016],[-63.755948,-42.043687],[-63.458059,-42.563138],[-64.378804,-42.873558],[-65.181804,-43.495381],[-65.328823,-44.501366],[-65.565269,-45.036786],[-66.509966,-45.039628],[-67.293794,-45.551896],[-67.580546,-46.301773],[-66.597066,-47.033925],[-65.641027,-47.236135],[-65.985088,-48.133289],[-67.166179,-48.697337],[-67.816088,-49.869669],[-68.728745,-50.264218],[-69.138539,-50.73251],[-68.815561,-51.771104],[-68.149995,-52.349983],[-68.571545,-52.299444],[-69.498362,-52.142761],[-71.914804,-52.009022],[-72.329404,-51.425956],[-72.309974,-50.67701],[-72.975747,-50.74145],[-73.328051,-50.378785],[-73.415436,-49.318436],[-72.648247,-48.878618],[-72.331161,-48.244238],[-72.447355,-47.738533],[-71.917258,-46.884838],[-71.552009,-45.560733],[-71.659316,-44.973689],[-71.222779,-44.784243],[-71.329801,-44.407522],[-71.793623,-44.207172],[-71.464056,-43.787611],[-71.915424,-43.408565],[-72.148898,-42.254888],[-71.746804,-42.051386],[-71.915734,-40.832339],[-71.680761,-39.808164],[-71.413517,-38.916022],[-70.814664,-38.552995],[-71.118625,-37.576827],[-71.121881,-36.658124],[-70.364769,-36.005089],[-70.388049,-35.169688],[-69.817309,-34.193571],[-69.814777,-33.273886],[-70.074399,-33.09121],[-70.535069,-31.36501],[-69.919008,-30.336339],[-70.01355,-29.367923],[-69.65613,-28.459141],[-69.001235,-27.521214],[-68.295542,-26.89934],[-68.5948,-26.506909],[-68.386001,-26.185016],[-68.417653,-24.518555],[-67.328443,-24.025303],[-66.985234,-22.986349],[-67.106674,-22.735925],[-66.273339,-21.83231],[-64.964892,-22.075862]]]]}}, {"type":"Feature","id":"ARM","properties":{"name":"Armenia"},"geometry":{"type":"Polygon","coordinates":[[[43.582746,41.092143],[44.97248,41.248129],[45.179496,40.985354],[45.560351,40.81229],[45.359175,40.561504],[45.891907,40.218476],[45.610012,39.899994],[46.034534,39.628021],[46.483499,39.464155],[46.50572,38.770605],[46.143623,38.741201],[45.735379,39.319719],[45.739978,39.473999],[45.298145,39.471751],[45.001987,39.740004],[44.79399,39.713003],[44.400009,40.005],[43.656436,40.253564],[43.752658,40.740201],[43.582746,41.092143]]]}}, {"type":"Feature","id":"ATA","properties":{"name":"Antarctica"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-59.572095,-80.040179],[-59.865849,-80.549657],[-60.159656,-81.000327],[-62.255393,-80.863178],[-64.488125,-80.921934],[-65.741666,-80.588827],[-65.741666,-80.549657],[-66.290031,-80.255773],[-64.037688,-80.294944],[-61.883246,-80.39287],[-61.138976,-79.981371],[-60.610119,-79.628679],[-59.572095,-80.040179]]],[[[-159.208184,-79.497059],[-161.127601,-79.634209],[-162.439847,-79.281465],[-163.027408,-78.928774],[-163.066604,-78.869966],[-163.712896,-78.595667],[-163.105801,-78.223338],[-161.245113,-78.380176],[-160.246208,-78.693645],[-159.482405,-79.046338],[-159.208184,-79.497059]]],[[[-45.154758,-78.04707],[-43.920828,-78.478103],[-43.48995,-79.08556],[-43.372438,-79.516645],[-43.333267,-80.026123],[-44.880537,-80.339644],[-46.506174,-80.594357],[-48.386421,-80.829485],[-50.482107,-81.025442],[-52.851988,-80.966685],[-54.164259,-80.633528],[-53.987991,-80.222028],[-51.853134,-79.94773],[-50.991326,-79.614623],[-50.364595,-79.183487],[-49.914131,-78.811209],[-49.306959,-78.458569],[-48.660616,-78.047018],[-48.660616,-78.047019],[-48.151396,-78.04707],[-46.662857,-77.831476],[-45.154758,-78.04707]]],[[[-121.211511,-73.50099],[-119.918851,-73.657725],[-118.724143,-73.481353],[-119.292119,-73.834097],[-120.232217,-74.08881],[-121.62283,-74.010468],[-122.621735,-73.657778],[-122.621735,-73.657777],[-122.406245,-73.324619],[-121.211511,-73.50099]]],[[[-125.559566,-73.481353],[-124.031882,-73.873268],[-124.619469,-73.834097],[-125.912181,-73.736118],[-127.28313,-73.461769],[-127.28313,-73.461768],[-126.558472,-73.246226],[-125.559566,-73.481353]]],[[[-98.98155,-71.933334],[-97.884743,-72.070535],[-96.787937,-71.952971],[-96.20035,-72.521205],[-96.983765,-72.442864],[-98.198083,-72.482035],[-99.432013,-72.442864],[-100.783455,-72.50162],[-101.801868,-72.305663],[-102.330725,-71.894164],[-101.703967,-71.717792],[-100.430919,-71.854993],[-98.98155,-71.933334]]],[[[-68.451346,-70.955823],[-68.333834,-71.406493],[-68.510128,-71.798407],[-68.784297,-72.170736],[-69.959471,-72.307885],[-71.075889,-72.503842],[-72.388134,-72.484257],[-71.8985,-72.092343],[-73.073622,-72.229492],[-74.19004,-72.366693],[-74.953895,-72.072757],[-75.012625,-71.661258],[-73.915819,-71.269345],[-73.915819,-71.269344],[-73.230331,-71.15178],[-72.074717,-71.190951],[-71.780962,-70.681473],[-71.72218,-70.309196],[-71.741791,-69.505782],[-71.173815,-69.035475],[-70.253252,-68.87874],[-69.724447,-69.251017],[-69.489422,-69.623346],[-69.058518,-70.074016],[-68.725541,-70.505153],[-68.451346,-70.955823]]],[[[-58.614143,-64.152467],[-59.045073,-64.36801],[-59.789342,-64.211223],[-60.611928,-64.309202],[-61.297416,-64.54433],[-62.0221,-64.799094],[-62.51176,-65.09303],[-62.648858,-65.484942],[-62.590128,-65.857219],[-62.120079,-66.190326],[-62.805567,-66.425505],[-63.74569,-66.503847],[-64.294106,-66.837004],[-64.881693,-67.150474],[-65.508425,-67.58161],[-65.665082,-67.953887],[-65.312545,-68.365335],[-64.783715,-68.678908],[-63.961103,-68.913984],[-63.1973,-69.227556],[-62.785955,-69.619419],[-62.570516,-69.991747],[-62.276736,-70.383661],[-61.806661,-70.716768],[-61.512906,-71.089045],[-61.375809,-72.010074],[-61.081977,-72.382351],[-61.003661,-72.774265],[-60.690269,-73.166179],[-60.827367,-73.695242],[-61.375809,-74.106742],[-61.96337,-74.439848],[-63.295201,-74.576997],[-63.74569,-74.92974],[-64.352836,-75.262847],[-65.860987,-75.635124],[-67.192818,-75.79191],[-68.446282,-76.007452],[-69.797724,-76.222995],[-70.600724,-76.634494],[-72.206776,-76.673665],[-73.969536,-76.634494],[-75.555977,-76.712887],[-77.24037,-76.712887],[-76.926979,-77.104802],[-75.399294,-77.28107],[-74.282876,-77.55542],[-73.656119,-77.908112],[-74.772536,-78.221633],[-76.4961,-78.123654],[-77.925858,-78.378419],[-77.984666,-78.789918],[-78.023785,-79.181833],[-76.848637,-79.514939],[-76.633224,-79.887216],[-75.360097,-80.259545],[-73.244852,-80.416331],[-71.442946,-80.69063],[-70.013163,-81.004151],[-68.191646,-81.317672],[-65.704279,-81.474458],[-63.25603,-81.748757],[-61.552026,-82.042692],[-59.691416,-82.37585],[-58.712121,-82.846106],[-58.222487,-83.218434],[-57.008117,-82.865691],[-55.362894,-82.571755],[-53.619771,-82.258235],[-51.543644,-82.003521],[-49.76135,-81.729171],[-47.273931,-81.709586],[-44.825708,-81.846735],[-42.808363,-82.081915],[-42.16202,-81.65083],[-40.771433,-81.356894],[-38.244818,-81.337309],[-36.26667,-81.121715],[-34.386397,-80.906172],[-32.310296,-80.769023],[-30.097098,-80.592651],[-28.549802,-80.337938],[-29.254901,-79.985195],[-29.685805,-79.632503],[-29.685805,-79.260226],[-31.624808,-79.299397],[-33.681324,-79.456132],[-35.639912,-79.456132],[-35.914107,-79.083855],[-35.77701,-78.339248],[-35.326546,-78.123654],[-33.896763,-77.888526],[-32.212369,-77.65345],[-30.998051,-77.359515],[-29.783732,-77.065579],[-28.882779,-76.673665],[-27.511752,-76.497345],[-26.160336,-76.360144],[-25.474822,-76.281803],[-23.927552,-76.24258],[-22.458598,-76.105431],[-21.224694,-75.909474],[-20.010375,-75.674346],[-18.913543,-75.439218],[-17.522982,-75.125698],[-16.641589,-74.79254],[-15.701491,-74.498604],[-15.40771,-74.106742],[-16.46532,-73.871614],[-16.112784,-73.460114],[-15.446855,-73.146542],[-14.408805,-72.950585],[-13.311973,-72.715457],[-12.293508,-72.401936],[-11.510067,-72.010074],[-11.020433,-71.539767],[-10.295774,-71.265416],[-9.101015,-71.324224],[-8.611381,-71.65733],[-7.416622,-71.696501],[-7.377451,-71.324224],[-6.868232,-70.93231],[-5.790985,-71.030289],[-5.536375,-71.402617],[-4.341667,-71.461373],[-3.048981,-71.285053],[-1.795492,-71.167438],[-0.659489,-71.226246],[-0.228637,-71.637745],[0.868195,-71.304639],[1.886686,-71.128267],[3.022638,-70.991118],[4.139055,-70.853917],[5.157546,-70.618789],[6.273912,-70.462055],[7.13572,-70.246512],[7.742866,-69.893769],[8.48711,-70.148534],[9.525135,-70.011333],[10.249845,-70.48164],[10.817821,-70.834332],[11.953824,-70.638375],[12.404287,-70.246512],[13.422778,-69.972162],[14.734998,-70.030918],[15.126757,-70.403247],[15.949342,-70.030918],[17.026589,-69.913354],[18.201711,-69.874183],[19.259373,-69.893769],[20.375739,-70.011333],[21.452985,-70.07014],[21.923034,-70.403247],[22.569403,-70.697182],[23.666184,-70.520811],[24.841357,-70.48164],[25.977309,-70.48164],[27.093726,-70.462055],[28.09258,-70.324854],[29.150242,-70.20729],[30.031583,-69.93294],[30.971733,-69.75662],[31.990172,-69.658641],[32.754053,-69.384291],[33.302443,-68.835642],[33.870419,-68.502588],[34.908495,-68.659271],[35.300202,-69.012014],[36.16201,-69.247142],[37.200035,-69.168748],[37.905108,-69.52144],[38.649404,-69.776205],[39.667894,-69.541077],[40.020431,-69.109941],[40.921358,-68.933621],[41.959434,-68.600514],[42.938702,-68.463313],[44.113876,-68.267408],[44.897291,-68.051866],[45.719928,-67.816738],[46.503343,-67.601196],[47.44344,-67.718759],[48.344419,-67.366068],[48.990736,-67.091718],[49.930885,-67.111303],[50.753471,-66.876175],[50.949325,-66.523484],[51.791547,-66.249133],[52.614133,-66.053176],[53.613038,-65.89639],[54.53355,-65.818049],[55.414943,-65.876805],[56.355041,-65.974783],[57.158093,-66.249133],[57.255968,-66.680218],[58.137361,-67.013324],[58.744508,-67.287675],[59.939318,-67.405239],[60.605221,-67.679589],[61.427806,-67.953887],[62.387489,-68.012695],[63.19049,-67.816738],[64.052349,-67.405239],[64.992447,-67.620729],[65.971715,-67.738345],[66.911864,-67.855909],[67.891133,-67.934302],[68.890038,-67.934302],[69.712624,-68.972791],[69.673453,-69.227556],[69.555941,-69.678226],[68.596258,-69.93294],[67.81274,-70.305268],[67.949889,-70.697182],[69.066307,-70.677545],[68.929157,-71.069459],[68.419989,-71.441788],[67.949889,-71.853287],[68.71377,-72.166808],[69.869307,-72.264787],[71.024895,-72.088415],[71.573285,-71.696501],[71.906288,-71.324224],[72.454627,-71.010703],[73.08141,-70.716768],[73.33602,-70.364024],[73.864877,-69.874183],[74.491557,-69.776205],[75.62756,-69.737034],[76.626465,-69.619419],[77.644904,-69.462684],[78.134539,-69.07077],[78.428371,-68.698441],[79.113859,-68.326216],[80.093127,-68.071503],[80.93535,-67.875546],[81.483792,-67.542388],[82.051767,-67.366068],[82.776426,-67.209282],[83.775331,-67.30726],[84.676206,-67.209282],[85.655527,-67.091718],[86.752359,-67.150474],[87.477017,-66.876175],[87.986289,-66.209911],[88.358411,-66.484261],[88.828408,-66.954568],[89.67063,-67.150474],[90.630365,-67.228867],[91.5901,-67.111303],[92.608539,-67.189696],[93.548637,-67.209282],[94.17542,-67.111303],[95.017591,-67.170111],[95.781472,-67.385653],[96.682399,-67.248504],[97.759646,-67.248504],[98.68021,-67.111303],[99.718182,-67.248504],[100.384188,-66.915346],[100.893356,-66.58224],[101.578896,-66.30789],[102.832411,-65.563284],[103.478676,-65.700485],[104.242557,-65.974783],[104.90846,-66.327527],[106.181561,-66.934931],[107.160881,-66.954568],[108.081393,-66.954568],[109.15864,-66.837004],[110.235835,-66.699804],[111.058472,-66.425505],[111.74396,-66.13157],[112.860378,-66.092347],[113.604673,-65.876805],[114.388088,-66.072762],[114.897308,-66.386283],[115.602381,-66.699804],[116.699161,-66.660633],[117.384701,-66.915346],[118.57946,-67.170111],[119.832924,-67.268089],[120.871,-67.189696],[121.654415,-66.876175],[122.320369,-66.562654],[123.221296,-66.484261],[124.122274,-66.621462],[125.160247,-66.719389],[126.100396,-66.562654],[127.001427,-66.562654],[127.882768,-66.660633],[128.80328,-66.758611],[129.704259,-66.58224],[130.781454,-66.425505],[131.799945,-66.386283],[132.935896,-66.386283],[133.85646,-66.288304],[134.757387,-66.209963],[135.031582,-65.72007],[135.070753,-65.308571],[135.697485,-65.582869],[135.873805,-66.033591],[136.206705,-66.44509],[136.618049,-66.778197],[137.460271,-66.954568],[138.596223,-66.895761],[139.908442,-66.876175],[140.809421,-66.817367],[142.121692,-66.817367],[143.061842,-66.797782],[144.374061,-66.837004],[145.490427,-66.915346],[146.195552,-67.228867],[145.999699,-67.601196],[146.646067,-67.895131],[147.723263,-68.130259],[148.839629,-68.385024],[150.132314,-68.561292],[151.483705,-68.71813],[152.502247,-68.874813],[153.638199,-68.894502],[154.284567,-68.561292],[155.165857,-68.835642],[155.92979,-69.149215],[156.811132,-69.384291],[158.025528,-69.482269],[159.181013,-69.599833],[159.670699,-69.991747],[160.80665,-70.226875],[161.570479,-70.579618],[162.686897,-70.736353],[163.842434,-70.716768],[164.919681,-70.775524],[166.11444,-70.755938],[167.309095,-70.834332],[168.425616,-70.971481],[169.463589,-71.20666],[170.501665,-71.402617],[171.20679,-71.696501],[171.089227,-72.088415],[170.560422,-72.441159],[170.109958,-72.891829],[169.75737,-73.24452],[169.287321,-73.65602],[167.975101,-73.812806],[167.387489,-74.165498],[166.094803,-74.38104],[165.644391,-74.772954],[164.958851,-75.145283],[164.234193,-75.458804],[163.822797,-75.870303],[163.568239,-76.24258],[163.47026,-76.693302],[163.489897,-77.065579],[164.057873,-77.457442],[164.273363,-77.82977],[164.743464,-78.182514],[166.604126,-78.319611],[166.995781,-78.750748],[165.193876,-78.907483],[163.666217,-79.123025],[161.766385,-79.162248],[160.924162,-79.730482],[160.747894,-80.200737],[160.316964,-80.573066],[159.788211,-80.945395],[161.120016,-81.278501],[161.629287,-81.690001],[162.490992,-82.062278],[163.705336,-82.395435],[165.095949,-82.708956],[166.604126,-83.022477],[168.895665,-83.335998],[169.404782,-83.825891],[172.283934,-84.041433],[172.477049,-84.117914],[173.224083,-84.41371],[175.985672,-84.158997],[178.277212,-84.472518],[180,-84.71338],[-179.942499,-84.721443],[-179.058677,-84.139412],[-177.256772,-84.452933],[-177.140807,-84.417941],[-176.084673,-84.099259],[-175.947235,-84.110449],[-175.829882,-84.117914],[-174.382503,-84.534323],[-173.116559,-84.117914],[-172.889106,-84.061019],[-169.951223,-83.884647],[-168.999989,-84.117914],[-168.530199,-84.23739],[-167.022099,-84.570497],[-164.182144,-84.82521],[-161.929775,-85.138731],[-158.07138,-85.37391],[-155.192253,-85.09956],[-150.942099,-85.295517],[-148.533073,-85.609038],[-145.888918,-85.315102],[-143.107718,-85.040752],[-142.892279,-84.570497],[-146.829068,-84.531274],[-150.060732,-84.296146],[-150.902928,-83.904232],[-153.586201,-83.68869],[-153.409907,-83.23802],[-153.037759,-82.82652],[-152.665637,-82.454192],[-152.861517,-82.042692],[-154.526299,-81.768394],[-155.29018,-81.41565],[-156.83745,-81.102129],[-154.408787,-81.160937],[-152.097662,-81.004151],[-150.648293,-81.337309],[-148.865998,-81.043373],[-147.22075,-80.671045],[-146.417749,-80.337938],[-146.770286,-79.926439],[-148.062947,-79.652089],[-149.531901,-79.358205],[-151.588416,-79.299397],[-153.390322,-79.162248],[-155.329376,-79.064269],[-155.975668,-78.69194],[-157.268302,-78.378419],[-158.051768,-78.025676],[-158.365134,-76.889207],[-157.875474,-76.987238],[-156.974573,-77.300759],[-155.329376,-77.202728],[-153.742832,-77.065579],[-152.920247,-77.496664],[-151.33378,-77.398737],[-150.00195,-77.183143],[-148.748486,-76.908845],[-147.612483,-76.575738],[-146.104409,-76.47776],[-146.143528,-76.105431],[-146.496091,-75.733154],[-146.20231,-75.380411],[-144.909624,-75.204039],[-144.322037,-75.537197],[-142.794353,-75.34124],[-141.638764,-75.086475],[-140.209007,-75.06689],[-138.85759,-74.968911],[-137.5062,-74.733783],[-136.428901,-74.518241],[-135.214583,-74.302699],[-134.431194,-74.361455],[-133.745654,-74.439848],[-132.257168,-74.302699],[-130.925311,-74.479019],[-129.554284,-74.459433],[-128.242038,-74.322284],[-126.890622,-74.420263],[-125.402082,-74.518241],[-124.011496,-74.479019],[-122.562152,-74.498604],[-121.073613,-74.518241],[-119.70256,-74.479019],[-118.684145,-74.185083],[-117.469801,-74.028348],[-116.216312,-74.243891],[-115.021552,-74.067519],[-113.944331,-73.714828],[-113.297988,-74.028348],[-112.945452,-74.38104],[-112.299083,-74.714198],[-111.261059,-74.420263],[-110.066325,-74.79254],[-108.714909,-74.910103],[-107.559346,-75.184454],[-106.149148,-75.125698],[-104.876074,-74.949326],[-103.367949,-74.988497],[-102.016507,-75.125698],[-100.645531,-75.302018],[-100.1167,-74.870933],[-100.763043,-74.537826],[-101.252703,-74.185083],[-102.545337,-74.106742],[-103.113313,-73.734413],[-103.328752,-73.362084],[-103.681289,-72.61753],[-102.917485,-72.754679],[-101.60524,-72.813436],[-100.312528,-72.754679],[-99.13738,-72.911414],[-98.118889,-73.20535],[-97.688037,-73.558041],[-96.336595,-73.616849],[-95.043961,-73.4797],[-93.672907,-73.283743],[-92.439003,-73.166179],[-91.420564,-73.401307],[-90.088733,-73.322914],[-89.226951,-72.558722],[-88.423951,-73.009393],[-87.268337,-73.185764],[-86.014822,-73.087786],[-85.192236,-73.4797],[-83.879991,-73.518871],[-82.665646,-73.636434],[-81.470913,-73.851977],[-80.687447,-73.4797],[-80.295791,-73.126956],[-79.296886,-73.518871],[-77.925858,-73.420892],[-76.907367,-73.636434],[-76.221879,-73.969541],[-74.890049,-73.871614],[-73.852024,-73.65602],[-72.833533,-73.401307],[-71.619215,-73.264157],[-70.209042,-73.146542],[-68.935916,-73.009393],[-67.956622,-72.79385],[-67.369061,-72.480329],[-67.134036,-72.049244],[-67.251548,-71.637745],[-67.56494,-71.245831],[-67.917477,-70.853917],[-68.230843,-70.462055],[-68.485452,-70.109311],[-68.544209,-69.717397],[-68.446282,-69.325535],[-67.976233,-68.953206],[-67.5845,-68.541707],[-67.427843,-68.149844],[-67.62367,-67.718759],[-67.741183,-67.326845],[-67.251548,-66.876175],[-66.703184,-66.58224],[-66.056815,-66.209963],[-65.371327,-65.89639],[-64.568276,-65.602506],[-64.176542,-65.171423],[-63.628152,-64.897073],[-63.001394,-64.642308],[-62.041686,-64.583552],[-61.414928,-64.270031],[-60.709855,-64.074074],[-59.887269,-63.95651],[-59.162585,-63.701745],[-58.594557,-63.388224],[-57.811143,-63.27066],[-57.223582,-63.525425],[-57.59573,-63.858532],[-58.614143,-64.152467]]]]}}, {"type":"Feature","id":"ATF","properties":{"name":"French Southern and Antarctic Lands"},"geometry":{"type":"Polygon","coordinates":[[[68.935,-48.625],[69.58,-48.94],[70.525,-49.065],[70.56,-49.255],[70.28,-49.71],[68.745,-49.775],[68.72,-49.2425],[68.8675,-48.83],[68.935,-48.625]]]}}, {"type":"Feature","id":"AUS","properties":{"name":"Australia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[145.397978,-40.792549],[146.364121,-41.137695],[146.908584,-41.000546],[147.689259,-40.808258],[148.289068,-40.875438],[148.359865,-42.062445],[148.017301,-42.407024],[147.914052,-43.211522],[147.564564,-42.937689],[146.870343,-43.634597],[146.663327,-43.580854],[146.048378,-43.549745],[145.43193,-42.693776],[145.29509,-42.03361],[144.718071,-41.162552],[144.743755,-40.703975],[145.397978,-40.792549]]],[[[143.561811,-13.763656],[143.922099,-14.548311],[144.563714,-14.171176],[144.894908,-14.594458],[145.374724,-14.984976],[145.271991,-15.428205],[145.48526,-16.285672],[145.637033,-16.784918],[145.888904,-16.906926],[146.160309,-17.761655],[146.063674,-18.280073],[146.387478,-18.958274],[147.471082,-19.480723],[148.177602,-19.955939],[148.848414,-20.39121],[148.717465,-20.633469],[149.28942,-21.260511],[149.678337,-22.342512],[150.077382,-22.122784],[150.482939,-22.556142],[150.727265,-22.402405],[150.899554,-23.462237],[151.609175,-24.076256],[152.07354,-24.457887],[152.855197,-25.267501],[153.136162,-26.071173],[153.161949,-26.641319],[153.092909,-27.2603],[153.569469,-28.110067],[153.512108,-28.995077],[153.339095,-29.458202],[153.069241,-30.35024],[153.089602,-30.923642],[152.891578,-31.640446],[152.450002,-32.550003],[151.709117,-33.041342],[151.343972,-33.816023],[151.010555,-34.31036],[150.714139,-35.17346],[150.32822,-35.671879],[150.075212,-36.420206],[149.946124,-37.109052],[149.997284,-37.425261],[149.423882,-37.772681],[148.304622,-37.809061],[147.381733,-38.219217],[146.922123,-38.606532],[146.317922,-39.035757],[145.489652,-38.593768],[144.876976,-38.417448],[145.032212,-37.896188],[144.485682,-38.085324],[143.609974,-38.809465],[142.745427,-38.538268],[142.17833,-38.380034],[141.606582,-38.308514],[140.638579,-38.019333],[139.992158,-37.402936],[139.806588,-36.643603],[139.574148,-36.138362],[139.082808,-35.732754],[138.120748,-35.612296],[138.449462,-35.127261],[138.207564,-34.384723],[137.71917,-35.076825],[136.829406,-35.260535],[137.352371,-34.707339],[137.503886,-34.130268],[137.890116,-33.640479],[137.810328,-32.900007],[136.996837,-33.752771],[136.372069,-34.094766],[135.989043,-34.890118],[135.208213,-34.47867],[135.239218,-33.947953],[134.613417,-33.222778],[134.085904,-32.848072],[134.273903,-32.617234],[132.990777,-32.011224],[132.288081,-31.982647],[131.326331,-31.495803],[129.535794,-31.590423],[128.240938,-31.948489],[127.102867,-32.282267],[126.148714,-32.215966],[125.088623,-32.728751],[124.221648,-32.959487],[124.028947,-33.483847],[123.659667,-33.890179],[122.811036,-33.914467],[122.183064,-34.003402],[121.299191,-33.821036],[120.580268,-33.930177],[119.893695,-33.976065],[119.298899,-34.509366],[119.007341,-34.464149],[118.505718,-34.746819],[118.024972,-35.064733],[117.295507,-35.025459],[116.625109,-35.025097],[115.564347,-34.386428],[115.026809,-34.196517],[115.048616,-33.623425],[115.545123,-33.487258],[115.714674,-33.259572],[115.679379,-32.900369],[115.801645,-32.205062],[115.689611,-31.612437],[115.160909,-30.601594],[114.997043,-30.030725],[115.040038,-29.461095],[114.641974,-28.810231],[114.616498,-28.516399],[114.173579,-28.118077],[114.048884,-27.334765],[113.477498,-26.543134],[113.338953,-26.116545],[113.778358,-26.549025],[113.440962,-25.621278],[113.936901,-25.911235],[114.232852,-26.298446],[114.216161,-25.786281],[113.721255,-24.998939],[113.625344,-24.683971],[113.393523,-24.384764],[113.502044,-23.80635],[113.706993,-23.560215],[113.843418,-23.059987],[113.736552,-22.475475],[114.149756,-21.755881],[114.225307,-22.517488],[114.647762,-21.82952],[115.460167,-21.495173],[115.947373,-21.068688],[116.711615,-20.701682],[117.166316,-20.623599],[117.441545,-20.746899],[118.229559,-20.374208],[118.836085,-20.263311],[118.987807,-20.044203],[119.252494,-19.952942],[119.805225,-19.976506],[120.85622,-19.683708],[121.399856,-19.239756],[121.655138,-18.705318],[122.241665,-18.197649],[122.286624,-17.798603],[122.312772,-17.254967],[123.012574,-16.4052],[123.433789,-17.268558],[123.859345,-17.069035],[123.503242,-16.596506],[123.817073,-16.111316],[124.258287,-16.327944],[124.379726,-15.56706],[124.926153,-15.0751],[125.167275,-14.680396],[125.670087,-14.51007],[125.685796,-14.230656],[126.125149,-14.347341],[126.142823,-14.095987],[126.582589,-13.952791],[127.065867,-13.817968],[127.804633,-14.276906],[128.35969,-14.86917],[128.985543,-14.875991],[129.621473,-14.969784],[129.4096,-14.42067],[129.888641,-13.618703],[130.339466,-13.357376],[130.183506,-13.10752],[130.617795,-12.536392],[131.223495,-12.183649],[131.735091,-12.302453],[132.575298,-12.114041],[132.557212,-11.603012],[131.824698,-11.273782],[132.357224,-11.128519],[133.019561,-11.376411],[133.550846,-11.786515],[134.393068,-12.042365],[134.678632,-11.941183],[135.298491,-12.248606],[135.882693,-11.962267],[136.258381,-12.049342],[136.492475,-11.857209],[136.95162,-12.351959],[136.685125,-12.887223],[136.305407,-13.29123],[135.961758,-13.324509],[136.077617,-13.724278],[135.783836,-14.223989],[135.428664,-14.715432],[135.500184,-14.997741],[136.295175,-15.550265],[137.06536,-15.870762],[137.580471,-16.215082],[138.303217,-16.807604],[138.585164,-16.806622],[139.108543,-17.062679],[139.260575,-17.371601],[140.215245,-17.710805],[140.875463,-17.369069],[141.07111,-16.832047],[141.274095,-16.38887],[141.398222,-15.840532],[141.702183,-15.044921],[141.56338,-14.561333],[141.63552,-14.270395],[141.519869,-13.698078],[141.65092,-12.944688],[141.842691,-12.741548],[141.68699,-12.407614],[141.928629,-11.877466],[142.118488,-11.328042],[142.143706,-11.042737],[142.51526,-10.668186],[142.79731,-11.157355],[142.866763,-11.784707],[143.115947,-11.90563],[143.158632,-12.325656],[143.522124,-12.834358],[143.597158,-13.400422],[143.561811,-13.763656]]]]}}, {"type":"Feature","id":"AUT","properties":{"name":"Austria"},"geometry":{"type":"Polygon","coordinates":[[[16.979667,48.123497],[16.903754,47.714866],[16.340584,47.712902],[16.534268,47.496171],[16.202298,46.852386],[16.011664,46.683611],[15.137092,46.658703],[14.632472,46.431817],[13.806475,46.509306],[12.376485,46.767559],[12.153088,47.115393],[11.164828,46.941579],[11.048556,46.751359],[10.442701,46.893546],[9.932448,46.920728],[9.47997,47.10281],[9.632932,47.347601],[9.594226,47.525058],[9.896068,47.580197],[10.402084,47.302488],[10.544504,47.566399],[11.426414,47.523766],[12.141357,47.703083],[12.62076,47.672388],[12.932627,47.467646],[13.025851,47.637584],[12.884103,48.289146],[13.243357,48.416115],[13.595946,48.877172],[14.338898,48.555305],[14.901447,48.964402],[15.253416,49.039074],[16.029647,48.733899],[16.499283,48.785808],[16.960288,48.596982],[16.879983,48.470013],[16.979667,48.123497]]]}}, {"type":"Feature","id":"AZE","properties":{"name":"Azerbaijan"},"geometry":{"type":"MultiPolygon","coordinates":[[[[45.001987,39.740004],[45.298145,39.471751],[45.739978,39.473999],[45.735379,39.319719],[46.143623,38.741201],[45.457722,38.874139],[44.952688,39.335765],[44.79399,39.713003],[45.001987,39.740004]]],[[[47.373315,41.219732],[47.815666,41.151416],[47.987283,41.405819],[48.584353,41.80887],[49.110264,41.282287],[49.618915,40.572924],[50.08483,40.526157],[50.392821,40.256561],[49.569202,40.176101],[49.395259,39.399482],[49.223228,39.049219],[48.856532,38.815486],[48.883249,38.320245],[48.634375,38.270378],[48.010744,38.794015],[48.355529,39.288765],[48.060095,39.582235],[47.685079,39.508364],[46.50572,38.770605],[46.483499,39.464155],[46.034534,39.628021],[45.610012,39.899994],[45.891907,40.218476],[45.359175,40.561504],[45.560351,40.81229],[45.179496,40.985354],[44.97248,41.248129],[45.217426,41.411452],[45.962601,41.123873],[46.501637,41.064445],[46.637908,41.181673],[46.145432,41.722802],[46.404951,41.860675],[46.686071,41.827137],[47.373315,41.219732]]]]}}, {"type":"Feature","id":"BDI","properties":{"name":"Burundi"},"geometry":{"type":"Polygon","coordinates":[[[29.339998,-4.499983],[29.276384,-3.293907],[29.024926,-2.839258],[29.632176,-2.917858],[29.938359,-2.348487],[30.469696,-2.413858],[30.527677,-2.807632],[30.743013,-3.034285],[30.752263,-3.35933],[30.50556,-3.568567],[30.116333,-4.090138],[29.753512,-4.452389],[29.339998,-4.499983]]]}}, {"type":"Feature","id":"BEL","properties":{"name":"Belgium"},"geometry":{"type":"Polygon","coordinates":[[[3.314971,51.345781],[4.047071,51.267259],[4.973991,51.475024],[5.606976,51.037298],[6.156658,50.803721],[6.043073,50.128052],[5.782417,50.090328],[5.674052,49.529484],[4.799222,49.985373],[4.286023,49.907497],[3.588184,50.378992],[3.123252,50.780363],[2.658422,50.796848],[2.513573,51.148506],[3.314971,51.345781]]]}}, {"type":"Feature","id":"BEN","properties":{"name":"Benin"},"geometry":{"type":"Polygon","coordinates":[[[2.691702,6.258817],[1.865241,6.142158],[1.618951,6.832038],[1.664478,9.12859],[1.463043,9.334624],[1.425061,9.825395],[1.077795,10.175607],[0.772336,10.470808],[0.899563,10.997339],[1.24347,11.110511],[1.447178,11.547719],[1.935986,11.64115],[2.154474,11.94015],[2.490164,12.233052],[2.848643,12.235636],[3.61118,11.660167],[3.572216,11.327939],[3.797112,10.734746],[3.60007,10.332186],[3.705438,10.06321],[3.220352,9.444153],[2.912308,9.137608],[2.723793,8.506845],[2.749063,7.870734],[2.691702,6.258817]]]}}, {"type":"Feature","id":"BFA","properties":{"name":"Burkina Faso"},"geometry":{"type":"Polygon","coordinates":[[[-2.827496,9.642461],[-3.511899,9.900326],[-3.980449,9.862344],[-4.330247,9.610835],[-4.779884,9.821985],[-4.954653,10.152714],[-5.404342,10.370737],[-5.470565,10.95127],[-5.197843,11.375146],[-5.220942,11.713859],[-4.427166,12.542646],[-4.280405,13.228444],[-4.006391,13.472485],[-3.522803,13.337662],[-3.103707,13.541267],[-2.967694,13.79815],[-2.191825,14.246418],[-2.001035,14.559008],[-1.066363,14.973815],[-0.515854,15.116158],[-0.266257,14.924309],[0.374892,14.928908],[0.295646,14.444235],[0.429928,13.988733],[0.993046,13.33575],[1.024103,12.851826],[2.177108,12.625018],[2.154474,11.94015],[1.935986,11.64115],[1.447178,11.547719],[1.24347,11.110511],[0.899563,10.997339],[0.023803,11.018682],[-0.438702,11.098341],[-0.761576,10.93693],[-1.203358,11.009819],[-2.940409,10.96269],[-2.963896,10.395335],[-2.827496,9.642461]]]}}, {"type":"Feature","id":"BGD","properties":{"name":"Bangladesh"},"geometry":{"type":"Polygon","coordinates":[[[92.672721,22.041239],[92.652257,21.324048],[92.303234,21.475485],[92.368554,20.670883],[92.082886,21.192195],[92.025215,21.70157],[91.834891,22.182936],[91.417087,22.765019],[90.496006,22.805017],[90.586957,22.392794],[90.272971,21.836368],[89.847467,22.039146],[89.70205,21.857116],[89.418863,21.966179],[89.031961,22.055708],[88.876312,22.879146],[88.52977,23.631142],[88.69994,24.233715],[88.084422,24.501657],[88.306373,24.866079],[88.931554,25.238692],[88.209789,25.768066],[88.563049,26.446526],[89.355094,26.014407],[89.832481,25.965082],[89.920693,25.26975],[90.872211,25.132601],[91.799596,25.147432],[92.376202,24.976693],[91.915093,24.130414],[91.46773,24.072639],[91.158963,23.503527],[91.706475,22.985264],[91.869928,23.624346],[92.146035,23.627499],[92.672721,22.041239]]]}}, {"type":"Feature","id":"BGR","properties":{"name":"Bulgaria"},"geometry":{"type":"Polygon","coordinates":[[[22.65715,44.234923],[22.944832,43.823785],[23.332302,43.897011],[24.100679,43.741051],[25.569272,43.688445],[26.065159,43.943494],[27.2424,44.175986],[27.970107,43.812468],[28.558081,43.707462],[28.039095,43.293172],[27.673898,42.577892],[27.99672,42.007359],[27.135739,42.141485],[26.117042,41.826905],[26.106138,41.328899],[25.197201,41.234486],[24.492645,41.583896],[23.692074,41.309081],[22.952377,41.337994],[22.881374,41.999297],[22.380526,42.32026],[22.545012,42.461362],[22.436595,42.580321],[22.604801,42.898519],[22.986019,43.211161],[22.500157,43.642814],[22.410446,44.008063],[22.65715,44.234923]]]}}, {"type":"Feature","id":"BHS","properties":{"name":"The Bahamas"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-77.53466,23.75975],[-77.78,23.71],[-78.03405,24.28615],[-78.40848,24.57564],[-78.19087,25.2103],[-77.89,25.17],[-77.54,24.34],[-77.53466,23.75975]]],[[[-77.82,26.58],[-78.91,26.42],[-78.98,26.79],[-78.51,26.87],[-77.85,26.84],[-77.82,26.58]]],[[[-77,26.59],[-77.17255,25.87918],[-77.35641,26.00735],[-77.34,26.53],[-77.78802,26.92516],[-77.79,27.04],[-77,26.59]]]]}}, {"type":"Feature","id":"BIH","properties":{"name":"Bosnia and Herzegovina"},"geometry":{"type":"Polygon","coordinates":[[[19.005486,44.860234],[19.36803,44.863],[19.11761,44.42307],[19.59976,44.03847],[19.454,43.5681],[19.21852,43.52384],[19.03165,43.43253],[18.70648,43.20011],[18.56,42.65],[17.674922,43.028563],[17.297373,43.446341],[16.916156,43.667722],[16.456443,44.04124],[16.23966,44.351143],[15.750026,44.818712],[15.959367,45.233777],[16.318157,45.004127],[16.534939,45.211608],[17.002146,45.233777],[17.861783,45.06774],[18.553214,45.08159],[19.005486,44.860234]]]}}, {"type":"Feature","id":"BLR","properties":{"name":"Belarus"},"geometry":{"type":"Polygon","coordinates":[[[23.484128,53.912498],[24.450684,53.905702],[25.536354,54.282423],[25.768433,54.846963],[26.588279,55.167176],[26.494331,55.615107],[27.10246,55.783314],[28.176709,56.16913],[29.229513,55.918344],[29.371572,55.670091],[29.896294,55.789463],[30.873909,55.550976],[30.971836,55.081548],[30.757534,54.811771],[31.384472,54.157056],[31.791424,53.974639],[31.731273,53.794029],[32.405599,53.618045],[32.693643,53.351421],[32.304519,53.132726],[31.497644,53.167427],[31.305201,53.073996],[31.540018,52.742052],[31.785998,52.101678],[30.927549,52.042353],[30.619454,51.822806],[30.555117,51.319503],[30.157364,51.416138],[29.254938,51.368234],[28.992835,51.602044],[28.617613,51.427714],[28.241615,51.572227],[27.454066,51.592303],[26.337959,51.832289],[25.327788,51.910656],[24.553106,51.888461],[24.005078,51.617444],[23.527071,51.578454],[23.508002,52.023647],[23.199494,52.486977],[23.799199,52.691099],[23.804935,53.089731],[23.527536,53.470122],[23.484128,53.912498]]]}}, {"type":"Feature","id":"BLZ","properties":{"name":"Belize"},"geometry":{"type":"Polygon","coordinates":[[[-89.14308,17.808319],[-89.150909,17.955468],[-89.029857,18.001511],[-88.848344,17.883198],[-88.490123,18.486831],[-88.300031,18.499982],[-88.296336,18.353273],[-88.106813,18.348674],[-88.123479,18.076675],[-88.285355,17.644143],[-88.197867,17.489475],[-88.302641,17.131694],[-88.239518,17.036066],[-88.355428,16.530774],[-88.551825,16.265467],[-88.732434,16.233635],[-88.930613,15.887273],[-89.229122,15.886938],[-89.150806,17.015577],[-89.14308,17.808319]]]}}, {"type":"Feature","id":"BMU","properties":{"name":"Bermuda"},"geometry":{"type":"Polygon","coordinates":[[[-64.7799734332998,32.3072000581802],[-64.7873319183061,32.3039237143428],[-64.7946942710173,32.3032682700388],[-64.8094297981283,32.3098175728414],[-64.8167896352437,32.3058845718466],[-64.8101968029642,32.3022833180511],[-64.7962291465484,32.2934409732427],[-64.7815086336978,32.2868973114514],[-64.7997025513437,32.2796896417328],[-64.8066707691087,32.2747767569465],[-64.8225587873683,32.2669111289395],[-64.8287548840306,32.2669075473817],[-64.8306732143498,32.2583944840235],[-64.8399924854972,32.254782282336],[-64.8566090462354,32.2547740387514],[-64.8682296789446,32.2616393614322],[-64.8628241459563,32.2724481933959],[-64.8748651338951,32.2757120264753],[-64.8717752856644,32.2819371582026],[-64.8671422127295,32.2930760547989],[-64.8559068764437,32.2960321186471],[-64.8597429072279,32.3015842021933],[-64.8439233486717,32.3140553852543],[-64.8350242329311,32.3242161760006],[-64.8338690593672,32.3294587561557],[-64.8520298651164,32.3110911879954],[-64.8635922932573,32.3048469433363],[-64.8686668994079,32.30910745083],[-64.8721354593415,32.3041908606301],[-64.8779667328485,32.3038632800462],[-64.8780046844321,32.2907757831692],[-64.8849776658292,32.2819261366004],[-64.8783230004629,32.2613001418681],[-64.863194968877,32.2465799485801],[-64.8519819555722,32.2485519134663],[-64.842311980074,32.2492123317296],[-64.8388242605209,32.2475773472534],[-64.8334002575532,32.2462714714698],[-64.8256389530584,32.2472637398594],[-64.8205697556026,32.2531698880328],[-64.8105087275579,32.2561208974156],[-64.7900177727338,32.2659446936992],[-64.7745415970416,32.2718413023427],[-64.7644742436426,32.2855931353214],[-64.7551803442276,32.2908326702531],[-64.7423982971436,32.2996734994024],[-64.7206991797682,32.3137542201258],[-64.7117851247134,32.3176823360806],[-64.6962778813133,32.3275029115532],[-64.6768921127452,32.3324095397555],[-64.6567136927777,32.3451776458469],[-64.6532168823499,32.3494356627941],[-64.6605720384429,32.3589423487763],[-64.65125819471,32.3615600906466],[-64.6462011670816,32.36975169749],[-64.6613227512832,32.3763135008721],[-64.6690666074397,32.388444543924],[-64.6834270548595,32.3854968316788],[-64.6954617672714,32.3763221285869],[-64.70438689565,32.3704254760469],[-64.7117569982798,32.368132600249],[-64.7061764744404,32.3600110593559],[-64.700531552697,32.3590601356818],[-64.6940348033967,32.3640708659835],[-64.6895164826082,32.3633598579866],[-64.6864150099255,32.3547797587266],[-64.6824635995504,32.3540628176846],[-64.6835876652835,32.3626447677968],[-64.6801998697415,32.3631199096979],[-64.6672170444687,32.3597751617473],[-64.6598811264978,32.3497625771755],[-64.6737331235384,32.3390281851635],[-64.6887090648183,32.3342439408053],[-64.706732854446,32.3429010723036],[-64.7149301576112,32.3552188753513],[-64.7185967666669,32.3552239212394],[-64.7214189847314,32.3518830231342],[-64.7270616067222,32.3466461715475],[-64.734962460882,32.3442819830499],[-64.7383521549094,32.3407216514918],[-64.7411729976333,32.3311790864627],[-64.7423019216485,32.323311561213],[-64.7462482354281,32.318538611581],[-64.7566773739613,32.3130509130175],[-64.768738200563,32.3088369816572],[-64.7799734332998,32.3072000581802]]]}}, {"type":"Feature","id":"BOL","properties":{"name":"Bolivia"},"geometry":{"type":"Polygon","coordinates":[[[-62.846468,-22.034985],[-63.986838,-21.993644],[-64.377021,-22.798091],[-64.964892,-22.075862],[-66.273339,-21.83231],[-67.106674,-22.735925],[-67.82818,-22.872919],[-68.219913,-21.494347],[-68.757167,-20.372658],[-68.442225,-19.405068],[-68.966818,-18.981683],[-69.100247,-18.260125],[-69.590424,-17.580012],[-68.959635,-16.500698],[-69.389764,-15.660129],[-69.160347,-15.323974],[-69.339535,-14.953195],[-68.948887,-14.453639],[-68.929224,-13.602684],[-68.88008,-12.899729],[-68.66508,-12.5613],[-69.529678,-10.951734],[-68.786158,-11.03638],[-68.271254,-11.014521],[-68.048192,-10.712059],[-67.173801,-10.306812],[-66.646908,-9.931331],[-65.338435,-9.761988],[-65.444837,-10.511451],[-65.321899,-10.895872],[-65.402281,-11.56627],[-64.316353,-12.461978],[-63.196499,-12.627033],[-62.80306,-13.000653],[-62.127081,-13.198781],[-61.713204,-13.489202],[-61.084121,-13.479384],[-60.503304,-13.775955],[-60.459198,-14.354007],[-60.264326,-14.645979],[-60.251149,-15.077219],[-60.542966,-15.09391],[-60.15839,-16.258284],[-58.24122,-16.299573],[-58.388058,-16.877109],[-58.280804,-17.27171],[-57.734558,-17.552468],[-57.498371,-18.174188],[-57.676009,-18.96184],[-57.949997,-19.400004],[-57.853802,-19.969995],[-58.166392,-20.176701],[-58.183471,-19.868399],[-59.115042,-19.356906],[-60.043565,-19.342747],[-61.786326,-19.633737],[-62.265961,-20.513735],[-62.291179,-21.051635],[-62.685057,-22.249029],[-62.846468,-22.034985]]]}}, {"type":"Feature","id":"BRA","properties":{"name":"Brazil"},"geometry":{"type":"Polygon","coordinates":[[[-57.625133,-30.216295],[-56.2909,-28.852761],[-55.162286,-27.881915],[-54.490725,-27.474757],[-53.648735,-26.923473],[-53.628349,-26.124865],[-54.13005,-25.547639],[-54.625291,-25.739255],[-54.428946,-25.162185],[-54.293476,-24.5708],[-54.29296,-24.021014],[-54.652834,-23.839578],[-55.027902,-24.001274],[-55.400747,-23.956935],[-55.517639,-23.571998],[-55.610683,-22.655619],[-55.797958,-22.35693],[-56.473317,-22.0863],[-56.88151,-22.282154],[-57.937156,-22.090176],[-57.870674,-20.732688],[-58.166392,-20.176701],[-57.853802,-19.969995],[-57.949997,-19.400004],[-57.676009,-18.96184],[-57.498371,-18.174188],[-57.734558,-17.552468],[-58.280804,-17.27171],[-58.388058,-16.877109],[-58.24122,-16.299573],[-60.15839,-16.258284],[-60.542966,-15.09391],[-60.251149,-15.077219],[-60.264326,-14.645979],[-60.459198,-14.354007],[-60.503304,-13.775955],[-61.084121,-13.479384],[-61.713204,-13.489202],[-62.127081,-13.198781],[-62.80306,-13.000653],[-63.196499,-12.627033],[-64.316353,-12.461978],[-65.402281,-11.56627],[-65.321899,-10.895872],[-65.444837,-10.511451],[-65.338435,-9.761988],[-66.646908,-9.931331],[-67.173801,-10.306812],[-68.048192,-10.712059],[-68.271254,-11.014521],[-68.786158,-11.03638],[-69.529678,-10.951734],[-70.093752,-11.123972],[-70.548686,-11.009147],[-70.481894,-9.490118],[-71.302412,-10.079436],[-72.184891,-10.053598],[-72.563033,-9.520194],[-73.226713,-9.462213],[-73.015383,-9.032833],[-73.571059,-8.424447],[-73.987235,-7.52383],[-73.723401,-7.340999],[-73.724487,-6.918595],[-73.120027,-6.629931],[-73.219711,-6.089189],[-72.964507,-5.741251],[-72.891928,-5.274561],[-71.748406,-4.593983],[-70.928843,-4.401591],[-70.794769,-4.251265],[-69.893635,-4.298187],[-69.444102,-1.556287],[-69.420486,-1.122619],[-69.577065,-0.549992],[-70.020656,-0.185156],[-70.015566,0.541414],[-69.452396,0.706159],[-69.252434,0.602651],[-69.218638,0.985677],[-69.804597,1.089081],[-69.816973,1.714805],[-67.868565,1.692455],[-67.53781,2.037163],[-67.259998,1.719999],[-67.065048,1.130112],[-66.876326,1.253361],[-66.325765,0.724452],[-65.548267,0.789254],[-65.354713,1.095282],[-64.611012,1.328731],[-64.199306,1.492855],[-64.083085,1.916369],[-63.368788,2.2009],[-63.422867,2.411068],[-64.269999,2.497006],[-64.408828,3.126786],[-64.368494,3.79721],[-64.816064,4.056445],[-64.628659,4.148481],[-63.888343,4.02053],[-63.093198,3.770571],[-62.804533,4.006965],[-62.08543,4.162124],[-60.966893,4.536468],[-60.601179,4.918098],[-60.733574,5.200277],[-60.213683,5.244486],[-59.980959,5.014061],[-60.111002,4.574967],[-59.767406,4.423503],[-59.53804,3.958803],[-59.815413,3.606499],[-59.974525,2.755233],[-59.718546,2.24963],[-59.646044,1.786894],[-59.030862,1.317698],[-58.540013,1.268088],[-58.429477,1.463942],[-58.11345,1.507195],[-57.660971,1.682585],[-57.335823,1.948538],[-56.782704,1.863711],[-56.539386,1.899523],[-55.995698,1.817667],[-55.9056,2.021996],[-56.073342,2.220795],[-55.973322,2.510364],[-55.569755,2.421506],[-55.097587,2.523748],[-54.524754,2.311849],[-54.088063,2.105557],[-53.778521,2.376703],[-53.554839,2.334897],[-53.418465,2.053389],[-52.939657,2.124858],[-52.556425,2.504705],[-52.249338,3.241094],[-51.657797,4.156232],[-51.317146,4.203491],[-51.069771,3.650398],[-50.508875,1.901564],[-49.974076,1.736483],[-49.947101,1.04619],[-50.699251,0.222984],[-50.388211,-0.078445],[-48.620567,-0.235489],[-48.584497,-1.237805],[-47.824956,-0.581618],[-46.566584,-0.941028],[-44.905703,-1.55174],[-44.417619,-2.13775],[-44.581589,-2.691308],[-43.418791,-2.38311],[-41.472657,-2.912018],[-39.978665,-2.873054],[-38.500383,-3.700652],[-37.223252,-4.820946],[-36.452937,-5.109404],[-35.597796,-5.149504],[-35.235389,-5.464937],[-34.89603,-6.738193],[-34.729993,-7.343221],[-35.128212,-8.996401],[-35.636967,-9.649282],[-37.046519,-11.040721],[-37.683612,-12.171195],[-38.423877,-13.038119],[-38.673887,-13.057652],[-38.953276,-13.79337],[-38.882298,-15.667054],[-39.161092,-17.208407],[-39.267339,-17.867746],[-39.583521,-18.262296],[-39.760823,-19.599113],[-40.774741,-20.904512],[-40.944756,-21.937317],[-41.754164,-22.370676],[-41.988284,-22.97007],[-43.074704,-22.967693],[-44.647812,-23.351959],[-45.352136,-23.796842],[-46.472093,-24.088969],[-47.648972,-24.885199],[-48.495458,-25.877025],[-48.641005,-26.623698],[-48.474736,-27.175912],[-48.66152,-28.186135],[-48.888457,-28.674115],[-49.587329,-29.224469],[-50.696874,-30.984465],[-51.576226,-31.777698],[-52.256081,-32.24537],[-52.7121,-33.196578],[-53.373662,-33.768378],[-53.650544,-33.202004],[-53.209589,-32.727666],[-53.787952,-32.047243],[-54.572452,-31.494511],[-55.60151,-30.853879],[-55.973245,-30.883076],[-56.976026,-30.109686],[-57.625133,-30.216295]]]}}, {"type":"Feature","id":"BRN","properties":{"name":"Brunei"},"geometry":{"type":"Polygon","coordinates":[[[114.204017,4.525874],[114.599961,4.900011],[115.45071,5.44773],[115.4057,4.955228],[115.347461,4.316636],[114.869557,4.348314],[114.659596,4.007637],[114.204017,4.525874]]]}}, {"type":"Feature","id":"BTN","properties":{"name":"Bhutan"},"geometry":{"type":"Polygon","coordinates":[[[91.696657,27.771742],[92.103712,27.452614],[92.033484,26.83831],[91.217513,26.808648],[90.373275,26.875724],[89.744528,26.719403],[88.835643,27.098966],[88.814248,27.299316],[89.47581,28.042759],[90.015829,28.296439],[90.730514,28.064954],[91.258854,28.040614],[91.696657,27.771742]]]}}, {"type":"Feature","id":"BWA","properties":{"name":"Botswana"},"geometry":{"type":"Polygon","coordinates":[[[25.649163,-18.536026],[25.850391,-18.714413],[26.164791,-19.293086],[27.296505,-20.39152],[27.724747,-20.499059],[27.727228,-20.851802],[28.02137,-21.485975],[28.794656,-21.639454],[29.432188,-22.091313],[28.017236,-22.827754],[27.11941,-23.574323],[26.786407,-24.240691],[26.485753,-24.616327],[25.941652,-24.696373],[25.765849,-25.174845],[25.664666,-25.486816],[25.025171,-25.71967],[24.211267,-25.670216],[23.73357,-25.390129],[23.312097,-25.26869],[22.824271,-25.500459],[22.579532,-25.979448],[22.105969,-26.280256],[21.605896,-26.726534],[20.889609,-26.828543],[20.66647,-26.477453],[20.758609,-25.868136],[20.165726,-24.917962],[19.895768,-24.76779],[19.895458,-21.849157],[20.881134,-21.814327],[20.910641,-18.252219],[21.65504,-18.219146],[23.196858,-17.869038],[23.579006,-18.281261],[24.217365,-17.889347],[24.520705,-17.887125],[25.084443,-17.661816],[25.264226,-17.73654],[25.649163,-18.536026]]]}}, {"type":"Feature","id":"CAF","properties":{"name":"Central African Republic"},"geometry":{"type":"Polygon","coordinates":[[[15.27946,7.421925],[16.106232,7.497088],[16.290562,7.754307],[16.456185,7.734774],[16.705988,7.508328],[17.96493,7.890914],[18.389555,8.281304],[18.911022,8.630895],[18.81201,8.982915],[19.094008,9.074847],[20.059685,9.012706],[21.000868,9.475985],[21.723822,10.567056],[22.231129,10.971889],[22.864165,11.142395],[22.977544,10.714463],[23.554304,10.089255],[23.55725,9.681218],[23.394779,9.265068],[23.459013,8.954286],[23.805813,8.666319],[24.567369,8.229188],[25.114932,7.825104],[25.124131,7.500085],[25.796648,6.979316],[26.213418,6.546603],[26.465909,5.946717],[27.213409,5.550953],[27.374226,5.233944],[27.044065,5.127853],[26.402761,5.150875],[25.650455,5.256088],[25.278798,5.170408],[25.128833,4.927245],[24.805029,4.897247],[24.410531,5.108784],[23.297214,4.609693],[22.84148,4.710126],[22.704124,4.633051],[22.405124,4.02916],[21.659123,4.224342],[20.927591,4.322786],[20.290679,4.691678],[19.467784,5.031528],[18.932312,4.709506],[18.542982,4.201785],[18.453065,3.504386],[17.8099,3.560196],[17.133042,3.728197],[16.537058,3.198255],[16.012852,2.26764],[15.907381,2.557389],[15.862732,3.013537],[15.405396,3.335301],[15.03622,3.851367],[14.950953,4.210389],[14.478372,4.732605],[14.558936,5.030598],[14.459407,5.451761],[14.53656,6.226959],[14.776545,6.408498],[15.27946,7.421925]]]}}, {"type":"Feature","id":"CAN","properties":{"name":"Canada"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-63.6645,46.55001],[-62.9393,46.41587],[-62.01208,46.44314],[-62.50391,46.03339],[-62.87433,45.96818],[-64.1428,46.39265],[-64.39261,46.72747],[-64.01486,47.03601],[-63.6645,46.55001]]],[[[-61.806305,49.10506],[-62.29318,49.08717],[-63.58926,49.40069],[-64.51912,49.87304],[-64.17322,49.95718],[-62.85829,49.70641],[-61.835585,49.28855],[-61.806305,49.10506]]],[[[-123.510002,48.510011],[-124.012891,48.370846],[-125.655013,48.825005],[-125.954994,49.179996],[-126.850004,49.53],[-127.029993,49.814996],[-128.059336,49.994959],[-128.444584,50.539138],[-128.358414,50.770648],[-127.308581,50.552574],[-126.695001,50.400903],[-125.755007,50.295018],[-125.415002,49.950001],[-124.920768,49.475275],[-123.922509,49.062484],[-123.510002,48.510011]]],[[[-56.134036,50.68701],[-56.795882,49.812309],[-56.143105,50.150117],[-55.471492,49.935815],[-55.822401,49.587129],[-54.935143,49.313011],[-54.473775,49.556691],[-53.476549,49.249139],[-53.786014,48.516781],[-53.086134,48.687804],[-52.958648,48.157164],[-52.648099,47.535548],[-53.069158,46.655499],[-53.521456,46.618292],[-54.178936,46.807066],[-53.961869,47.625207],[-54.240482,47.752279],[-55.400773,46.884994],[-55.997481,46.91972],[-55.291219,47.389562],[-56.250799,47.632545],[-57.325229,47.572807],[-59.266015,47.603348],[-59.419494,47.899454],[-58.796586,48.251525],[-59.231625,48.523188],[-58.391805,49.125581],[-57.35869,50.718274],[-56.73865,51.287438],[-55.870977,51.632094],[-55.406974,51.588273],[-55.600218,51.317075],[-56.134036,50.68701]]],[[[-132.710008,54.040009],[-131.74999,54.120004],[-132.04948,52.984621],[-131.179043,52.180433],[-131.57783,52.182371],[-132.180428,52.639707],[-132.549992,53.100015],[-133.054611,53.411469],[-133.239664,53.85108],[-133.180004,54.169975],[-132.710008,54.040009]]],[[[-79.26582,62.158675],[-79.65752,61.63308],[-80.09956,61.7181],[-80.36215,62.01649],[-80.315395,62.085565],[-79.92939,62.3856],[-79.52002,62.36371],[-79.26582,62.158675]]],[[[-81.89825,62.7108],[-83.06857,62.15922],[-83.77462,62.18231],[-83.99367,62.4528],[-83.25048,62.91409],[-81.87699,62.90458],[-81.89825,62.7108]]],[[[-85.161308,65.657285],[-84.975764,65.217518],[-84.464012,65.371772],[-83.882626,65.109618],[-82.787577,64.766693],[-81.642014,64.455136],[-81.55344,63.979609],[-80.817361,64.057486],[-80.103451,63.725981],[-80.99102,63.411246],[-82.547178,63.651722],[-83.108798,64.101876],[-84.100417,63.569712],[-85.523405,63.052379],[-85.866769,63.637253],[-87.221983,63.541238],[-86.35276,64.035833],[-86.224886,64.822917],[-85.883848,65.738778],[-85.161308,65.657285]]],[[[-75.86588,67.14886],[-76.98687,67.09873],[-77.2364,67.58809],[-76.81166,68.14856],[-75.89521,68.28721],[-75.1145,68.01036],[-75.10333,67.58202],[-75.21597,67.44425],[-75.86588,67.14886]]],[[[-95.647681,69.10769],[-96.269521,68.75704],[-97.617401,69.06003],[-98.431801,68.9507],[-99.797401,69.40003],[-98.917401,69.71003],[-98.218261,70.14354],[-97.157401,69.86003],[-96.557401,69.68003],[-96.257401,69.49003],[-95.647681,69.10769]]],[[[-90.5471,69.49766],[-90.55151,68.47499],[-89.21515,69.25873],[-88.01966,68.61508],[-88.31749,67.87338],[-87.35017,67.19872],[-86.30607,67.92146],[-85.57664,68.78456],[-85.52197,69.88211],[-84.10081,69.80539],[-82.62258,69.65826],[-81.28043,69.16202],[-81.2202,68.66567],[-81.96436,68.13253],[-81.25928,67.59716],[-81.38653,67.11078],[-83.34456,66.41154],[-84.73542,66.2573],[-85.76943,66.55833],[-86.0676,66.05625],[-87.03143,65.21297],[-87.32324,64.77563],[-88.48296,64.09897],[-89.91444,64.03273],[-90.70398,63.61017],[-90.77004,62.96021],[-91.93342,62.83508],[-93.15698,62.02469],[-94.24153,60.89865],[-94.62931,60.11021],[-94.6846,58.94882],[-93.21502,58.78212],[-92.76462,57.84571],[-92.29703,57.08709],[-90.89769,57.28468],[-89.03953,56.85172],[-88.03978,56.47162],[-87.32421,55.99914],[-86.07121,55.72383],[-85.01181,55.3026],[-83.36055,55.24489],[-82.27285,55.14832],[-82.4362,54.28227],[-82.12502,53.27703],[-81.40075,52.15788],[-79.91289,51.20842],[-79.14301,51.53393],[-78.60191,52.56208],[-79.12421,54.14145],[-79.82958,54.66772],[-78.22874,55.13645],[-77.0956,55.83741],[-76.54137,56.53423],[-76.62319,57.20263],[-77.30226,58.05209],[-78.51688,58.80458],[-77.33676,59.85261],[-77.77272,60.75788],[-78.10687,62.31964],[-77.41067,62.55053],[-75.69621,62.2784],[-74.6682,62.18111],[-73.83988,62.4438],[-72.90853,62.10507],[-71.67708,61.52535],[-71.37369,61.13717],[-69.59042,61.06141],[-69.62033,60.22125],[-69.2879,58.95736],[-68.37455,58.80106],[-67.64976,58.21206],[-66.20178,58.76731],[-65.24517,59.87071],[-64.58352,60.33558],[-63.80475,59.4426],[-62.50236,58.16708],[-61.39655,56.96745],[-61.79866,56.33945],[-60.46853,55.77548],[-59.56962,55.20407],[-57.97508,54.94549],[-57.3332,54.6265],[-56.93689,53.78032],[-56.15811,53.64749],[-55.75632,53.27036],[-55.68338,52.14664],[-56.40916,51.7707],[-57.12691,51.41972],[-58.77482,51.0643],[-60.03309,50.24277],[-61.72366,50.08046],[-63.86251,50.29099],[-65.36331,50.2982],[-66.39905,50.22897],[-67.23631,49.51156],[-68.51114,49.06836],[-69.95362,47.74488],[-71.10458,46.82171],[-70.25522,46.98606],[-68.65,48.3],[-66.55243,49.1331],[-65.05626,49.23278],[-64.17099,48.74248],[-65.11545,48.07085],[-64.79854,46.99297],[-64.47219,46.23849],[-63.17329,45.73902],[-61.52072,45.88377],[-60.51815,47.00793],[-60.4486,46.28264],[-59.80287,45.9204],[-61.03988,45.26525],[-63.25471,44.67014],[-64.24656,44.26553],[-65.36406,43.54523],[-66.1234,43.61867],[-66.16173,44.46512],[-64.42549,45.29204],[-66.02605,45.25931],[-67.13741,45.13753],[-67.79134,45.70281],[-67.79046,47.06636],[-68.23444,47.35486],[-68.905,47.185],[-69.237216,47.447781],[-69.99997,46.69307],[-70.305,45.915],[-70.66,45.46],[-71.08482,45.30524],[-71.405,45.255],[-71.50506,45.0082],[-73.34783,45.00738],[-74.867,45.00048],[-75.31821,44.81645],[-76.375,44.09631],[-76.5,44.018459],[-76.820034,43.628784],[-77.737885,43.629056],[-78.72028,43.625089],[-79.171674,43.466339],[-79.01,43.27],[-78.92,42.965],[-78.939362,42.863611],[-80.247448,42.3662],[-81.277747,42.209026],[-82.439278,41.675105],[-82.690089,41.675105],[-83.02981,41.832796],[-83.142,41.975681],[-83.12,42.08],[-82.9,42.43],[-82.43,42.98],[-82.137642,43.571088],[-82.337763,44.44],[-82.550925,45.347517],[-83.592851,45.816894],[-83.469551,45.994686],[-83.616131,46.116927],[-83.890765,46.116927],[-84.091851,46.275419],[-84.14212,46.512226],[-84.3367,46.40877],[-84.6049,46.4396],[-84.543749,46.538684],[-84.779238,46.637102],[-84.87608,46.900083],[-85.652363,47.220219],[-86.461991,47.553338],[-87.439793,47.94],[-88.378114,48.302918],[-89.272917,48.019808],[-89.6,48.01],[-90.83,48.27],[-91.64,48.14],[-92.61,48.45],[-93.63087,48.60926],[-94.32914,48.67074],[-94.64,48.84],[-94.81758,49.38905],[-95.15609,49.38425],[-95.15907,49],[-97.22872,49.0007],[-100.65,49],[-104.04826,48.99986],[-107.05,49],[-110.05,49],[-113,49],[-116.04818,49],[-117.03121,49],[-120,49],[-122.84,49],[-122.97421,49.002538],[-124.91024,49.98456],[-125.62461,50.41656],[-127.43561,50.83061],[-127.99276,51.71583],[-127.85032,52.32961],[-129.12979,52.75538],[-129.30523,53.56159],[-130.51497,54.28757],[-130.53611,54.80278],[-129.98,55.285],[-130.00778,55.91583],[-131.70781,56.55212],[-132.73042,57.69289],[-133.35556,58.41028],[-134.27111,58.86111],[-134.945,59.27056],[-135.47583,59.78778],[-136.47972,59.46389],[-137.4525,58.905],[-138.34089,59.56211],[-139.039,60],[-140.013,60.27682],[-140.99778,60.30639],[-140.9925,66.00003],[-140.986,69.712],[-139.12052,69.47102],[-137.54636,68.99002],[-136.50358,68.89804],[-135.62576,69.31512],[-134.41464,69.62743],[-132.92925,69.50534],[-131.43136,69.94451],[-129.79471,70.19369],[-129.10773,69.77927],[-128.36156,70.01286],[-128.13817,70.48384],[-127.44712,70.37721],[-125.75632,69.48058],[-124.42483,70.1584],[-124.28968,69.39969],[-123.06108,69.56372],[-122.6835,69.85553],[-121.47226,69.79778],[-119.94288,69.37786],[-117.60268,69.01128],[-116.22643,68.84151],[-115.2469,68.90591],[-113.89794,68.3989],[-115.30489,67.90261],[-113.49727,67.68815],[-110.798,67.80612],[-109.94619,67.98104],[-108.8802,67.38144],[-107.79239,67.88736],[-108.81299,68.31164],[-108.16721,68.65392],[-106.95,68.7],[-106.15,68.8],[-105.34282,68.56122],[-104.33791,68.018],[-103.22115,68.09775],[-101.45433,67.64689],[-99.90195,67.80566],[-98.4432,67.78165],[-98.5586,68.40394],[-97.66948,68.57864],[-96.11991,68.23939],[-96.12588,67.29338],[-95.48943,68.0907],[-94.685,68.06383],[-94.23282,69.06903],[-95.30408,69.68571],[-96.47131,70.08976],[-96.39115,71.19482],[-95.2088,71.92053],[-93.88997,71.76015],[-92.87818,71.31869],[-91.51964,70.19129],[-92.40692,69.69997],[-90.5471,69.49766]]],[[[-114.16717,73.12145],[-114.66634,72.65277],[-112.44102,72.9554],[-111.05039,72.4504],[-109.92035,72.96113],[-109.00654,72.63335],[-108.18835,71.65089],[-107.68599,72.06548],[-108.39639,73.08953],[-107.51645,73.23598],[-106.52259,73.07601],[-105.40246,72.67259],[-104.77484,71.6984],[-104.46476,70.99297],[-102.78537,70.49776],[-100.98078,70.02432],[-101.08929,69.58447],[-102.73116,69.50402],[-102.09329,69.11962],[-102.43024,68.75282],[-104.24,68.91],[-105.96,69.18],[-107.12254,69.11922],[-109,68.78],[-111.534149,68.630059],[-113.3132,68.53554],[-113.85496,69.00744],[-115.22,69.28],[-116.10794,69.16821],[-117.34,69.96],[-116.67473,70.06655],[-115.13112,70.2373],[-113.72141,70.19237],[-112.4161,70.36638],[-114.35,70.6],[-116.48684,70.52045],[-117.9048,70.54056],[-118.43238,70.9092],[-116.11311,71.30918],[-117.65568,71.2952],[-119.40199,71.55859],[-118.56267,72.30785],[-117.86642,72.70594],[-115.18909,73.31459],[-114.16717,73.12145]]],[[[-104.5,73.42],[-105.38,72.76],[-106.94,73.46],[-106.6,73.6],[-105.26,73.64],[-104.5,73.42]]],[[[-76.34,73.102685],[-76.251404,72.826385],[-77.314438,72.855545],[-78.39167,72.876656],[-79.486252,72.742203],[-79.775833,72.802902],[-80.876099,73.333183],[-80.833885,73.693184],[-80.353058,73.75972],[-78.064438,73.651932],[-76.34,73.102685]]],[[[-86.562179,73.157447],[-85.774371,72.534126],[-84.850112,73.340278],[-82.31559,73.750951],[-80.600088,72.716544],[-80.748942,72.061907],[-78.770639,72.352173],[-77.824624,72.749617],[-75.605845,72.243678],[-74.228616,71.767144],[-74.099141,71.33084],[-72.242226,71.556925],[-71.200015,70.920013],[-68.786054,70.525024],[-67.91497,70.121948],[-66.969033,69.186087],[-68.805123,68.720198],[-66.449866,68.067163],[-64.862314,67.847539],[-63.424934,66.928473],[-61.851981,66.862121],[-62.163177,66.160251],[-63.918444,64.998669],[-65.14886,65.426033],[-66.721219,66.388041],[-68.015016,66.262726],[-68.141287,65.689789],[-67.089646,65.108455],[-65.73208,64.648406],[-65.320168,64.382737],[-64.669406,63.392927],[-65.013804,62.674185],[-66.275045,62.945099],[-68.783186,63.74567],[-67.369681,62.883966],[-66.328297,62.280075],[-66.165568,61.930897],[-68.877367,62.330149],[-71.023437,62.910708],[-72.235379,63.397836],[-71.886278,63.679989],[-73.378306,64.193963],[-74.834419,64.679076],[-74.818503,64.389093],[-77.70998,64.229542],[-78.555949,64.572906],[-77.897281,65.309192],[-76.018274,65.326969],[-73.959795,65.454765],[-74.293883,65.811771],[-73.944912,66.310578],[-72.651167,67.284576],[-72.92606,67.726926],[-73.311618,68.069437],[-74.843307,68.554627],[-76.869101,68.894736],[-76.228649,69.147769],[-77.28737,69.76954],[-78.168634,69.826488],[-78.957242,70.16688],[-79.492455,69.871808],[-81.305471,69.743185],[-84.944706,69.966634],[-87.060003,70.260001],[-88.681713,70.410741],[-89.51342,70.762038],[-88.467721,71.218186],[-89.888151,71.222552],[-90.20516,72.235074],[-89.436577,73.129464],[-88.408242,73.537889],[-85.826151,73.803816],[-86.562179,73.157447]]],[[[-100.35642,73.84389],[-99.16387,73.63339],[-97.38,73.76],[-97.12,73.47],[-98.05359,72.99052],[-96.54,72.56],[-96.72,71.66],[-98.35966,71.27285],[-99.32286,71.35639],[-100.01482,71.73827],[-102.5,72.51],[-102.48,72.83],[-100.43836,72.70588],[-101.54,73.36],[-100.35642,73.84389]]],[[[-93.196296,72.771992],[-94.269047,72.024596],[-95.409856,72.061881],[-96.033745,72.940277],[-96.018268,73.43743],[-95.495793,73.862417],[-94.503658,74.134907],[-92.420012,74.100025],[-90.509793,73.856732],[-92.003965,72.966244],[-93.196296,72.771992]]],[[[-120.46,71.383602],[-123.09219,70.90164],[-123.62,71.34],[-125.928949,71.868688],[-125.5,72.292261],[-124.80729,73.02256],[-123.94,73.68],[-124.91775,74.29275],[-121.53788,74.44893],[-120.10978,74.24135],[-117.55564,74.18577],[-116.58442,73.89607],[-115.51081,73.47519],[-116.76794,73.22292],[-119.22,72.52],[-120.46,71.82],[-120.46,71.383602]]],[[[-93.612756,74.979997],[-94.156909,74.592347],[-95.608681,74.666864],[-96.820932,74.927623],[-96.288587,75.377828],[-94.85082,75.647218],[-93.977747,75.29649],[-93.612756,74.979997]]],[[[-98.5,76.72],[-97.735585,76.25656],[-97.704415,75.74344],[-98.16,75],[-99.80874,74.89744],[-100.88366,75.05736],[-100.86292,75.64075],[-102.50209,75.5638],[-102.56552,76.3366],[-101.48973,76.30537],[-99.98349,76.64634],[-98.57699,76.58859],[-98.5,76.72]]],[[[-108.21141,76.20168],[-107.81943,75.84552],[-106.92893,76.01282],[-105.881,75.9694],[-105.70498,75.47951],[-106.31347,75.00527],[-109.7,74.85],[-112.22307,74.41696],[-113.74381,74.39427],[-113.87135,74.72029],[-111.79421,75.1625],[-116.31221,75.04343],[-117.7104,75.2222],[-116.34602,76.19903],[-115.40487,76.47887],[-112.59056,76.14134],[-110.81422,75.54919],[-109.0671,75.47321],[-110.49726,76.42982],[-109.5811,76.79417],[-108.54859,76.67832],[-108.21141,76.20168]]],[[[-94.684086,77.097878],[-93.573921,76.776296],[-91.605023,76.778518],[-90.741846,76.449597],[-90.969661,76.074013],[-89.822238,75.847774],[-89.187083,75.610166],[-87.838276,75.566189],[-86.379192,75.482421],[-84.789625,75.699204],[-82.753445,75.784315],[-81.128531,75.713983],[-80.057511,75.336849],[-79.833933,74.923127],[-80.457771,74.657304],[-81.948843,74.442459],[-83.228894,74.564028],[-86.097452,74.410032],[-88.15035,74.392307],[-89.764722,74.515555],[-92.422441,74.837758],[-92.768285,75.38682],[-92.889906,75.882655],[-93.893824,76.319244],[-95.962457,76.441381],[-97.121379,76.751078],[-96.745123,77.161389],[-94.684086,77.097878]]],[[[-116.198587,77.645287],[-116.335813,76.876962],[-117.106051,76.530032],[-118.040412,76.481172],[-119.899318,76.053213],[-121.499995,75.900019],[-122.854924,76.116543],[-122.854925,76.116543],[-121.157535,76.864508],[-119.103939,77.51222],[-117.570131,77.498319],[-116.198587,77.645287]]],[[[-93.840003,77.519997],[-94.295608,77.491343],[-96.169654,77.555111],[-96.436304,77.834629],[-94.422577,77.820005],[-93.720656,77.634331],[-93.840003,77.519997]]],[[[-110.186938,77.697015],[-112.051191,77.409229],[-113.534279,77.732207],[-112.724587,78.05105],[-111.264443,78.152956],[-109.854452,77.996325],[-110.186938,77.697015]]],[[[-109.663146,78.601973],[-110.881314,78.40692],[-112.542091,78.407902],[-112.525891,78.550555],[-111.50001,78.849994],[-110.963661,78.804441],[-109.663146,78.601973]]],[[[-95.830295,78.056941],[-97.309843,77.850597],[-98.124289,78.082857],[-98.552868,78.458105],[-98.631984,78.87193],[-97.337231,78.831984],[-96.754399,78.765813],[-95.559278,78.418315],[-95.830295,78.056941]]],[[[-100.060192,78.324754],[-99.670939,77.907545],[-101.30394,78.018985],[-102.949809,78.343229],[-105.176133,78.380332],[-104.210429,78.67742],[-105.41958,78.918336],[-105.492289,79.301594],[-103.529282,79.165349],[-100.825158,78.800462],[-100.060192,78.324754]]],[[[-87.02,79.66],[-85.81435,79.3369],[-87.18756,79.0393],[-89.03535,78.28723],[-90.80436,78.21533],[-92.87669,78.34333],[-93.95116,78.75099],[-93.93574,79.11373],[-93.14524,79.3801],[-94.974,79.37248],[-96.07614,79.70502],[-96.70972,80.15777],[-96.01644,80.60233],[-95.32345,80.90729],[-94.29843,80.97727],[-94.73542,81.20646],[-92.40984,81.25739],[-91.13289,80.72345],[-89.45,80.509322],[-87.81,80.32],[-87.02,79.66]]],[[[-68.5,83.106322],[-65.82735,83.02801],[-63.68,82.9],[-61.85,82.6286],[-61.89388,82.36165],[-64.334,81.92775],[-66.75342,81.72527],[-67.65755,81.50141],[-65.48031,81.50657],[-67.84,80.9],[-69.4697,80.61683],[-71.18,79.8],[-73.2428,79.63415],[-73.88,79.430162],[-76.90773,79.32309],[-75.52924,79.19766],[-76.22046,79.01907],[-75.39345,78.52581],[-76.34354,78.18296],[-77.88851,77.89991],[-78.36269,77.50859],[-79.75951,77.20968],[-79.61965,76.98336],[-77.91089,77.022045],[-77.88911,76.777955],[-80.56125,76.17812],[-83.17439,76.45403],[-86.11184,76.29901],[-87.6,76.42],[-89.49068,76.47239],[-89.6161,76.95213],[-87.76739,77.17833],[-88.26,77.9],[-87.65,77.970222],[-84.97634,77.53873],[-86.34,78.18],[-87.96192,78.37181],[-87.15198,78.75867],[-85.37868,78.9969],[-85.09495,79.34543],[-86.50734,79.73624],[-86.93179,80.25145],[-84.19844,80.20836],[-83.408696,80.1],[-81.84823,80.46442],[-84.1,80.58],[-87.59895,80.51627],[-89.36663,80.85569],[-90.2,81.26],[-91.36786,81.5531],[-91.58702,81.89429],[-90.1,82.085],[-88.93227,82.11751],[-86.97024,82.27961],[-85.5,82.652273],[-84.260005,82.6],[-83.18,82.32],[-82.42,82.86],[-81.1,83.02],[-79.30664,83.13056],[-76.25,83.172059],[-75.71878,83.06404],[-72.83153,83.23324],[-70.665765,83.169781],[-68.5,83.106322]]]]}}, {"type":"Feature","id":"CHE","properties":{"name":"Switzerland"},"geometry":{"type":"Polygon","coordinates":[[[9.594226,47.525058],[9.632932,47.347601],[9.47997,47.10281],[9.932448,46.920728],[10.442701,46.893546],[10.363378,46.483571],[9.922837,46.314899],[9.182882,46.440215],[8.966306,46.036932],[8.489952,46.005151],[8.31663,46.163642],[7.755992,45.82449],[7.273851,45.776948],[6.843593,45.991147],[6.5001,46.429673],[6.022609,46.27299],[6.037389,46.725779],[6.768714,47.287708],[6.736571,47.541801],[7.192202,47.449766],[7.466759,47.620582],[8.317301,47.61358],[8.522612,47.830828],[9.594226,47.525058]]]}}, {"type":"Feature","id":"CHL","properties":{"name":"Chile"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-68.63401,-52.63637],[-68.63335,-54.8695],[-67.56244,-54.87001],[-66.95992,-54.89681],[-67.29103,-55.30124],[-68.14863,-55.61183],[-68.639991,-55.580018],[-69.2321,-55.49906],[-69.95809,-55.19843],[-71.00568,-55.05383],[-72.2639,-54.49514],[-73.2852,-53.95752],[-74.66253,-52.83749],[-73.8381,-53.04743],[-72.43418,-53.7154],[-71.10773,-54.07433],[-70.59178,-53.61583],[-70.26748,-52.93123],[-69.34565,-52.5183],[-68.63401,-52.63637]]],[[[-68.219913,-21.494347],[-67.82818,-22.872919],[-67.106674,-22.735925],[-66.985234,-22.986349],[-67.328443,-24.025303],[-68.417653,-24.518555],[-68.386001,-26.185016],[-68.5948,-26.506909],[-68.295542,-26.89934],[-69.001235,-27.521214],[-69.65613,-28.459141],[-70.01355,-29.367923],[-69.919008,-30.336339],[-70.535069,-31.36501],[-70.074399,-33.09121],[-69.814777,-33.273886],[-69.817309,-34.193571],[-70.388049,-35.169688],[-70.364769,-36.005089],[-71.121881,-36.658124],[-71.118625,-37.576827],[-70.814664,-38.552995],[-71.413517,-38.916022],[-71.680761,-39.808164],[-71.915734,-40.832339],[-71.746804,-42.051386],[-72.148898,-42.254888],[-71.915424,-43.408565],[-71.464056,-43.787611],[-71.793623,-44.207172],[-71.329801,-44.407522],[-71.222779,-44.784243],[-71.659316,-44.973689],[-71.552009,-45.560733],[-71.917258,-46.884838],[-72.447355,-47.738533],[-72.331161,-48.244238],[-72.648247,-48.878618],[-73.415436,-49.318436],[-73.328051,-50.378785],[-72.975747,-50.74145],[-72.309974,-50.67701],[-72.329404,-51.425956],[-71.914804,-52.009022],[-69.498362,-52.142761],[-68.571545,-52.299444],[-69.461284,-52.291951],[-69.94278,-52.537931],[-70.845102,-52.899201],[-71.006332,-53.833252],[-71.429795,-53.856455],[-72.557943,-53.53141],[-73.702757,-52.835069],[-73.702757,-52.83507],[-74.946763,-52.262754],[-75.260026,-51.629355],[-74.976632,-51.043396],[-75.479754,-50.378372],[-75.608015,-48.673773],[-75.18277,-47.711919],[-74.126581,-46.939253],[-75.644395,-46.647643],[-74.692154,-45.763976],[-74.351709,-44.103044],[-73.240356,-44.454961],[-72.717804,-42.383356],[-73.3889,-42.117532],[-73.701336,-43.365776],[-74.331943,-43.224958],[-74.017957,-41.794813],[-73.677099,-39.942213],[-73.217593,-39.258689],[-73.505559,-38.282883],[-73.588061,-37.156285],[-73.166717,-37.12378],[-72.553137,-35.50884],[-71.861732,-33.909093],[-71.43845,-32.418899],[-71.668721,-30.920645],[-71.370083,-30.095682],[-71.489894,-28.861442],[-70.905124,-27.64038],[-70.724954,-25.705924],[-70.403966,-23.628997],[-70.091246,-21.393319],[-70.16442,-19.756468],[-70.372572,-18.347975],[-69.858444,-18.092694],[-69.590424,-17.580012],[-69.100247,-18.260125],[-68.966818,-18.981683],[-68.442225,-19.405068],[-68.757167,-20.372658],[-68.219913,-21.494347]]]]}}, {"type":"Feature","id":"CHN","properties":{"name":"China"},"geometry":{"type":"MultiPolygon","coordinates":[[[[110.339188,18.678395],[109.47521,18.197701],[108.655208,18.507682],[108.626217,19.367888],[109.119056,19.821039],[110.211599,20.101254],[110.786551,20.077534],[111.010051,19.69593],[110.570647,19.255879],[110.339188,18.678395]]],[[[127.657407,49.76027],[129.397818,49.4406],[130.582293,48.729687],[130.987282,47.790132],[132.506672,47.78897],[133.373596,48.183442],[135.026311,48.47823],[134.500814,47.57844],[134.112362,47.212467],[133.769644,46.116927],[133.097127,45.144066],[131.883454,45.321162],[131.025212,44.967953],[131.288555,44.11152],[131.144688,42.92999],[130.633866,42.903015],[130.640016,42.395009],[129.994267,42.985387],[129.596669,42.424982],[128.052215,41.994285],[128.208433,41.466772],[127.343783,41.503152],[126.869083,41.816569],[126.182045,41.107336],[125.079942,40.569824],[124.265625,39.928493],[122.86757,39.637788],[122.131388,39.170452],[121.054554,38.897471],[121.585995,39.360854],[121.376757,39.750261],[122.168595,40.422443],[121.640359,40.94639],[120.768629,40.593388],[119.639602,39.898056],[119.023464,39.252333],[118.042749,39.204274],[117.532702,38.737636],[118.059699,38.061476],[118.87815,37.897325],[118.911636,37.448464],[119.702802,37.156389],[120.823457,37.870428],[121.711259,37.481123],[122.357937,37.454484],[122.519995,36.930614],[121.104164,36.651329],[120.637009,36.11144],[119.664562,35.609791],[119.151208,34.909859],[120.227525,34.360332],[120.620369,33.376723],[121.229014,32.460319],[121.908146,31.692174],[121.891919,30.949352],[121.264257,30.676267],[121.503519,30.142915],[122.092114,29.83252],[121.938428,29.018022],[121.684439,28.225513],[121.125661,28.135673],[120.395473,27.053207],[119.585497,25.740781],[118.656871,24.547391],[117.281606,23.624501],[115.890735,22.782873],[114.763827,22.668074],[114.152547,22.22376],[113.80678,22.54834],[113.241078,22.051367],[111.843592,21.550494],[110.785466,21.397144],[110.444039,20.341033],[109.889861,20.282457],[109.627655,21.008227],[109.864488,21.395051],[108.522813,21.715212],[108.05018,21.55238],[107.04342,21.811899],[106.567273,22.218205],[106.725403,22.794268],[105.811247,22.976892],[105.329209,23.352063],[104.476858,22.81915],[103.504515,22.703757],[102.706992,22.708795],[102.170436,22.464753],[101.652018,22.318199],[101.80312,21.174367],[101.270026,21.201652],[101.180005,21.436573],[101.150033,21.849984],[100.416538,21.558839],[99.983489,21.742937],[99.240899,22.118314],[99.531992,22.949039],[98.898749,23.142722],[98.660262,24.063286],[97.60472,23.897405],[97.724609,25.083637],[98.671838,25.918703],[98.712094,26.743536],[98.68269,27.508812],[98.246231,27.747221],[97.911988,28.335945],[97.327114,28.261583],[96.248833,28.411031],[96.586591,28.83098],[96.117679,29.452802],[95.404802,29.031717],[94.56599,29.277438],[93.413348,28.640629],[92.503119,27.896876],[91.696657,27.771742],[91.258854,28.040614],[90.730514,28.064954],[90.015829,28.296439],[89.47581,28.042759],[88.814248,27.299316],[88.730326,28.086865],[88.120441,27.876542],[86.954517,27.974262],[85.82332,28.203576],[85.011638,28.642774],[84.23458,28.839894],[83.898993,29.320226],[83.337115,29.463732],[82.327513,30.115268],[81.525804,30.422717],[81.111256,30.183481],[79.721367,30.882715],[78.738894,31.515906],[78.458446,32.618164],[79.176129,32.48378],[79.208892,32.994395],[78.811086,33.506198],[78.912269,34.321936],[77.837451,35.49401],[76.192848,35.898403],[75.896897,36.666806],[75.158028,37.133031],[74.980002,37.41999],[74.829986,37.990007],[74.864816,38.378846],[74.257514,38.606507],[73.928852,38.505815],[73.675379,39.431237],[73.960013,39.660008],[73.822244,39.893973],[74.776862,40.366425],[75.467828,40.562072],[76.526368,40.427946],[76.904484,41.066486],[78.187197,41.185316],[78.543661,41.582243],[80.11943,42.123941],[80.25999,42.349999],[80.18015,42.920068],[80.866206,43.180362],[79.966106,44.917517],[81.947071,45.317027],[82.458926,45.53965],[83.180484,47.330031],[85.16429,47.000956],[85.720484,47.452969],[85.768233,48.455751],[86.598776,48.549182],[87.35997,49.214981],[87.751264,49.297198],[88.013832,48.599463],[88.854298,48.069082],[90.280826,47.693549],[90.970809,46.888146],[90.585768,45.719716],[90.94554,45.286073],[92.133891,45.115076],[93.480734,44.975472],[94.688929,44.352332],[95.306875,44.241331],[95.762455,43.319449],[96.349396,42.725635],[97.451757,42.74889],[99.515817,42.524691],[100.845866,42.663804],[101.83304,42.514873],[103.312278,41.907468],[104.522282,41.908347],[104.964994,41.59741],[106.129316,42.134328],[107.744773,42.481516],[109.243596,42.519446],[110.412103,42.871234],[111.129682,43.406834],[111.829588,43.743118],[111.667737,44.073176],[111.348377,44.457442],[111.873306,45.102079],[112.436062,45.011646],[113.463907,44.808893],[114.460332,45.339817],[115.985096,45.727235],[116.717868,46.388202],[117.421701,46.672733],[118.874326,46.805412],[119.66327,46.69268],[119.772824,47.048059],[118.866574,47.74706],[118.064143,48.06673],[117.295507,47.697709],[116.308953,47.85341],[115.742837,47.726545],[115.485282,48.135383],[116.191802,49.134598],[116.678801,49.888531],[117.879244,49.510983],[119.288461,50.142883],[119.279366,50.582908],[120.18205,51.643566],[120.738191,51.964115],[120.725789,52.516226],[120.177089,52.753886],[121.003085,53.251401],[122.245748,53.431726],[123.571507,53.458804],[125.068211,53.161045],[125.946349,52.792799],[126.564399,51.784255],[126.939157,51.353894],[127.287456,50.739797],[127.657407,49.76027]]]]}}, {"type":"Feature","id":"CIV","properties":{"name":"Ivory Coast"},"geometry":{"type":"Polygon","coordinates":[[[-2.856125,4.994476],[-3.311084,4.984296],[-4.00882,5.179813],[-4.649917,5.168264],[-5.834496,4.993701],[-6.528769,4.705088],[-7.518941,4.338288],[-7.712159,4.364566],[-7.635368,5.188159],[-7.539715,5.313345],[-7.570153,5.707352],[-7.993693,6.12619],[-8.311348,6.193033],[-8.60288,6.467564],[-8.385452,6.911801],[-8.485446,7.395208],[-8.439298,7.686043],[-8.280703,7.68718],[-8.221792,8.123329],[-8.299049,8.316444],[-8.203499,8.455453],[-7.8321,8.575704],[-8.079114,9.376224],[-8.309616,9.789532],[-8.229337,10.12902],[-8.029944,10.206535],[-7.89959,10.297382],[-7.622759,10.147236],[-6.850507,10.138994],[-6.666461,10.430811],[-6.493965,10.411303],[-6.205223,10.524061],[-6.050452,10.096361],[-5.816926,10.222555],[-5.404342,10.370737],[-4.954653,10.152714],[-4.779884,9.821985],[-4.330247,9.610835],[-3.980449,9.862344],[-3.511899,9.900326],[-2.827496,9.642461],[-2.56219,8.219628],[-2.983585,7.379705],[-3.24437,6.250472],[-2.810701,5.389051],[-2.856125,4.994476]]]}}, {"type":"Feature","id":"CMR","properties":{"name":"Cameroon"},"geometry":{"type":"Polygon","coordinates":[[[13.075822,2.267097],[12.951334,2.321616],[12.35938,2.192812],[11.751665,2.326758],[11.276449,2.261051],[9.649158,2.283866],[9.795196,3.073404],[9.404367,3.734527],[8.948116,3.904129],[8.744924,4.352215],[8.488816,4.495617],[8.500288,4.771983],[8.757533,5.479666],[9.233163,6.444491],[9.522706,6.453482],[10.118277,7.03877],[10.497375,7.055358],[11.058788,6.644427],[11.745774,6.981383],[11.839309,7.397042],[12.063946,7.799808],[12.218872,8.305824],[12.753672,8.717763],[12.955468,9.417772],[13.1676,9.640626],[13.308676,10.160362],[13.57295,10.798566],[14.415379,11.572369],[14.468192,11.904752],[14.577178,12.085361],[14.181336,12.483657],[14.213531,12.802035],[14.495787,12.859396],[14.893386,12.219048],[14.960152,11.555574],[14.923565,10.891325],[15.467873,9.982337],[14.909354,9.992129],[14.627201,9.920919],[14.171466,10.021378],[13.954218,9.549495],[14.544467,8.965861],[14.979996,8.796104],[15.120866,8.38215],[15.436092,7.692812],[15.27946,7.421925],[14.776545,6.408498],[14.53656,6.226959],[14.459407,5.451761],[14.558936,5.030598],[14.478372,4.732605],[14.950953,4.210389],[15.03622,3.851367],[15.405396,3.335301],[15.862732,3.013537],[15.907381,2.557389],[16.012852,2.26764],[15.940919,1.727673],[15.146342,1.964015],[14.337813,2.227875],[13.075822,2.267097]]]}}, {"type":"Feature","id":"COD","properties":{"name":"Democratic Republic of the Congo"},"geometry":{"type":"Polygon","coordinates":[[[30.83386,3.509166],[30.773347,2.339883],[31.174149,2.204465],[30.85267,1.849396],[30.468508,1.583805],[30.086154,1.062313],[29.875779,0.59738],[29.819503,-0.20531],[29.587838,-0.587406],[29.579466,-1.341313],[29.291887,-1.620056],[29.254835,-2.21511],[29.117479,-2.292211],[29.024926,-2.839258],[29.276384,-3.293907],[29.339998,-4.499983],[29.519987,-5.419979],[29.419993,-5.939999],[29.620032,-6.520015],[30.199997,-7.079981],[30.740015,-8.340007],[30.346086,-8.238257],[29.002912,-8.407032],[28.734867,-8.526559],[28.449871,-9.164918],[28.673682,-9.605925],[28.49607,-10.789884],[28.372253,-11.793647],[28.642417,-11.971569],[29.341548,-12.360744],[29.616001,-12.178895],[29.699614,-13.257227],[28.934286,-13.248958],[28.523562,-12.698604],[28.155109,-12.272481],[27.388799,-12.132747],[27.16442,-11.608748],[26.553088,-11.92444],[25.75231,-11.784965],[25.418118,-11.330936],[24.78317,-11.238694],[24.314516,-11.262826],[24.257155,-10.951993],[23.912215,-10.926826],[23.456791,-10.867863],[22.837345,-11.017622],[22.402798,-10.993075],[22.155268,-11.084801],[22.208753,-9.894796],[21.875182,-9.523708],[21.801801,-8.908707],[21.949131,-8.305901],[21.746456,-7.920085],[21.728111,-7.290872],[20.514748,-7.299606],[20.601823,-6.939318],[20.091622,-6.94309],[20.037723,-7.116361],[19.417502,-7.155429],[19.166613,-7.738184],[19.016752,-7.988246],[18.464176,-7.847014],[18.134222,-7.987678],[17.47297,-8.068551],[17.089996,-7.545689],[16.860191,-7.222298],[16.57318,-6.622645],[16.326528,-5.87747],[13.375597,-5.864241],[13.024869,-5.984389],[12.735171,-5.965682],[12.322432,-6.100092],[12.182337,-5.789931],[12.436688,-5.684304],[12.468004,-5.248362],[12.631612,-4.991271],[12.995517,-4.781103],[13.25824,-4.882957],[13.600235,-4.500138],[14.144956,-4.510009],[14.209035,-4.793092],[14.582604,-4.970239],[15.170992,-4.343507],[15.75354,-3.855165],[16.00629,-3.535133],[15.972803,-2.712392],[16.407092,-1.740927],[16.865307,-1.225816],[17.523716,-0.74383],[17.638645,-0.424832],[17.663553,-0.058084],[17.82654,0.288923],[17.774192,0.855659],[17.898835,1.741832],[18.094276,2.365722],[18.393792,2.900443],[18.453065,3.504386],[18.542982,4.201785],[18.932312,4.709506],[19.467784,5.031528],[20.290679,4.691678],[20.927591,4.322786],[21.659123,4.224342],[22.405124,4.02916],[22.704124,4.633051],[22.84148,4.710126],[23.297214,4.609693],[24.410531,5.108784],[24.805029,4.897247],[25.128833,4.927245],[25.278798,5.170408],[25.650455,5.256088],[26.402761,5.150875],[27.044065,5.127853],[27.374226,5.233944],[27.979977,4.408413],[28.428994,4.287155],[28.696678,4.455077],[29.159078,4.389267],[29.715995,4.600805],[29.9535,4.173699],[30.83386,3.509166]]]}}, {"type":"Feature","id":"COG","properties":{"name":"Republic of the Congo"},"geometry":{"type":"Polygon","coordinates":[[[12.995517,-4.781103],[12.62076,-4.438023],[12.318608,-4.60623],[11.914963,-5.037987],[11.093773,-3.978827],[11.855122,-3.426871],[11.478039,-2.765619],[11.820964,-2.514161],[12.495703,-2.391688],[12.575284,-1.948511],[13.109619,-2.42874],[13.992407,-2.470805],[14.29921,-1.998276],[14.425456,-1.333407],[14.316418,-0.552627],[13.843321,0.038758],[14.276266,1.19693],[14.026669,1.395677],[13.282631,1.314184],[13.003114,1.830896],[13.075822,2.267097],[14.337813,2.227875],[15.146342,1.964015],[15.940919,1.727673],[16.012852,2.26764],[16.537058,3.198255],[17.133042,3.728197],[17.8099,3.560196],[18.453065,3.504386],[18.393792,2.900443],[18.094276,2.365722],[17.898835,1.741832],[17.774192,0.855659],[17.82654,0.288923],[17.663553,-0.058084],[17.638645,-0.424832],[17.523716,-0.74383],[16.865307,-1.225816],[16.407092,-1.740927],[15.972803,-2.712392],[16.00629,-3.535133],[15.75354,-3.855165],[15.170992,-4.343507],[14.582604,-4.970239],[14.209035,-4.793092],[14.144956,-4.510009],[13.600235,-4.500138],[13.25824,-4.882957],[12.995517,-4.781103]]]}}, {"type":"Feature","id":"COL","properties":{"name":"Colombia"},"geometry":{"type":"Polygon","coordinates":[[[-75.373223,-0.152032],[-75.801466,0.084801],[-76.292314,0.416047],[-76.57638,0.256936],[-77.424984,0.395687],[-77.668613,0.825893],[-77.855061,0.809925],[-78.855259,1.380924],[-78.990935,1.69137],[-78.617831,1.766404],[-78.662118,2.267355],[-78.42761,2.629556],[-77.931543,2.696606],[-77.510431,3.325017],[-77.12769,3.849636],[-77.496272,4.087606],[-77.307601,4.667984],[-77.533221,5.582812],[-77.318815,5.845354],[-77.476661,6.691116],[-77.881571,7.223771],[-77.753414,7.70984],[-77.431108,7.638061],[-77.242566,7.935278],[-77.474723,8.524286],[-77.353361,8.670505],[-76.836674,8.638749],[-76.086384,9.336821],[-75.6746,9.443248],[-75.664704,9.774003],[-75.480426,10.61899],[-74.906895,11.083045],[-74.276753,11.102036],[-74.197223,11.310473],[-73.414764,11.227015],[-72.627835,11.731972],[-72.238195,11.95555],[-71.75409,12.437303],[-71.399822,12.376041],[-71.137461,12.112982],[-71.331584,11.776284],[-71.973922,11.608672],[-72.227575,11.108702],[-72.614658,10.821975],[-72.905286,10.450344],[-73.027604,9.73677],[-73.304952,9.152],[-72.78873,9.085027],[-72.660495,8.625288],[-72.439862,8.405275],[-72.360901,8.002638],[-72.479679,7.632506],[-72.444487,7.423785],[-72.198352,7.340431],[-71.960176,6.991615],[-70.674234,7.087785],[-70.093313,6.960376],[-69.38948,6.099861],[-68.985319,6.206805],[-68.265052,6.153268],[-67.695087,6.267318],[-67.34144,6.095468],[-67.521532,5.55687],[-67.744697,5.221129],[-67.823012,4.503937],[-67.621836,3.839482],[-67.337564,3.542342],[-67.303173,3.318454],[-67.809938,2.820655],[-67.447092,2.600281],[-67.181294,2.250638],[-66.876326,1.253361],[-67.065048,1.130112],[-67.259998,1.719999],[-67.53781,2.037163],[-67.868565,1.692455],[-69.816973,1.714805],[-69.804597,1.089081],[-69.218638,0.985677],[-69.252434,0.602651],[-69.452396,0.706159],[-70.015566,0.541414],[-70.020656,-0.185156],[-69.577065,-0.549992],[-69.420486,-1.122619],[-69.444102,-1.556287],[-69.893635,-4.298187],[-70.394044,-3.766591],[-70.692682,-3.742872],[-70.047709,-2.725156],[-70.813476,-2.256865],[-71.413646,-2.342802],[-71.774761,-2.16979],[-72.325787,-2.434218],[-73.070392,-2.308954],[-73.659504,-1.260491],[-74.122395,-1.002833],[-74.441601,-0.53082],[-75.106625,-0.057205],[-75.373223,-0.152032]]]}}, {"type":"Feature","id":"CRI","properties":{"name":"Costa Rica"},"geometry":{"type":"Polygon","coordinates":[[[-82.965783,8.225028],[-83.508437,8.446927],[-83.711474,8.656836],[-83.596313,8.830443],[-83.632642,9.051386],[-83.909886,9.290803],[-84.303402,9.487354],[-84.647644,9.615537],[-84.713351,9.908052],[-84.97566,10.086723],[-84.911375,9.795992],[-85.110923,9.55704],[-85.339488,9.834542],[-85.660787,9.933347],[-85.797445,10.134886],[-85.791709,10.439337],[-85.659314,10.754331],[-85.941725,10.895278],[-85.71254,11.088445],[-85.561852,11.217119],[-84.903003,10.952303],[-84.673069,11.082657],[-84.355931,10.999226],[-84.190179,10.79345],[-83.895054,10.726839],[-83.655612,10.938764],[-83.40232,10.395438],[-83.015677,9.992982],[-82.546196,9.566135],[-82.932891,9.476812],[-82.927155,9.07433],[-82.719183,8.925709],[-82.868657,8.807266],[-82.829771,8.626295],[-82.913176,8.423517],[-82.965783,8.225028]]]}}, {"type":"Feature","id":"CUB","properties":{"name":"Cuba"},"geometry":{"type":"Polygon","coordinates":[[[-82.268151,23.188611],[-81.404457,23.117271],[-80.618769,23.10598],[-79.679524,22.765303],[-79.281486,22.399202],[-78.347434,22.512166],[-77.993296,22.277194],[-77.146422,21.657851],[-76.523825,21.20682],[-76.19462,21.220565],[-75.598222,21.016624],[-75.67106,20.735091],[-74.933896,20.693905],[-74.178025,20.284628],[-74.296648,20.050379],[-74.961595,19.923435],[-75.63468,19.873774],[-76.323656,19.952891],[-77.755481,19.855481],[-77.085108,20.413354],[-77.492655,20.673105],[-78.137292,20.739949],[-78.482827,21.028613],[-78.719867,21.598114],[-79.285,21.559175],[-80.217475,21.827324],[-80.517535,22.037079],[-81.820943,22.192057],[-82.169992,22.387109],[-81.795002,22.636965],[-82.775898,22.68815],[-83.494459,22.168518],[-83.9088,22.154565],[-84.052151,21.910575],[-84.54703,21.801228],[-84.974911,21.896028],[-84.447062,22.20495],[-84.230357,22.565755],[-83.77824,22.788118],[-83.267548,22.983042],[-82.510436,23.078747],[-82.268151,23.188611]]]}}, {"type":"Feature","id":"-99","properties":{"name":"Northern Cyprus"},"geometry":{"type":"Polygon","coordinates":[[[32.73178,35.140026],[32.802474,35.145504],[32.946961,35.386703],[33.667227,35.373216],[34.576474,35.671596],[33.900804,35.245756],[33.973617,35.058506],[33.86644,35.093595],[33.675392,35.017863],[33.525685,35.038688],[33.475817,35.000345],[33.455922,35.101424],[33.383833,35.162712],[33.190977,35.173125],[32.919572,35.087833],[32.73178,35.140026]]]}}, {"type":"Feature","id":"CYP","properties":{"name":"Cyprus"},"geometry":{"type":"Polygon","coordinates":[[[33.973617,35.058506],[34.004881,34.978098],[32.979827,34.571869],[32.490296,34.701655],[32.256667,35.103232],[32.73178,35.140026],[32.919572,35.087833],[33.190977,35.173125],[33.383833,35.162712],[33.455922,35.101424],[33.475817,35.000345],[33.525685,35.038688],[33.675392,35.017863],[33.86644,35.093595],[33.973617,35.058506]]]}}, {"type":"Feature","id":"CZE","properties":{"name":"Czech Republic"},"geometry":{"type":"Polygon","coordinates":[[[16.960288,48.596982],[16.499283,48.785808],[16.029647,48.733899],[15.253416,49.039074],[14.901447,48.964402],[14.338898,48.555305],[13.595946,48.877172],[13.031329,49.307068],[12.521024,49.547415],[12.415191,49.969121],[12.240111,50.266338],[12.966837,50.484076],[13.338132,50.733234],[14.056228,50.926918],[14.307013,51.117268],[14.570718,51.002339],[15.016996,51.106674],[15.490972,50.78473],[16.238627,50.697733],[16.176253,50.422607],[16.719476,50.215747],[16.868769,50.473974],[17.554567,50.362146],[17.649445,50.049038],[18.392914,49.988629],[18.853144,49.49623],[18.554971,49.495015],[18.399994,49.315001],[18.170498,49.271515],[18.104973,49.043983],[17.913512,48.996493],[17.886485,48.903475],[17.545007,48.800019],[17.101985,48.816969],[16.960288,48.596982]]]}}, {"type":"Feature","id":"DEU","properties":{"name":"Germany"},"geometry":{"type":"Polygon","coordinates":[[[9.921906,54.983104],[9.93958,54.596642],[10.950112,54.363607],[10.939467,54.008693],[11.956252,54.196486],[12.51844,54.470371],[13.647467,54.075511],[14.119686,53.757029],[14.353315,53.248171],[14.074521,52.981263],[14.4376,52.62485],[14.685026,52.089947],[14.607098,51.745188],[15.016996,51.106674],[14.570718,51.002339],[14.307013,51.117268],[14.056228,50.926918],[13.338132,50.733234],[12.966837,50.484076],[12.240111,50.266338],[12.415191,49.969121],[12.521024,49.547415],[13.031329,49.307068],[13.595946,48.877172],[13.243357,48.416115],[12.884103,48.289146],[13.025851,47.637584],[12.932627,47.467646],[12.62076,47.672388],[12.141357,47.703083],[11.426414,47.523766],[10.544504,47.566399],[10.402084,47.302488],[9.896068,47.580197],[9.594226,47.525058],[8.522612,47.830828],[8.317301,47.61358],[7.466759,47.620582],[7.593676,48.333019],[8.099279,49.017784],[6.65823,49.201958],[6.18632,49.463803],[6.242751,49.902226],[6.043073,50.128052],[6.156658,50.803721],[5.988658,51.851616],[6.589397,51.852029],[6.84287,52.22844],[7.092053,53.144043],[6.90514,53.482162],[7.100425,53.693932],[7.936239,53.748296],[8.121706,53.527792],[8.800734,54.020786],[8.572118,54.395646],[8.526229,54.962744],[9.282049,54.830865],[9.921906,54.983104]]]}}, {"type":"Feature","id":"DJI","properties":{"name":"Djibouti"},"geometry":{"type":"Polygon","coordinates":[[[43.081226,12.699639],[43.317852,12.390148],[43.286381,11.974928],[42.715874,11.735641],[43.145305,11.46204],[42.776852,10.926879],[42.55493,11.10511],[42.31414,11.0342],[41.75557,11.05091],[41.73959,11.35511],[41.66176,11.6312],[42,12.1],[42.35156,12.54223],[42.779642,12.455416],[43.081226,12.699639]]]}}, {"type":"Feature","id":"DNK","properties":{"name":"Denmark"},"geometry":{"type":"MultiPolygon","coordinates":[[[[12.690006,55.609991],[12.089991,54.800015],[11.043543,55.364864],[10.903914,55.779955],[12.370904,56.111407],[12.690006,55.609991]]],[[[10.912182,56.458621],[10.667804,56.081383],[10.369993,56.190007],[9.649985,55.469999],[9.921906,54.983104],[9.282049,54.830865],[8.526229,54.962744],[8.120311,55.517723],[8.089977,56.540012],[8.256582,56.809969],[8.543438,57.110003],[9.424469,57.172066],[9.775559,57.447941],[10.580006,57.730017],[10.546106,57.215733],[10.25,56.890016],[10.369993,56.609982],[10.912182,56.458621]]]]}}, {"type":"Feature","id":"DOM","properties":{"name":"Dominican Republic"},"geometry":{"type":"Polygon","coordinates":[[[-71.712361,19.714456],[-71.587304,19.884911],[-70.806706,19.880286],[-70.214365,19.622885],[-69.950815,19.648],[-69.76925,19.293267],[-69.222126,19.313214],[-69.254346,19.015196],[-68.809412,18.979074],[-68.317943,18.612198],[-68.689316,18.205142],[-69.164946,18.422648],[-69.623988,18.380713],[-69.952934,18.428307],[-70.133233,18.245915],[-70.517137,18.184291],[-70.669298,18.426886],[-70.99995,18.283329],[-71.40021,17.598564],[-71.657662,17.757573],[-71.708305,18.044997],[-71.687738,18.31666],[-71.945112,18.6169],[-71.701303,18.785417],[-71.624873,19.169838],[-71.712361,19.714456]]]}}, {"type":"Feature","id":"DZA","properties":{"name":"Algeria"},"geometry":{"type":"Polygon","coordinates":[[[11.999506,23.471668],[8.572893,21.565661],[5.677566,19.601207],[4.267419,19.155265],[3.158133,19.057364],[3.146661,19.693579],[2.683588,19.85623],[2.060991,20.142233],[1.823228,20.610809],[-1.550055,22.792666],[-4.923337,24.974574],[-8.6844,27.395744],[-8.665124,27.589479],[-8.66559,27.656426],[-8.674116,28.841289],[-7.059228,29.579228],[-6.060632,29.7317],[-5.242129,30.000443],[-4.859646,30.501188],[-3.690441,30.896952],[-3.647498,31.637294],[-3.06898,31.724498],[-2.616605,32.094346],[-1.307899,32.262889],[-1.124551,32.651522],[-1.388049,32.864015],[-1.733455,33.919713],[-1.792986,34.527919],[-2.169914,35.168396],[-1.208603,35.714849],[-0.127454,35.888662],[0.503877,36.301273],[1.466919,36.605647],[3.161699,36.783905],[4.815758,36.865037],[5.32012,36.716519],[6.26182,37.110655],[7.330385,37.118381],[7.737078,36.885708],[8.420964,36.946427],[8.217824,36.433177],[8.376368,35.479876],[8.140981,34.655146],[7.524482,34.097376],[7.612642,33.344115],[8.430473,32.748337],[8.439103,32.506285],[9.055603,32.102692],[9.48214,30.307556],[9.805634,29.424638],[9.859998,28.95999],[9.683885,28.144174],[9.756128,27.688259],[9.629056,27.140953],[9.716286,26.512206],[9.319411,26.094325],[9.910693,25.365455],[9.948261,24.936954],[10.303847,24.379313],[10.771364,24.562532],[11.560669,24.097909],[11.999506,23.471668]]]}}, {"type":"Feature","id":"ECU","properties":{"name":"Ecuador"},"geometry":{"type":"Polygon","coordinates":[[[-80.302561,-3.404856],[-79.770293,-2.657512],[-79.986559,-2.220794],[-80.368784,-2.685159],[-80.967765,-2.246943],[-80.764806,-1.965048],[-80.933659,-1.057455],[-80.58337,-0.906663],[-80.399325,-0.283703],[-80.020898,0.36034],[-80.09061,0.768429],[-79.542762,0.982938],[-78.855259,1.380924],[-77.855061,0.809925],[-77.668613,0.825893],[-77.424984,0.395687],[-76.57638,0.256936],[-76.292314,0.416047],[-75.801466,0.084801],[-75.373223,-0.152032],[-75.233723,-0.911417],[-75.544996,-1.56161],[-76.635394,-2.608678],[-77.837905,-3.003021],[-78.450684,-3.873097],[-78.639897,-4.547784],[-79.205289,-4.959129],[-79.624979,-4.454198],[-80.028908,-4.346091],[-80.442242,-4.425724],[-80.469295,-4.059287],[-80.184015,-3.821162],[-80.302561,-3.404856]]]}}, {"type":"Feature","id":"EGY","properties":{"name":"Egypt"},"geometry":{"type":"Polygon","coordinates":[[[34.9226,29.50133],[34.64174,29.09942],[34.42655,28.34399],[34.15451,27.8233],[33.92136,27.6487],[33.58811,27.97136],[33.13676,28.41765],[32.42323,29.85108],[32.32046,29.76043],[32.73482,28.70523],[33.34876,27.69989],[34.10455,26.14227],[34.47387,25.59856],[34.79507,25.03375],[35.69241,23.92671],[35.49372,23.75237],[35.52598,23.10244],[36.69069,22.20485],[36.86623,22],[32.9,22],[29.02,22],[25,22],[25,25.6825],[25,29.238655],[24.70007,30.04419],[24.95762,30.6616],[24.80287,31.08929],[25.16482,31.56915],[26.49533,31.58568],[27.45762,31.32126],[28.45048,31.02577],[28.91353,30.87005],[29.68342,31.18686],[30.09503,31.4734],[30.97693,31.55586],[31.68796,31.4296],[31.96041,30.9336],[32.19247,31.26034],[32.99392,31.02407],[33.7734,30.96746],[34.26544,31.21936],[34.9226,29.50133]]]}}, {"type":"Feature","id":"ERI","properties":{"name":"Eritrea"},"geometry":{"type":"Polygon","coordinates":[[[42.35156,12.54223],[42.00975,12.86582],[41.59856,13.45209],[41.155194,13.77332],[40.8966,14.11864],[40.026219,14.519579],[39.34061,14.53155],[39.0994,14.74064],[38.51295,14.50547],[37.90607,14.95943],[37.59377,14.2131],[36.42951,14.42211],[36.323189,14.822481],[36.75386,16.291874],[36.85253,16.95655],[37.16747,17.26314],[37.904,17.42754],[38.41009,17.998307],[38.990623,16.840626],[39.26611,15.922723],[39.814294,15.435647],[41.179275,14.49108],[41.734952,13.921037],[42.276831,13.343992],[42.589576,13.000421],[43.081226,12.699639],[42.779642,12.455416],[42.35156,12.54223]]]}}, {"type":"Feature","id":"ESP","properties":{"name":"Spain"},"geometry":{"type":"Polygon","coordinates":[[[-9.034818,41.880571],[-8.984433,42.592775],[-9.392884,43.026625],[-7.97819,43.748338],[-6.754492,43.567909],[-5.411886,43.57424],[-4.347843,43.403449],[-3.517532,43.455901],[-1.901351,43.422802],[-1.502771,43.034014],[0.338047,42.579546],[0.701591,42.795734],[1.826793,42.343385],[2.985999,42.473015],[3.039484,41.89212],[2.091842,41.226089],[0.810525,41.014732],[0.721331,40.678318],[0.106692,40.123934],[-0.278711,39.309978],[0.111291,38.738514],[-0.467124,38.292366],[-0.683389,37.642354],[-1.438382,37.443064],[-2.146453,36.674144],[-3.415781,36.6589],[-4.368901,36.677839],[-4.995219,36.324708],[-5.37716,35.94685],[-5.866432,36.029817],[-6.236694,36.367677],[-6.520191,36.942913],[-7.453726,37.097788],[-7.537105,37.428904],[-7.166508,37.803894],[-7.029281,38.075764],[-7.374092,38.373059],[-7.098037,39.030073],[-7.498632,39.629571],[-7.066592,39.711892],[-7.026413,40.184524],[-6.86402,40.330872],[-6.851127,41.111083],[-6.389088,41.381815],[-6.668606,41.883387],[-7.251309,41.918346],[-7.422513,41.792075],[-8.013175,41.790886],[-8.263857,42.280469],[-8.671946,42.134689],[-9.034818,41.880571]]]}}, {"type":"Feature","id":"EST","properties":{"name":"Estonia"},"geometry":{"type":"Polygon","coordinates":[[[24.312863,57.793424],[24.428928,58.383413],[24.061198,58.257375],[23.42656,58.612753],[23.339795,59.18724],[24.604214,59.465854],[25.864189,59.61109],[26.949136,59.445803],[27.981114,59.475388],[28.131699,59.300825],[27.420166,58.724581],[27.716686,57.791899],[27.288185,57.474528],[26.463532,57.476389],[25.60281,57.847529],[25.164594,57.970157],[24.312863,57.793424]]]}}, {"type":"Feature","id":"ETH","properties":{"name":"Ethiopia"},"geometry":{"type":"Polygon","coordinates":[[[37.90607,14.95943],[38.51295,14.50547],[39.0994,14.74064],[39.34061,14.53155],[40.02625,14.51959],[40.8966,14.11864],[41.1552,13.77333],[41.59856,13.45209],[42.00975,12.86582],[42.35156,12.54223],[42,12.1],[41.66176,11.6312],[41.73959,11.35511],[41.75557,11.05091],[42.31414,11.0342],[42.55493,11.10511],[42.776852,10.926879],[42.55876,10.57258],[42.92812,10.02194],[43.29699,9.54048],[43.67875,9.18358],[46.94834,7.99688],[47.78942,8.003],[44.9636,5.00162],[43.66087,4.95755],[42.76967,4.25259],[42.12861,4.23413],[41.855083,3.918912],[41.1718,3.91909],[40.76848,4.25702],[39.85494,3.83879],[39.559384,3.42206],[38.89251,3.50074],[38.67114,3.61607],[38.43697,3.58851],[38.120915,3.598605],[36.855093,4.447864],[36.159079,4.447864],[35.817448,4.776966],[35.817448,5.338232],[35.298007,5.506],[34.70702,6.59422],[34.25032,6.82607],[34.0751,7.22595],[33.56829,7.71334],[32.95418,7.78497],[33.2948,8.35458],[33.8255,8.37916],[33.97498,8.68456],[33.96162,9.58358],[34.25745,10.63009],[34.73115,10.91017],[34.83163,11.31896],[35.26049,12.08286],[35.86363,12.57828],[36.27022,13.56333],[36.42951,14.42211],[37.59377,14.2131],[37.90607,14.95943]]]}}, {"type":"Feature","id":"FIN","properties":{"name":"Finland"},"geometry":{"type":"Polygon","coordinates":[[[28.59193,69.064777],[28.445944,68.364613],[29.977426,67.698297],[29.054589,66.944286],[30.21765,65.80598],[29.54443,64.948672],[30.444685,64.204453],[30.035872,63.552814],[31.516092,62.867687],[31.139991,62.357693],[30.211107,61.780028],[28.069998,60.503517],[26.255173,60.423961],[24.496624,60.057316],[22.869695,59.846373],[22.290764,60.391921],[21.322244,60.72017],[21.544866,61.705329],[21.059211,62.607393],[21.536029,63.189735],[22.442744,63.81781],[24.730512,64.902344],[25.398068,65.111427],[25.294043,65.534346],[23.903379,66.006927],[23.56588,66.396051],[23.539473,67.936009],[21.978535,68.616846],[20.645593,69.106247],[21.244936,69.370443],[22.356238,68.841741],[23.66205,68.891247],[24.735679,68.649557],[25.689213,69.092114],[26.179622,69.825299],[27.732292,70.164193],[29.015573,69.766491],[28.59193,69.064777]]]}}, {"type":"Feature","id":"FJI","properties":{"name":"Fiji"},"geometry":{"type":"MultiPolygon","coordinates":[[[[178.3736,-17.33992],[178.71806,-17.62846],[178.55271,-18.15059],[177.93266,-18.28799],[177.38146,-18.16432],[177.28504,-17.72465],[177.67087,-17.38114],[178.12557,-17.50481],[178.3736,-17.33992]]],[[[179.364143,-16.801354],[178.725059,-17.012042],[178.596839,-16.63915],[179.096609,-16.433984],[179.413509,-16.379054],[180,-16.067133],[180,-16.555217],[179.364143,-16.801354]]],[[[-179.917369,-16.501783],[-180,-16.555217],[-180,-16.067133],[-179.79332,-16.020882],[-179.917369,-16.501783]]]]}}, {"type":"Feature","id":"FLK","properties":{"name":"Falkland Islands"},"geometry":{"type":"Polygon","coordinates":[[[-61.2,-51.85],[-60,-51.25],[-59.15,-51.5],[-58.55,-51.1],[-57.75,-51.55],[-58.05,-51.9],[-59.4,-52.2],[-59.85,-51.85],[-60.7,-52.3],[-61.2,-51.85]]]}}, {"type":"Feature","id":"FRA","properties":{"name":"France"},"geometry":{"type":"MultiPolygon","coordinates":[[[[9.560016,42.152492],[9.229752,41.380007],[8.775723,41.583612],[8.544213,42.256517],[8.746009,42.628122],[9.390001,43.009985],[9.560016,42.152492]]],[[[3.588184,50.378992],[4.286023,49.907497],[4.799222,49.985373],[5.674052,49.529484],[5.897759,49.442667],[6.18632,49.463803],[6.65823,49.201958],[8.099279,49.017784],[7.593676,48.333019],[7.466759,47.620582],[7.192202,47.449766],[6.736571,47.541801],[6.768714,47.287708],[6.037389,46.725779],[6.022609,46.27299],[6.5001,46.429673],[6.843593,45.991147],[6.802355,45.70858],[7.096652,45.333099],[6.749955,45.028518],[7.007562,44.254767],[7.549596,44.127901],[7.435185,43.693845],[6.529245,43.128892],[4.556963,43.399651],[3.100411,43.075201],[2.985999,42.473015],[1.826793,42.343385],[0.701591,42.795734],[0.338047,42.579546],[-1.502771,43.034014],[-1.901351,43.422802],[-1.384225,44.02261],[-1.193798,46.014918],[-2.225724,47.064363],[-2.963276,47.570327],[-4.491555,47.954954],[-4.59235,48.68416],[-3.295814,48.901692],[-1.616511,48.644421],[-1.933494,49.776342],[-0.989469,49.347376],[1.338761,50.127173],[1.639001,50.946606],[2.513573,51.148506],[2.658422,50.796848],[3.123252,50.780363],[3.588184,50.378992]]]]}}, {"type":"Feature","id":"GAB","properties":{"name":"Gabon"},"geometry":{"type":"Polygon","coordinates":[[[11.093773,-3.978827],[10.066135,-2.969483],[9.405245,-2.144313],[8.797996,-1.111301],[8.830087,-0.779074],[9.04842,-0.459351],[9.291351,0.268666],[9.492889,1.01012],[9.830284,1.067894],[11.285079,1.057662],[11.276449,2.261051],[11.751665,2.326758],[12.35938,2.192812],[12.951334,2.321616],[13.075822,2.267097],[13.003114,1.830896],[13.282631,1.314184],[14.026669,1.395677],[14.276266,1.19693],[13.843321,0.038758],[14.316418,-0.552627],[14.425456,-1.333407],[14.29921,-1.998276],[13.992407,-2.470805],[13.109619,-2.42874],[12.575284,-1.948511],[12.495703,-2.391688],[11.820964,-2.514161],[11.478039,-2.765619],[11.855122,-3.426871],[11.093773,-3.978827]]]}}, {"type":"Feature","id":"GBR","properties":{"name":"United Kingdom"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-5.661949,54.554603],[-6.197885,53.867565],[-6.95373,54.073702],[-7.572168,54.059956],[-7.366031,54.595841],[-7.572168,55.131622],[-6.733847,55.17286],[-5.661949,54.554603]]],[[[-3.005005,58.635],[-4.073828,57.553025],[-3.055002,57.690019],[-1.959281,57.6848],[-2.219988,56.870017],[-3.119003,55.973793],[-2.085009,55.909998],[-2.005676,55.804903],[-1.114991,54.624986],[-0.430485,54.464376],[0.184981,53.325014],[0.469977,52.929999],[1.681531,52.73952],[1.559988,52.099998],[1.050562,51.806761],[1.449865,51.289428],[0.550334,50.765739],[-0.787517,50.774989],[-2.489998,50.500019],[-2.956274,50.69688],[-3.617448,50.228356],[-4.542508,50.341837],[-5.245023,49.96],[-5.776567,50.159678],[-4.30999,51.210001],[-3.414851,51.426009],[-3.422719,51.426848],[-4.984367,51.593466],[-5.267296,51.9914],[-4.222347,52.301356],[-4.770013,52.840005],[-4.579999,53.495004],[-3.093831,53.404547],[-3.09208,53.404441],[-2.945009,53.985],[-3.614701,54.600937],[-3.630005,54.615013],[-4.844169,54.790971],[-5.082527,55.061601],[-4.719112,55.508473],[-5.047981,55.783986],[-5.586398,55.311146],[-5.644999,56.275015],[-6.149981,56.78501],[-5.786825,57.818848],[-5.009999,58.630013],[-4.211495,58.550845],[-3.005005,58.635]]]]}}, {"type":"Feature","id":"GEO","properties":{"name":"Georgia"},"geometry":{"type":"Polygon","coordinates":[[[41.554084,41.535656],[41.703171,41.962943],[41.45347,42.645123],[40.875469,43.013628],[40.321394,43.128634],[39.955009,43.434998],[40.076965,43.553104],[40.922185,43.382159],[42.394395,43.220308],[43.756017,42.740828],[43.9312,42.554974],[44.537623,42.711993],[45.470279,42.502781],[45.77641,42.092444],[46.404951,41.860675],[46.145432,41.722802],[46.637908,41.181673],[46.501637,41.064445],[45.962601,41.123873],[45.217426,41.411452],[44.97248,41.248129],[43.582746,41.092143],[42.619549,41.583173],[41.554084,41.535656]]]}}, {"type":"Feature","id":"GHA","properties":{"name":"Ghana"},"geometry":{"type":"Polygon","coordinates":[[[1.060122,5.928837],[-0.507638,5.343473],[-1.063625,5.000548],[-1.964707,4.710462],[-2.856125,4.994476],[-2.810701,5.389051],[-3.24437,6.250472],[-2.983585,7.379705],[-2.56219,8.219628],[-2.827496,9.642461],[-2.963896,10.395335],[-2.940409,10.96269],[-1.203358,11.009819],[-0.761576,10.93693],[-0.438702,11.098341],[0.023803,11.018682],[-0.049785,10.706918],[0.36758,10.191213],[0.365901,9.465004],[0.461192,8.677223],[0.712029,8.312465],[0.490957,7.411744],[0.570384,6.914359],[0.836931,6.279979],[1.060122,5.928837]]]}}, {"type":"Feature","id":"GIN","properties":{"name":"Guinea"},"geometry":{"type":"Polygon","coordinates":[[[-8.439298,7.686043],[-8.722124,7.711674],[-8.926065,7.309037],[-9.208786,7.313921],[-9.403348,7.526905],[-9.33728,7.928534],[-9.755342,8.541055],[-10.016567,8.428504],[-10.230094,8.406206],[-10.505477,8.348896],[-10.494315,8.715541],[-10.65477,8.977178],[-10.622395,9.26791],[-10.839152,9.688246],[-11.117481,10.045873],[-11.917277,10.046984],[-12.150338,9.858572],[-12.425929,9.835834],[-12.596719,9.620188],[-12.711958,9.342712],[-13.24655,8.903049],[-13.685154,9.494744],[-14.074045,9.886167],[-14.330076,10.01572],[-14.579699,10.214467],[-14.693232,10.656301],[-14.839554,10.876572],[-15.130311,11.040412],[-14.685687,11.527824],[-14.382192,11.509272],[-14.121406,11.677117],[-13.9008,11.678719],[-13.743161,11.811269],[-13.828272,12.142644],[-13.718744,12.247186],[-13.700476,12.586183],[-13.217818,12.575874],[-12.499051,12.33209],[-12.278599,12.35444],[-12.203565,12.465648],[-11.658301,12.386583],[-11.513943,12.442988],[-11.456169,12.076834],[-11.297574,12.077971],[-11.036556,12.211245],[-10.87083,12.177887],[-10.593224,11.923975],[-10.165214,11.844084],[-9.890993,12.060479],[-9.567912,12.194243],[-9.327616,12.334286],[-9.127474,12.30806],[-8.905265,12.088358],[-8.786099,11.812561],[-8.376305,11.393646],[-8.581305,11.136246],[-8.620321,10.810891],[-8.407311,10.909257],[-8.282357,10.792597],[-8.335377,10.494812],[-8.029944,10.206535],[-8.229337,10.12902],[-8.309616,9.789532],[-8.079114,9.376224],[-7.8321,8.575704],[-8.203499,8.455453],[-8.299049,8.316444],[-8.221792,8.123329],[-8.280703,7.68718],[-8.439298,7.686043]]]}}, {"type":"Feature","id":"GMB","properties":{"name":"Gambia"},"geometry":{"type":"Polygon","coordinates":[[[-16.841525,13.151394],[-16.713729,13.594959],[-15.624596,13.623587],[-15.39877,13.860369],[-15.081735,13.876492],[-14.687031,13.630357],[-14.376714,13.62568],[-14.046992,13.794068],[-13.844963,13.505042],[-14.277702,13.280585],[-14.712197,13.298207],[-15.141163,13.509512],[-15.511813,13.27857],[-15.691001,13.270353],[-15.931296,13.130284],[-16.841525,13.151394]]]}}, {"type":"Feature","id":"GNB","properties":{"name":"Guinea Bissau"},"geometry":{"type":"Polygon","coordinates":[[[-15.130311,11.040412],[-15.66418,11.458474],[-16.085214,11.524594],[-16.314787,11.806515],[-16.308947,11.958702],[-16.613838,12.170911],[-16.677452,12.384852],[-16.147717,12.547762],[-15.816574,12.515567],[-15.548477,12.62817],[-13.700476,12.586183],[-13.718744,12.247186],[-13.828272,12.142644],[-13.743161,11.811269],[-13.9008,11.678719],[-14.121406,11.677117],[-14.382192,11.509272],[-14.685687,11.527824],[-15.130311,11.040412]]]}}, {"type":"Feature","id":"GNQ","properties":{"name":"Equatorial Guinea"},"geometry":{"type":"Polygon","coordinates":[[[9.492889,1.01012],[9.305613,1.160911],[9.649158,2.283866],[11.276449,2.261051],[11.285079,1.057662],[9.830284,1.067894],[9.492889,1.01012]]]}}, {"type":"Feature","id":"GRC","properties":{"name":"Greece"},"geometry":{"type":"MultiPolygon","coordinates":[[[[23.69998,35.705004],[24.246665,35.368022],[25.025015,35.424996],[25.769208,35.354018],[25.745023,35.179998],[26.290003,35.29999],[26.164998,35.004995],[24.724982,34.919988],[24.735007,35.084991],[23.514978,35.279992],[23.69998,35.705004]]],[[[26.604196,41.562115],[26.294602,40.936261],[26.056942,40.824123],[25.447677,40.852545],[24.925848,40.947062],[23.714811,40.687129],[24.407999,40.124993],[23.899968,39.962006],[23.342999,39.960998],[22.813988,40.476005],[22.626299,40.256561],[22.849748,39.659311],[23.350027,39.190011],[22.973099,38.970903],[23.530016,38.510001],[24.025025,38.219993],[24.040011,37.655015],[23.115003,37.920011],[23.409972,37.409991],[22.774972,37.30501],[23.154225,36.422506],[22.490028,36.41],[21.670026,36.844986],[21.295011,37.644989],[21.120034,38.310323],[20.730032,38.769985],[20.217712,39.340235],[20.150016,39.624998],[20.615,40.110007],[20.674997,40.435],[20.99999,40.580004],[21.02004,40.842727],[21.674161,40.931275],[22.055378,41.149866],[22.597308,41.130487],[22.76177,41.3048],[22.952377,41.337994],[23.692074,41.309081],[24.492645,41.583896],[25.197201,41.234486],[26.106138,41.328899],[26.117042,41.826905],[26.604196,41.562115]]]]}}, {"type":"Feature","id":"GRL","properties":{"name":"Greenland"},"geometry":{"type":"Polygon","coordinates":[[[-46.76379,82.62796],[-43.40644,83.22516],[-39.89753,83.18018],[-38.62214,83.54905],[-35.08787,83.64513],[-27.10046,83.51966],[-20.84539,82.72669],[-22.69182,82.34165],[-26.51753,82.29765],[-31.9,82.2],[-31.39646,82.02154],[-27.85666,82.13178],[-24.84448,81.78697],[-22.90328,82.09317],[-22.07175,81.73449],[-23.16961,81.15271],[-20.62363,81.52462],[-15.76818,81.91245],[-12.77018,81.71885],[-12.20855,81.29154],[-16.28533,80.58004],[-16.85,80.35],[-20.04624,80.17708],[-17.73035,80.12912],[-18.9,79.4],[-19.70499,78.75128],[-19.67353,77.63859],[-18.47285,76.98565],[-20.03503,76.94434],[-21.67944,76.62795],[-19.83407,76.09808],[-19.59896,75.24838],[-20.66818,75.15585],[-19.37281,74.29561],[-21.59422,74.22382],[-20.43454,73.81713],[-20.76234,73.46436],[-22.17221,73.30955],[-23.56593,73.30663],[-22.31311,72.62928],[-22.29954,72.18409],[-24.27834,72.59788],[-24.79296,72.3302],[-23.44296,72.08016],[-22.13281,71.46898],[-21.75356,70.66369],[-23.53603,70.471],[-24.30702,70.85649],[-25.54341,71.43094],[-25.20135,70.75226],[-26.36276,70.22646],[-23.72742,70.18401],[-22.34902,70.12946],[-25.02927,69.2588],[-27.74737,68.47046],[-30.67371,68.12503],[-31.77665,68.12078],[-32.81105,67.73547],[-34.20196,66.67974],[-36.35284,65.9789],[-37.04378,65.93768],[-38.37505,65.69213],[-39.81222,65.45848],[-40.66899,64.83997],[-40.68281,64.13902],[-41.1887,63.48246],[-42.81938,62.68233],[-42.41666,61.90093],[-42.86619,61.07404],[-43.3784,60.09772],[-44.7875,60.03676],[-46.26364,60.85328],[-48.26294,60.85843],[-49.23308,61.40681],[-49.90039,62.38336],[-51.63325,63.62691],[-52.14014,64.27842],[-52.27659,65.1767],[-53.66166,66.09957],[-53.30161,66.8365],[-53.96911,67.18899],[-52.9804,68.35759],[-51.47536,68.72958],[-51.08041,69.14781],[-50.87122,69.9291],[-52.013585,69.574925],[-52.55792,69.42616],[-53.45629,69.283625],[-54.68336,69.61003],[-54.75001,70.28932],[-54.35884,70.821315],[-53.431315,70.835755],[-51.39014,70.56978],[-53.10937,71.20485],[-54.00422,71.54719],[-55,71.406537],[-55.83468,71.65444],[-54.71819,72.58625],[-55.32634,72.95861],[-56.12003,73.64977],[-57.32363,74.71026],[-58.59679,75.09861],[-58.58516,75.51727],[-61.26861,76.10238],[-63.39165,76.1752],[-66.06427,76.13486],[-68.50438,76.06141],[-69.66485,76.37975],[-71.40257,77.00857],[-68.77671,77.32312],[-66.76397,77.37595],[-71.04293,77.63595],[-73.297,78.04419],[-73.15938,78.43271],[-69.37345,78.91388],[-65.7107,79.39436],[-65.3239,79.75814],[-68.02298,80.11721],[-67.15129,80.51582],[-63.68925,81.21396],[-62.23444,81.3211],[-62.65116,81.77042],[-60.28249,82.03363],[-57.20744,82.19074],[-54.13442,82.19962],[-53.04328,81.88833],[-50.39061,82.43883],[-48.00386,82.06481],[-46.59984,81.985945],[-44.523,81.6607],[-46.9007,82.19979],[-46.76379,82.62796]]]}}, {"type":"Feature","id":"GTM","properties":{"name":"Guatemala"},"geometry":{"type":"Polygon","coordinates":[[[-90.095555,13.735338],[-90.608624,13.909771],[-91.23241,13.927832],[-91.689747,14.126218],[-92.22775,14.538829],[-92.20323,14.830103],[-92.087216,15.064585],[-92.229249,15.251447],[-91.74796,16.066565],[-90.464473,16.069562],[-90.438867,16.41011],[-90.600847,16.470778],[-90.711822,16.687483],[-91.08167,16.918477],[-91.453921,17.252177],[-91.002269,17.254658],[-91.00152,17.817595],[-90.067934,17.819326],[-89.14308,17.808319],[-89.150806,17.015577],[-89.229122,15.886938],[-88.930613,15.887273],[-88.604586,15.70638],[-88.518364,15.855389],[-88.225023,15.727722],[-88.68068,15.346247],[-89.154811,15.066419],[-89.22522,14.874286],[-89.145535,14.678019],[-89.353326,14.424133],[-89.587343,14.362586],[-89.534219,14.244816],[-89.721934,14.134228],[-90.064678,13.88197],[-90.095555,13.735338]]]}}, {"type":"Feature","id":"GUF","properties":{"name":"French Guiana"},"geometry":{"type":"Polygon","coordinates":[[[-52.556425,2.504705],[-52.939657,2.124858],[-53.418465,2.053389],[-53.554839,2.334897],[-53.778521,2.376703],[-54.088063,2.105557],[-54.524754,2.311849],[-54.27123,2.738748],[-54.184284,3.194172],[-54.011504,3.62257],[-54.399542,4.212611],[-54.478633,4.896756],[-53.958045,5.756548],[-53.618453,5.646529],[-52.882141,5.409851],[-51.823343,4.565768],[-51.657797,4.156232],[-52.249338,3.241094],[-52.556425,2.504705]]]}}, {"type":"Feature","id":"GUY","properties":{"name":"Guyana"},"geometry":{"type":"Polygon","coordinates":[[[-59.758285,8.367035],[-59.101684,7.999202],[-58.482962,7.347691],[-58.454876,6.832787],[-58.078103,6.809094],[-57.542219,6.321268],[-57.147436,5.97315],[-57.307246,5.073567],[-57.914289,4.812626],[-57.86021,4.576801],[-58.044694,4.060864],[-57.601569,3.334655],[-57.281433,3.333492],[-57.150098,2.768927],[-56.539386,1.899523],[-56.782704,1.863711],[-57.335823,1.948538],[-57.660971,1.682585],[-58.11345,1.507195],[-58.429477,1.463942],[-58.540013,1.268088],[-59.030862,1.317698],[-59.646044,1.786894],[-59.718546,2.24963],[-59.974525,2.755233],[-59.815413,3.606499],[-59.53804,3.958803],[-59.767406,4.423503],[-60.111002,4.574967],[-59.980959,5.014061],[-60.213683,5.244486],[-60.733574,5.200277],[-61.410303,5.959068],[-61.139415,6.234297],[-61.159336,6.696077],[-60.543999,6.856584],[-60.295668,7.043911],[-60.637973,7.415],[-60.550588,7.779603],[-59.758285,8.367035]]]}}, {"type":"Feature","id":"HND","properties":{"name":"Honduras"},"geometry":{"type":"Polygon","coordinates":[[[-87.316654,12.984686],[-87.489409,13.297535],[-87.793111,13.38448],[-87.723503,13.78505],[-87.859515,13.893312],[-88.065343,13.964626],[-88.503998,13.845486],[-88.541231,13.980155],[-88.843073,14.140507],[-89.058512,14.340029],[-89.353326,14.424133],[-89.145535,14.678019],[-89.22522,14.874286],[-89.154811,15.066419],[-88.68068,15.346247],[-88.225023,15.727722],[-88.121153,15.688655],[-87.901813,15.864458],[-87.61568,15.878799],[-87.522921,15.797279],[-87.367762,15.84694],[-86.903191,15.756713],[-86.440946,15.782835],[-86.119234,15.893449],[-86.001954,16.005406],[-85.683317,15.953652],[-85.444004,15.885749],[-85.182444,15.909158],[-84.983722,15.995923],[-84.52698,15.857224],[-84.368256,15.835158],[-84.063055,15.648244],[-83.773977,15.424072],[-83.410381,15.270903],[-83.147219,14.995829],[-83.489989,15.016267],[-83.628585,14.880074],[-83.975721,14.749436],[-84.228342,14.748764],[-84.449336,14.621614],[-84.649582,14.666805],[-84.820037,14.819587],[-84.924501,14.790493],[-85.052787,14.551541],[-85.148751,14.560197],[-85.165365,14.35437],[-85.514413,14.079012],[-85.698665,13.960078],[-85.801295,13.836055],[-86.096264,14.038187],[-86.312142,13.771356],[-86.520708,13.778487],[-86.755087,13.754845],[-86.733822,13.263093],[-86.880557,13.254204],[-87.005769,13.025794],[-87.316654,12.984686]]]}}, {"type":"Feature","id":"HRV","properties":{"name":"Croatia"},"geometry":{"type":"Polygon","coordinates":[[[18.829838,45.908878],[19.072769,45.521511],[19.390476,45.236516],[19.005486,44.860234],[18.553214,45.08159],[17.861783,45.06774],[17.002146,45.233777],[16.534939,45.211608],[16.318157,45.004127],[15.959367,45.233777],[15.750026,44.818712],[16.23966,44.351143],[16.456443,44.04124],[16.916156,43.667722],[17.297373,43.446341],[17.674922,43.028563],[18.56,42.65],[18.450016,42.479991],[17.50997,42.849995],[16.930006,43.209998],[16.015385,43.507215],[15.174454,44.243191],[15.37625,44.317915],[14.920309,44.738484],[14.901602,45.07606],[14.258748,45.233777],[13.952255,44.802124],[13.656976,45.136935],[13.679403,45.484149],[13.71506,45.500324],[14.411968,45.466166],[14.595109,45.634941],[14.935244,45.471695],[15.327675,45.452316],[15.323954,45.731783],[15.67153,45.834154],[15.768733,46.238108],[16.564808,46.503751],[16.882515,46.380632],[17.630066,45.951769],[18.456062,45.759481],[18.829838,45.908878]]]}}, {"type":"Feature","id":"HTI","properties":{"name":"Haiti"},"geometry":{"type":"Polygon","coordinates":[[[-73.189791,19.915684],[-72.579673,19.871501],[-71.712361,19.714456],[-71.624873,19.169838],[-71.701303,18.785417],[-71.945112,18.6169],[-71.687738,18.31666],[-71.708305,18.044997],[-72.372476,18.214961],[-72.844411,18.145611],[-73.454555,18.217906],[-73.922433,18.030993],[-74.458034,18.34255],[-74.369925,18.664908],[-73.449542,18.526053],[-72.694937,18.445799],[-72.334882,18.668422],[-72.79165,19.101625],[-72.784105,19.483591],[-73.415022,19.639551],[-73.189791,19.915684]]]}}, {"type":"Feature","id":"HUN","properties":{"name":"Hungary"},"geometry":{"type":"Polygon","coordinates":[[[16.202298,46.852386],[16.534268,47.496171],[16.340584,47.712902],[16.903754,47.714866],[16.979667,48.123497],[17.488473,47.867466],[17.857133,47.758429],[18.696513,47.880954],[18.777025,48.081768],[19.174365,48.111379],[19.661364,48.266615],[19.769471,48.202691],[20.239054,48.327567],[20.473562,48.56285],[20.801294,48.623854],[21.872236,48.319971],[22.085608,48.422264],[22.64082,48.15024],[22.710531,47.882194],[22.099768,47.672439],[21.626515,46.994238],[21.021952,46.316088],[20.220192,46.127469],[19.596045,46.17173],[18.829838,45.908878],[18.456062,45.759481],[17.630066,45.951769],[16.882515,46.380632],[16.564808,46.503751],[16.370505,46.841327],[16.202298,46.852386]]]}}, {"type":"Feature","id":"IDN","properties":{"name":"Indonesia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.715609,-10.239581],[120.295014,-10.25865],[118.967808,-9.557969],[119.90031,-9.36134],[120.425756,-9.665921],[120.775502,-9.969675],[120.715609,-10.239581]]],[[[124.43595,-10.140001],[123.579982,-10.359987],[123.459989,-10.239995],[123.550009,-9.900016],[123.980009,-9.290027],[124.968682,-8.89279],[125.07002,-9.089987],[125.08852,-9.393173],[124.43595,-10.140001]]],[[[117.900018,-8.095681],[118.260616,-8.362383],[118.87846,-8.280683],[119.126507,-8.705825],[117.970402,-8.906639],[117.277731,-9.040895],[116.740141,-9.032937],[117.083737,-8.457158],[117.632024,-8.449303],[117.900018,-8.095681]]],[[[122.903537,-8.094234],[122.756983,-8.649808],[121.254491,-8.933666],[119.924391,-8.810418],[119.920929,-8.444859],[120.715092,-8.236965],[121.341669,-8.53674],[122.007365,-8.46062],[122.903537,-8.094234]]],[[[108.623479,-6.777674],[110.539227,-6.877358],[110.759576,-6.465186],[112.614811,-6.946036],[112.978768,-7.594213],[114.478935,-7.776528],[115.705527,-8.370807],[114.564511,-8.751817],[113.464734,-8.348947],[112.559672,-8.376181],[111.522061,-8.302129],[110.58615,-8.122605],[109.427667,-7.740664],[108.693655,-7.6416],[108.277763,-7.766657],[106.454102,-7.3549],[106.280624,-6.9249],[105.365486,-6.851416],[106.051646,-5.895919],[107.265009,-5.954985],[108.072091,-6.345762],[108.486846,-6.421985],[108.623479,-6.777674]]],[[[134.724624,-6.214401],[134.210134,-6.895238],[134.112776,-6.142467],[134.290336,-5.783058],[134.499625,-5.445042],[134.727002,-5.737582],[134.724624,-6.214401]]],[[[127.249215,-3.459065],[126.874923,-3.790983],[126.183802,-3.607376],[125.989034,-3.177273],[127.000651,-3.129318],[127.249215,-3.459065]]],[[[130.471344,-3.093764],[130.834836,-3.858472],[129.990547,-3.446301],[129.155249,-3.362637],[128.590684,-3.428679],[127.898891,-3.393436],[128.135879,-2.84365],[129.370998,-2.802154],[130.471344,-3.093764]]],[[[134.143368,-1.151867],[134.422627,-2.769185],[135.457603,-3.367753],[136.293314,-2.307042],[137.440738,-1.703513],[138.329727,-1.702686],[139.184921,-2.051296],[139.926684,-2.409052],[141.00021,-2.600151],[141.017057,-5.859022],[141.033852,-9.117893],[140.143415,-8.297168],[139.127767,-8.096043],[138.881477,-8.380935],[137.614474,-8.411683],[138.039099,-7.597882],[138.668621,-7.320225],[138.407914,-6.232849],[137.92784,-5.393366],[135.98925,-4.546544],[135.164598,-4.462931],[133.66288,-3.538853],[133.367705,-4.024819],[132.983956,-4.112979],[132.756941,-3.746283],[132.753789,-3.311787],[131.989804,-2.820551],[133.066845,-2.460418],[133.780031,-2.479848],[133.696212,-2.214542],[132.232373,-2.212526],[131.836222,-1.617162],[130.94284,-1.432522],[130.519558,-0.93772],[131.867538,-0.695461],[132.380116,-0.369538],[133.985548,-0.78021],[134.143368,-1.151867]]],[[[125.240501,1.419836],[124.437035,0.427881],[123.685505,0.235593],[122.723083,0.431137],[121.056725,0.381217],[120.183083,0.237247],[120.04087,-0.519658],[120.935905,-1.408906],[121.475821,-0.955962],[123.340565,-0.615673],[123.258399,-1.076213],[122.822715,-0.930951],[122.38853,-1.516858],[121.508274,-1.904483],[122.454572,-3.186058],[122.271896,-3.5295],[123.170963,-4.683693],[123.162333,-5.340604],[122.628515,-5.634591],[122.236394,-5.282933],[122.719569,-4.464172],[121.738234,-4.851331],[121.489463,-4.574553],[121.619171,-4.188478],[120.898182,-3.602105],[120.972389,-2.627643],[120.305453,-2.931604],[120.390047,-4.097579],[120.430717,-5.528241],[119.796543,-5.6734],[119.366906,-5.379878],[119.653606,-4.459417],[119.498835,-3.494412],[119.078344,-3.487022],[118.767769,-2.801999],[119.180974,-2.147104],[119.323394,-1.353147],[119.825999,0.154254],[120.035702,0.566477],[120.885779,1.309223],[121.666817,1.013944],[122.927567,0.875192],[124.077522,0.917102],[125.065989,1.643259],[125.240501,1.419836]]],[[[128.688249,1.132386],[128.635952,0.258486],[128.12017,0.356413],[127.968034,-0.252077],[128.379999,-0.780004],[128.100016,-0.899996],[127.696475,-0.266598],[127.39949,1.011722],[127.600512,1.810691],[127.932378,2.174596],[128.004156,1.628531],[128.594559,1.540811],[128.688249,1.132386]]],[[[117.875627,1.827641],[118.996747,0.902219],[117.811858,0.784242],[117.478339,0.102475],[117.521644,-0.803723],[116.560048,-1.487661],[116.533797,-2.483517],[116.148084,-4.012726],[116.000858,-3.657037],[114.864803,-4.106984],[114.468652,-3.495704],[113.755672,-3.43917],[113.256994,-3.118776],[112.068126,-3.478392],[111.703291,-2.994442],[111.04824,-3.049426],[110.223846,-2.934032],[110.070936,-1.592874],[109.571948,-1.314907],[109.091874,-0.459507],[108.952658,0.415375],[109.069136,1.341934],[109.66326,2.006467],[109.830227,1.338136],[110.514061,0.773131],[111.159138,0.976478],[111.797548,0.904441],[112.380252,1.410121],[112.859809,1.49779],[113.80585,1.217549],[114.621355,1.430688],[115.134037,2.821482],[115.519078,3.169238],[115.865517,4.306559],[117.015214,4.306094],[117.882035,4.137551],[117.313232,3.234428],[118.04833,2.28769],[117.875627,1.827641]]],[[[105.817655,-5.852356],[104.710384,-5.873285],[103.868213,-5.037315],[102.584261,-4.220259],[102.156173,-3.614146],[101.399113,-2.799777],[100.902503,-2.050262],[100.141981,-0.650348],[99.26374,0.183142],[98.970011,1.042882],[98.601351,1.823507],[97.699598,2.453184],[97.176942,3.308791],[96.424017,3.86886],[95.380876,4.970782],[95.293026,5.479821],[95.936863,5.439513],[97.484882,5.246321],[98.369169,4.26837],[99.142559,3.59035],[99.693998,3.174329],[100.641434,2.099381],[101.658012,2.083697],[102.498271,1.3987],[103.07684,0.561361],[103.838396,0.104542],[103.437645,-0.711946],[104.010789,-1.059212],[104.369991,-1.084843],[104.53949,-1.782372],[104.887893,-2.340425],[105.622111,-2.428844],[106.108593,-3.061777],[105.857446,-4.305525],[105.817655,-5.852356]]]]}}, {"type":"Feature","id":"IND","properties":{"name":"India"},"geometry":{"type":"Polygon","coordinates":[[[77.837451,35.49401],[78.912269,34.321936],[78.811086,33.506198],[79.208892,32.994395],[79.176129,32.48378],[78.458446,32.618164],[78.738894,31.515906],[79.721367,30.882715],[81.111256,30.183481],[80.476721,29.729865],[80.088425,28.79447],[81.057203,28.416095],[81.999987,27.925479],[83.304249,27.364506],[84.675018,27.234901],[85.251779,26.726198],[86.024393,26.630985],[87.227472,26.397898],[88.060238,26.414615],[88.174804,26.810405],[88.043133,27.445819],[88.120441,27.876542],[88.730326,28.086865],[88.814248,27.299316],[88.835643,27.098966],[89.744528,26.719403],[90.373275,26.875724],[91.217513,26.808648],[92.033484,26.83831],[92.103712,27.452614],[91.696657,27.771742],[92.503119,27.896876],[93.413348,28.640629],[94.56599,29.277438],[95.404802,29.031717],[96.117679,29.452802],[96.586591,28.83098],[96.248833,28.411031],[97.327114,28.261583],[97.402561,27.882536],[97.051989,27.699059],[97.133999,27.083774],[96.419366,27.264589],[95.124768,26.573572],[95.155153,26.001307],[94.603249,25.162495],[94.552658,24.675238],[94.106742,23.850741],[93.325188,24.078556],[93.286327,23.043658],[93.060294,22.703111],[93.166128,22.27846],[92.672721,22.041239],[92.146035,23.627499],[91.869928,23.624346],[91.706475,22.985264],[91.158963,23.503527],[91.46773,24.072639],[91.915093,24.130414],[92.376202,24.976693],[91.799596,25.147432],[90.872211,25.132601],[89.920693,25.26975],[89.832481,25.965082],[89.355094,26.014407],[88.563049,26.446526],[88.209789,25.768066],[88.931554,25.238692],[88.306373,24.866079],[88.084422,24.501657],[88.69994,24.233715],[88.52977,23.631142],[88.876312,22.879146],[89.031961,22.055708],[88.888766,21.690588],[88.208497,21.703172],[86.975704,21.495562],[87.033169,20.743308],[86.499351,20.151638],[85.060266,19.478579],[83.941006,18.30201],[83.189217,17.671221],[82.192792,17.016636],[82.191242,16.556664],[81.692719,16.310219],[80.791999,15.951972],[80.324896,15.899185],[80.025069,15.136415],[80.233274,13.835771],[80.286294,13.006261],[79.862547,12.056215],[79.857999,10.357275],[79.340512,10.308854],[78.885345,9.546136],[79.18972,9.216544],[78.277941,8.933047],[77.941165,8.252959],[77.539898,7.965535],[76.592979,8.899276],[76.130061,10.29963],[75.746467,11.308251],[75.396101,11.781245],[74.864816,12.741936],[74.616717,13.992583],[74.443859,14.617222],[73.534199,15.990652],[73.119909,17.92857],[72.820909,19.208234],[72.824475,20.419503],[72.630533,21.356009],[71.175273,20.757441],[70.470459,20.877331],[69.16413,22.089298],[69.644928,22.450775],[69.349597,22.84318],[68.176645,23.691965],[68.842599,24.359134],[71.04324,24.356524],[70.844699,25.215102],[70.282873,25.722229],[70.168927,26.491872],[69.514393,26.940966],[70.616496,27.989196],[71.777666,27.91318],[72.823752,28.961592],[73.450638,29.976413],[74.42138,30.979815],[74.405929,31.692639],[75.258642,32.271105],[74.451559,32.7649],[74.104294,33.441473],[73.749948,34.317699],[74.240203,34.748887],[75.757061,34.504923],[76.871722,34.653544],[77.837451,35.49401]]]}}, {"type":"Feature","id":"IRL","properties":{"name":"Ireland"},"geometry":{"type":"Polygon","coordinates":[[[-6.197885,53.867565],[-6.032985,53.153164],[-6.788857,52.260118],[-8.561617,51.669301],[-9.977086,51.820455],[-9.166283,52.864629],[-9.688525,53.881363],[-8.327987,54.664519],[-7.572168,55.131622],[-7.366031,54.595841],[-7.572168,54.059956],[-6.95373,54.073702],[-6.197885,53.867565]]]}}, {"type":"Feature","id":"IRN","properties":{"name":"Iran"},"geometry":{"type":"Polygon","coordinates":[[[53.921598,37.198918],[54.800304,37.392421],[55.511578,37.964117],[56.180375,37.935127],[56.619366,38.121394],[57.330434,38.029229],[58.436154,37.522309],[59.234762,37.412988],[60.377638,36.527383],[61.123071,36.491597],[61.210817,35.650072],[60.803193,34.404102],[60.52843,33.676446],[60.9637,33.528832],[60.536078,32.981269],[60.863655,32.18292],[60.941945,31.548075],[61.699314,31.379506],[61.781222,30.73585],[60.874248,29.829239],[61.369309,29.303276],[61.771868,28.699334],[62.72783,28.259645],[62.755426,27.378923],[63.233898,27.217047],[63.316632,26.756532],[61.874187,26.239975],[61.497363,25.078237],[59.616134,25.380157],[58.525761,25.609962],[57.397251,25.739902],[56.970766,26.966106],[56.492139,27.143305],[55.72371,26.964633],[54.71509,26.480658],[53.493097,26.812369],[52.483598,27.580849],[51.520763,27.86569],[50.852948,28.814521],[50.115009,30.147773],[49.57685,29.985715],[48.941333,30.31709],[48.567971,29.926778],[48.014568,30.452457],[48.004698,30.985137],[47.685286,30.984853],[47.849204,31.709176],[47.334661,32.469155],[46.109362,33.017287],[45.416691,33.967798],[45.64846,34.748138],[46.151788,35.093259],[46.07634,35.677383],[45.420618,35.977546],[44.77267,37.17045],[44.225756,37.971584],[44.421403,38.281281],[44.109225,39.428136],[44.79399,39.713003],[44.952688,39.335765],[45.457722,38.874139],[46.143623,38.741201],[46.50572,38.770605],[47.685079,39.508364],[48.060095,39.582235],[48.355529,39.288765],[48.010744,38.794015],[48.634375,38.270378],[48.883249,38.320245],[49.199612,37.582874],[50.147771,37.374567],[50.842354,36.872814],[52.264025,36.700422],[53.82579,36.965031],[53.921598,37.198918]]]}}, {"type":"Feature","id":"IRQ","properties":{"name":"Iraq"},"geometry":{"type":"Polygon","coordinates":[[[45.420618,35.977546],[46.07634,35.677383],[46.151788,35.093259],[45.64846,34.748138],[45.416691,33.967798],[46.109362,33.017287],[47.334661,32.469155],[47.849204,31.709176],[47.685286,30.984853],[48.004698,30.985137],[48.014568,30.452457],[48.567971,29.926778],[47.974519,29.975819],[47.302622,30.05907],[46.568713,29.099025],[44.709499,29.178891],[41.889981,31.190009],[40.399994,31.889992],[39.195468,32.161009],[38.792341,33.378686],[41.006159,34.419372],[41.383965,35.628317],[41.289707,36.358815],[41.837064,36.605854],[42.349591,37.229873],[42.779126,37.385264],[43.942259,37.256228],[44.293452,37.001514],[44.772699,37.170445],[45.420618,35.977546]]]}}, {"type":"Feature","id":"ISL","properties":{"name":"Iceland"},"geometry":{"type":"Polygon","coordinates":[[[-14.508695,66.455892],[-14.739637,65.808748],[-13.609732,65.126671],[-14.909834,64.364082],[-17.794438,63.678749],[-18.656246,63.496383],[-19.972755,63.643635],[-22.762972,63.960179],[-21.778484,64.402116],[-23.955044,64.89113],[-22.184403,65.084968],[-22.227423,65.378594],[-24.326184,65.611189],[-23.650515,66.262519],[-22.134922,66.410469],[-20.576284,65.732112],[-19.056842,66.276601],[-17.798624,65.993853],[-16.167819,66.526792],[-14.508695,66.455892]]]}}, {"type":"Feature","id":"ISR","properties":{"name":"Israel"},"geometry":{"type":"Polygon","coordinates":[[[35.719918,32.709192],[35.545665,32.393992],[35.18393,32.532511],[34.974641,31.866582],[35.225892,31.754341],[34.970507,31.616778],[34.927408,31.353435],[35.397561,31.489086],[35.420918,31.100066],[34.922603,29.501326],[34.265433,31.219361],[34.556372,31.548824],[34.488107,31.605539],[34.752587,32.072926],[34.955417,32.827376],[35.098457,33.080539],[35.126053,33.0909],[35.460709,33.08904],[35.552797,33.264275],[35.821101,33.277426],[35.836397,32.868123],[35.700798,32.716014],[35.719918,32.709192]]]}}, {"type":"Feature","id":"ITA","properties":{"name":"Italy"},"geometry":{"type":"MultiPolygon","coordinates":[[[[15.520376,38.231155],[15.160243,37.444046],[15.309898,37.134219],[15.099988,36.619987],[14.335229,36.996631],[13.826733,37.104531],[12.431004,37.61295],[12.570944,38.126381],[13.741156,38.034966],[14.761249,38.143874],[15.520376,38.231155]]],[[[9.210012,41.209991],[9.809975,40.500009],[9.669519,39.177376],[9.214818,39.240473],[8.806936,38.906618],[8.428302,39.171847],[8.388253,40.378311],[8.159998,40.950007],[8.709991,40.899984],[9.210012,41.209991]]],[[[12.376485,46.767559],[13.806475,46.509306],[13.69811,46.016778],[13.93763,45.591016],[13.141606,45.736692],[12.328581,45.381778],[12.383875,44.885374],[12.261453,44.600482],[12.589237,44.091366],[13.526906,43.587727],[14.029821,42.761008],[15.14257,41.95514],[15.926191,41.961315],[16.169897,41.740295],[15.889346,41.541082],[16.785002,41.179606],[17.519169,40.877143],[18.376687,40.355625],[18.480247,40.168866],[18.293385,39.810774],[17.73838,40.277671],[16.869596,40.442235],[16.448743,39.795401],[17.17149,39.4247],[17.052841,38.902871],[16.635088,38.843572],[16.100961,37.985899],[15.684087,37.908849],[15.687963,38.214593],[15.891981,38.750942],[16.109332,38.964547],[15.718814,39.544072],[15.413613,40.048357],[14.998496,40.172949],[14.703268,40.60455],[14.060672,40.786348],[13.627985,41.188287],[12.888082,41.25309],[12.106683,41.704535],[11.191906,42.355425],[10.511948,42.931463],[10.200029,43.920007],[9.702488,44.036279],[8.888946,44.366336],[8.428561,44.231228],[7.850767,43.767148],[7.435185,43.693845],[7.549596,44.127901],[7.007562,44.254767],[6.749955,45.028518],[7.096652,45.333099],[6.802355,45.70858],[6.843593,45.991147],[7.273851,45.776948],[7.755992,45.82449],[8.31663,46.163642],[8.489952,46.005151],[8.966306,46.036932],[9.182882,46.440215],[9.922837,46.314899],[10.363378,46.483571],[10.442701,46.893546],[11.048556,46.751359],[11.164828,46.941579],[12.153088,47.115393],[12.376485,46.767559]]]]}}, {"type":"Feature","id":"JAM","properties":{"name":"Jamaica"},"geometry":{"type":"Polygon","coordinates":[[[-77.569601,18.490525],[-76.896619,18.400867],[-76.365359,18.160701],[-76.199659,17.886867],[-76.902561,17.868238],[-77.206341,17.701116],[-77.766023,17.861597],[-78.337719,18.225968],[-78.217727,18.454533],[-77.797365,18.524218],[-77.569601,18.490525]]]}}, {"type":"Feature","id":"JOR","properties":{"name":"Jordan"},"geometry":{"type":"Polygon","coordinates":[[[35.545665,32.393992],[35.719918,32.709192],[36.834062,32.312938],[38.792341,33.378686],[39.195468,32.161009],[39.004886,32.010217],[37.002166,31.508413],[37.998849,30.5085],[37.66812,30.338665],[37.503582,30.003776],[36.740528,29.865283],[36.501214,29.505254],[36.068941,29.197495],[34.956037,29.356555],[34.922603,29.501326],[35.420918,31.100066],[35.397561,31.489086],[35.545252,31.782505],[35.545665,32.393992]]]}}, {"type":"Feature","id":"JPN","properties":{"name":"Japan"},"geometry":{"type":"MultiPolygon","coordinates":[[[[134.638428,34.149234],[134.766379,33.806335],[134.203416,33.201178],[133.79295,33.521985],[133.280268,33.28957],[133.014858,32.704567],[132.363115,32.989382],[132.371176,33.463642],[132.924373,34.060299],[133.492968,33.944621],[133.904106,34.364931],[134.638428,34.149234]]],[[[140.976388,37.142074],[140.59977,36.343983],[140.774074,35.842877],[140.253279,35.138114],[138.975528,34.6676],[137.217599,34.606286],[135.792983,33.464805],[135.120983,33.849071],[135.079435,34.596545],[133.340316,34.375938],[132.156771,33.904933],[130.986145,33.885761],[132.000036,33.149992],[131.33279,31.450355],[130.686318,31.029579],[130.20242,31.418238],[130.447676,32.319475],[129.814692,32.61031],[129.408463,33.296056],[130.353935,33.604151],[130.878451,34.232743],[131.884229,34.749714],[132.617673,35.433393],[134.608301,35.731618],[135.677538,35.527134],[136.723831,37.304984],[137.390612,36.827391],[138.857602,37.827485],[139.426405,38.215962],[140.05479,39.438807],[139.883379,40.563312],[140.305783,41.195005],[141.368973,41.37856],[141.914263,39.991616],[141.884601,39.180865],[140.959489,38.174001],[140.976388,37.142074]]],[[[143.910162,44.1741],[144.613427,43.960883],[145.320825,44.384733],[145.543137,43.262088],[144.059662,42.988358],[143.18385,41.995215],[141.611491,42.678791],[141.067286,41.584594],[139.955106,41.569556],[139.817544,42.563759],[140.312087,43.333273],[141.380549,43.388825],[141.671952,44.772125],[141.967645,45.551483],[143.14287,44.510358],[143.910162,44.1741]]]]}}, {"type":"Feature","id":"KAZ","properties":{"name":"Kazakhstan"},"geometry":{"type":"Polygon","coordinates":[[[70.962315,42.266154],[70.388965,42.081308],[69.070027,41.384244],[68.632483,40.668681],[68.259896,40.662325],[67.985856,41.135991],[66.714047,41.168444],[66.510649,41.987644],[66.023392,41.994646],[66.098012,42.99766],[64.900824,43.728081],[63.185787,43.650075],[62.0133,43.504477],[61.05832,44.405817],[60.239972,44.784037],[58.689989,45.500014],[58.503127,45.586804],[55.928917,44.995858],[55.968191,41.308642],[55.455251,41.259859],[54.755345,42.043971],[54.079418,42.324109],[52.944293,42.116034],[52.50246,41.783316],[52.446339,42.027151],[52.692112,42.443895],[52.501426,42.792298],[51.342427,43.132975],[50.891292,44.031034],[50.339129,44.284016],[50.305643,44.609836],[51.278503,44.514854],[51.316899,45.245998],[52.16739,45.408391],[53.040876,45.259047],[53.220866,46.234646],[53.042737,46.853006],[52.042023,46.804637],[51.191945,47.048705],[50.034083,46.60899],[49.10116,46.39933],[48.593241,46.561034],[48.694734,47.075628],[48.057253,47.743753],[47.315231,47.715847],[46.466446,48.394152],[47.043672,49.152039],[46.751596,49.356006],[47.54948,50.454698],[48.577841,49.87476],[48.702382,50.605128],[50.766648,51.692762],[52.328724,51.718652],[54.532878,51.02624],[55.716941,50.621717],[56.777961,51.043551],[58.363291,51.063653],[59.642282,50.545442],[59.932807,50.842194],[61.337424,50.79907],[61.588003,51.272659],[59.967534,51.96042],[60.927269,52.447548],[60.739993,52.719986],[61.699986,52.979996],[60.978066,53.664993],[61.436591,54.006265],[65.178534,54.354228],[65.666876,54.601267],[68.1691,54.970392],[69.068167,55.38525],[70.865267,55.169734],[71.180131,54.133285],[72.22415,54.376655],[73.508516,54.035617],[73.425679,53.48981],[74.384845,53.546861],[76.8911,54.490524],[76.525179,54.177003],[77.800916,53.404415],[80.03556,50.864751],[80.568447,51.388336],[81.945986,50.812196],[83.383004,51.069183],[83.935115,50.889246],[84.416377,50.3114],[85.11556,50.117303],[85.54127,49.692859],[86.829357,49.826675],[87.35997,49.214981],[86.598776,48.549182],[85.768233,48.455751],[85.720484,47.452969],[85.16429,47.000956],[83.180484,47.330031],[82.458926,45.53965],[81.947071,45.317027],[79.966106,44.917517],[80.866206,43.180362],[80.18015,42.920068],[80.25999,42.349999],[79.643645,42.496683],[79.142177,42.856092],[77.658392,42.960686],[76.000354,42.988022],[75.636965,42.8779],[74.212866,43.298339],[73.645304,43.091272],[73.489758,42.500894],[71.844638,42.845395],[71.186281,42.704293],[70.962315,42.266154]]]}}, {"type":"Feature","id":"KEN","properties":{"name":"Kenya"},"geometry":{"type":"Polygon","coordinates":[[[40.993,-0.85829],[41.58513,-1.68325],[40.88477,-2.08255],[40.63785,-2.49979],[40.26304,-2.57309],[40.12119,-3.27768],[39.80006,-3.68116],[39.60489,-4.34653],[39.20222,-4.67677],[37.7669,-3.67712],[37.69869,-3.09699],[34.07262,-1.05982],[33.903711,-0.95],[33.893569,0.109814],[34.18,0.515],[34.6721,1.17694],[35.03599,1.90584],[34.59607,3.05374],[34.47913,3.5556],[34.005,4.249885],[34.620196,4.847123],[35.298007,5.506],[35.817448,5.338232],[35.817448,4.776966],[36.159079,4.447864],[36.855093,4.447864],[38.120915,3.598605],[38.43697,3.58851],[38.67114,3.61607],[38.89251,3.50074],[39.559384,3.42206],[39.85494,3.83879],[40.76848,4.25702],[41.1718,3.91909],[41.855083,3.918912],[40.98105,2.78452],[40.993,-0.85829]]]}}, {"type":"Feature","id":"KGZ","properties":{"name":"Kyrgyzstan"},"geometry":{"type":"Polygon","coordinates":[[[70.962315,42.266154],[71.186281,42.704293],[71.844638,42.845395],[73.489758,42.500894],[73.645304,43.091272],[74.212866,43.298339],[75.636965,42.8779],[76.000354,42.988022],[77.658392,42.960686],[79.142177,42.856092],[79.643645,42.496683],[80.25999,42.349999],[80.11943,42.123941],[78.543661,41.582243],[78.187197,41.185316],[76.904484,41.066486],[76.526368,40.427946],[75.467828,40.562072],[74.776862,40.366425],[73.822244,39.893973],[73.960013,39.660008],[73.675379,39.431237],[71.784694,39.279463],[70.549162,39.604198],[69.464887,39.526683],[69.55961,40.103211],[70.648019,39.935754],[71.014198,40.244366],[71.774875,40.145844],[73.055417,40.866033],[71.870115,41.3929],[71.157859,41.143587],[70.420022,41.519998],[71.259248,42.167711],[70.962315,42.266154]]]}}, {"type":"Feature","id":"KHM","properties":{"name":"Cambodia"},"geometry":{"type":"Polygon","coordinates":[[[103.49728,10.632555],[103.09069,11.153661],[102.584932,12.186595],[102.348099,13.394247],[102.988422,14.225721],[104.281418,14.416743],[105.218777,14.273212],[106.043946,13.881091],[106.496373,14.570584],[107.382727,14.202441],[107.614548,13.535531],[107.491403,12.337206],[105.810524,11.567615],[106.24967,10.961812],[105.199915,10.88931],[104.334335,10.486544],[103.49728,10.632555]]]}}, {"type":"Feature","id":"KOR","properties":{"name":"South Korea"},"geometry":{"type":"Polygon","coordinates":[[[128.349716,38.612243],[129.21292,37.432392],[129.46045,36.784189],[129.468304,35.632141],[129.091377,35.082484],[128.18585,34.890377],[127.386519,34.475674],[126.485748,34.390046],[126.37392,34.93456],[126.559231,35.684541],[126.117398,36.725485],[126.860143,36.893924],[126.174759,37.749686],[126.237339,37.840378],[126.68372,37.804773],[127.073309,38.256115],[127.780035,38.304536],[128.205746,38.370397],[128.349716,38.612243]]]}}, {"type":"Feature","id":"CS-KM","properties":{"name":"Kosovo"},"geometry":{"type":"Polygon","coordinates":[[[20.76216,42.05186],[20.71731,41.84711],[20.59023,41.85541],[20.52295,42.21787],[20.28374,42.32025],[20.0707,42.58863],[20.25758,42.81275],[20.49679,42.88469],[20.63508,43.21671],[20.81448,43.27205],[20.95651,43.13094],[21.143395,43.068685],[21.27421,42.90959],[21.43866,42.86255],[21.63302,42.67717],[21.77505,42.6827],[21.66292,42.43922],[21.54332,42.32025],[21.576636,42.245224],[21.3527,42.2068],[20.76216,42.05186]]]}}, {"type":"Feature","id":"KWT","properties":{"name":"Kuwait"},"geometry":{"type":"Polygon","coordinates":[[[47.974519,29.975819],[48.183189,29.534477],[48.093943,29.306299],[48.416094,28.552004],[47.708851,28.526063],[47.459822,29.002519],[46.568713,29.099025],[47.302622,30.05907],[47.974519,29.975819]]]}}, {"type":"Feature","id":"LAO","properties":{"name":"Laos"},"geometry":{"type":"Polygon","coordinates":[[[105.218777,14.273212],[105.544338,14.723934],[105.589039,15.570316],[104.779321,16.441865],[104.716947,17.428859],[103.956477,18.240954],[103.200192,18.309632],[102.998706,17.961695],[102.413005,17.932782],[102.113592,18.109102],[101.059548,17.512497],[101.035931,18.408928],[101.282015,19.462585],[100.606294,19.508344],[100.548881,20.109238],[100.115988,20.41785],[100.329101,20.786122],[101.180005,21.436573],[101.270026,21.201652],[101.80312,21.174367],[101.652018,22.318199],[102.170436,22.464753],[102.754896,21.675137],[103.203861,20.766562],[104.435,20.758733],[104.822574,19.886642],[104.183388,19.624668],[103.896532,19.265181],[105.094598,18.666975],[105.925762,17.485315],[106.556008,16.604284],[107.312706,15.908538],[107.564525,15.202173],[107.382727,14.202441],[106.496373,14.570584],[106.043946,13.881091],[105.218777,14.273212]]]}}, {"type":"Feature","id":"LBN","properties":{"name":"Lebanon"},"geometry":{"type":"Polygon","coordinates":[[[35.821101,33.277426],[35.552797,33.264275],[35.460709,33.08904],[35.126053,33.0909],[35.482207,33.90545],[35.979592,34.610058],[35.998403,34.644914],[36.448194,34.593935],[36.61175,34.201789],[36.06646,33.824912],[35.821101,33.277426]]]}}, {"type":"Feature","id":"LBR","properties":{"name":"Liberia"},"geometry":{"type":"Polygon","coordinates":[[[-7.712159,4.364566],[-7.974107,4.355755],[-9.004794,4.832419],[-9.91342,5.593561],[-10.765384,6.140711],[-11.438779,6.785917],[-11.199802,7.105846],[-11.146704,7.396706],[-10.695595,7.939464],[-10.230094,8.406206],[-10.016567,8.428504],[-9.755342,8.541055],[-9.33728,7.928534],[-9.403348,7.526905],[-9.208786,7.313921],[-8.926065,7.309037],[-8.722124,7.711674],[-8.439298,7.686043],[-8.485446,7.395208],[-8.385452,6.911801],[-8.60288,6.467564],[-8.311348,6.193033],[-7.993693,6.12619],[-7.570153,5.707352],[-7.539715,5.313345],[-7.635368,5.188159],[-7.712159,4.364566]]]}}, {"type":"Feature","id":"LBY","properties":{"name":"Libya"},"geometry":{"type":"Polygon","coordinates":[[[14.8513,22.86295],[14.143871,22.491289],[13.581425,23.040506],[11.999506,23.471668],[11.560669,24.097909],[10.771364,24.562532],[10.303847,24.379313],[9.948261,24.936954],[9.910693,25.365455],[9.319411,26.094325],[9.716286,26.512206],[9.629056,27.140953],[9.756128,27.688259],[9.683885,28.144174],[9.859998,28.95999],[9.805634,29.424638],[9.48214,30.307556],[9.970017,30.539325],[10.056575,30.961831],[9.950225,31.37607],[10.636901,31.761421],[10.94479,32.081815],[11.432253,32.368903],[11.488787,33.136996],[12.66331,32.79278],[13.08326,32.87882],[13.91868,32.71196],[15.24563,32.26508],[15.71394,31.37626],[16.61162,31.18218],[18.02109,30.76357],[19.08641,30.26639],[19.57404,30.52582],[20.05335,30.98576],[19.82033,31.75179],[20.13397,32.2382],[20.85452,32.7068],[21.54298,32.8432],[22.89576,32.63858],[23.2368,32.19149],[23.60913,32.18726],[23.9275,32.01667],[24.92114,31.89936],[25.16482,31.56915],[24.80287,31.08929],[24.95762,30.6616],[24.70007,30.04419],[25,29.238655],[25,25.6825],[25,22],[25,20.00304],[23.85,20],[23.83766,19.58047],[19.84926,21.49509],[15.86085,23.40972],[14.8513,22.86295]]]}}, {"type":"Feature","id":"LKA","properties":{"name":"Sri Lanka"},"geometry":{"type":"Polygon","coordinates":[[[81.787959,7.523055],[81.637322,6.481775],[81.21802,6.197141],[80.348357,5.96837],[79.872469,6.763463],[79.695167,8.200843],[80.147801,9.824078],[80.838818,9.268427],[81.304319,8.564206],[81.787959,7.523055]]]}}, {"type":"Feature","id":"LSO","properties":{"name":"Lesotho"},"geometry":{"type":"Polygon","coordinates":[[[28.978263,-28.955597],[29.325166,-29.257387],[29.018415,-29.743766],[28.8484,-30.070051],[28.291069,-30.226217],[28.107205,-30.545732],[27.749397,-30.645106],[26.999262,-29.875954],[27.532511,-29.242711],[28.074338,-28.851469],[28.5417,-28.647502],[28.978263,-28.955597]]]}}, {"type":"Feature","id":"LTU","properties":{"name":"Lithuania"},"geometry":{"type":"Polygon","coordinates":[[[22.731099,54.327537],[22.651052,54.582741],[22.757764,54.856574],[22.315724,55.015299],[21.268449,55.190482],[21.0558,56.031076],[22.201157,56.337802],[23.878264,56.273671],[24.860684,56.372528],[25.000934,56.164531],[25.533047,56.100297],[26.494331,55.615107],[26.588279,55.167176],[25.768433,54.846963],[25.536354,54.282423],[24.450684,53.905702],[23.484128,53.912498],[23.243987,54.220567],[22.731099,54.327537]]]}}, {"type":"Feature","id":"LUX","properties":{"name":"Luxembourg"},"geometry":{"type":"Polygon","coordinates":[[[6.043073,50.128052],[6.242751,49.902226],[6.18632,49.463803],[5.897759,49.442667],[5.674052,49.529484],[5.782417,50.090328],[6.043073,50.128052]]]}}, {"type":"Feature","id":"LVA","properties":{"name":"Latvia"},"geometry":{"type":"Polygon","coordinates":[[[21.0558,56.031076],[21.090424,56.783873],[21.581866,57.411871],[22.524341,57.753374],[23.318453,57.006236],[24.12073,57.025693],[24.312863,57.793424],[25.164594,57.970157],[25.60281,57.847529],[26.463532,57.476389],[27.288185,57.474528],[27.770016,57.244258],[27.855282,56.759326],[28.176709,56.16913],[27.10246,55.783314],[26.494331,55.615107],[25.533047,56.100297],[25.000934,56.164531],[24.860684,56.372528],[23.878264,56.273671],[22.201157,56.337802],[21.0558,56.031076]]]}}, {"type":"Feature","id":"MAR","properties":{"name":"Morocco"},"geometry":{"type":"Polygon","coordinates":[[[-5.193863,35.755182],[-4.591006,35.330712],[-3.640057,35.399855],[-2.604306,35.179093],[-2.169914,35.168396],[-1.792986,34.527919],[-1.733455,33.919713],[-1.388049,32.864015],[-1.124551,32.651522],[-1.307899,32.262889],[-2.616605,32.094346],[-3.06898,31.724498],[-3.647498,31.637294],[-3.690441,30.896952],[-4.859646,30.501188],[-5.242129,30.000443],[-6.060632,29.7317],[-7.059228,29.579228],[-8.674116,28.841289],[-8.66559,27.656426],[-8.817809,27.656426],[-8.817828,27.656426],[-8.794884,27.120696],[-9.413037,27.088476],[-9.735343,26.860945],[-10.189424,26.860945],[-10.551263,26.990808],[-11.392555,26.883424],[-11.71822,26.104092],[-12.030759,26.030866],[-12.500963,24.770116],[-13.89111,23.691009],[-14.221168,22.310163],[-14.630833,21.86094],[-14.750955,21.5006],[-17.002962,21.420734],[-17.020428,21.42231],[-16.973248,21.885745],[-16.589137,22.158234],[-16.261922,22.67934],[-16.326414,23.017768],[-15.982611,23.723358],[-15.426004,24.359134],[-15.089332,24.520261],[-14.824645,25.103533],[-14.800926,25.636265],[-14.43994,26.254418],[-13.773805,26.618892],[-13.139942,27.640148],[-13.121613,27.654148],[-12.618837,28.038186],[-11.688919,28.148644],[-10.900957,28.832142],[-10.399592,29.098586],[-9.564811,29.933574],[-9.814718,31.177736],[-9.434793,32.038096],[-9.300693,32.564679],[-8.657476,33.240245],[-7.654178,33.697065],[-6.912544,34.110476],[-6.244342,35.145865],[-5.929994,35.759988],[-5.193863,35.755182]]]}}, {"type":"Feature","id":"MDA","properties":{"name":"Moldova"},"geometry":{"type":"Polygon","coordinates":[[[26.619337,48.220726],[26.857824,48.368211],[27.522537,48.467119],[28.259547,48.155562],[28.670891,48.118149],[29.122698,47.849095],[29.050868,47.510227],[29.415135,47.346645],[29.559674,46.928583],[29.908852,46.674361],[29.83821,46.525326],[30.024659,46.423937],[29.759972,46.349988],[29.170654,46.379262],[29.072107,46.517678],[28.862972,46.437889],[28.933717,46.25883],[28.659987,45.939987],[28.485269,45.596907],[28.233554,45.488283],[28.054443,45.944586],[28.160018,46.371563],[28.12803,46.810476],[27.551166,47.405117],[27.233873,47.826771],[26.924176,48.123264],[26.619337,48.220726]]]}}, {"type":"Feature","id":"MDG","properties":{"name":"Madagascar"},"geometry":{"type":"Polygon","coordinates":[[[49.543519,-12.469833],[49.808981,-12.895285],[50.056511,-13.555761],[50.217431,-14.758789],[50.476537,-15.226512],[50.377111,-15.706069],[50.200275,-16.000263],[49.860606,-15.414253],[49.672607,-15.710204],[49.863344,-16.451037],[49.774564,-16.875042],[49.498612,-17.106036],[49.435619,-17.953064],[49.041792,-19.118781],[48.548541,-20.496888],[47.930749,-22.391501],[47.547723,-23.781959],[47.095761,-24.94163],[46.282478,-25.178463],[45.409508,-25.601434],[44.833574,-25.346101],[44.03972,-24.988345],[43.763768,-24.460677],[43.697778,-23.574116],[43.345654,-22.776904],[43.254187,-22.057413],[43.433298,-21.336475],[43.893683,-21.163307],[43.89637,-20.830459],[44.374325,-20.072366],[44.464397,-19.435454],[44.232422,-18.961995],[44.042976,-18.331387],[43.963084,-17.409945],[44.312469,-16.850496],[44.446517,-16.216219],[44.944937,-16.179374],[45.502732,-15.974373],[45.872994,-15.793454],[46.312243,-15.780018],[46.882183,-15.210182],[47.70513,-14.594303],[48.005215,-14.091233],[47.869047,-13.663869],[48.293828,-13.784068],[48.84506,-13.089175],[48.863509,-12.487868],[49.194651,-12.040557],[49.543519,-12.469833]]]}}, {"type":"Feature","id":"MEX","properties":{"name":"Mexico"},"geometry":{"type":"Polygon","coordinates":[[[-97.140008,25.869997],[-97.528072,24.992144],[-97.702946,24.272343],[-97.776042,22.93258],[-97.872367,22.444212],[-97.699044,21.898689],[-97.38896,21.411019],[-97.189333,20.635433],[-96.525576,19.890931],[-96.292127,19.320371],[-95.900885,18.828024],[-94.839063,18.562717],[-94.42573,18.144371],[-93.548651,18.423837],[-92.786114,18.524839],[-92.037348,18.704569],[-91.407903,18.876083],[-90.77187,19.28412],[-90.53359,19.867418],[-90.451476,20.707522],[-90.278618,20.999855],[-89.601321,21.261726],[-88.543866,21.493675],[-87.658417,21.458846],[-87.05189,21.543543],[-86.811982,21.331515],[-86.845908,20.849865],[-87.383291,20.255405],[-87.621054,19.646553],[-87.43675,19.472403],[-87.58656,19.04013],[-87.837191,18.259816],[-88.090664,18.516648],[-88.300031,18.499982],[-88.490123,18.486831],[-88.848344,17.883198],[-89.029857,18.001511],[-89.150909,17.955468],[-89.14308,17.808319],[-90.067934,17.819326],[-91.00152,17.817595],[-91.002269,17.254658],[-91.453921,17.252177],[-91.08167,16.918477],[-90.711822,16.687483],[-90.600847,16.470778],[-90.438867,16.41011],[-90.464473,16.069562],[-91.74796,16.066565],[-92.229249,15.251447],[-92.087216,15.064585],[-92.20323,14.830103],[-92.22775,14.538829],[-93.359464,15.61543],[-93.875169,15.940164],[-94.691656,16.200975],[-95.250227,16.128318],[-96.053382,15.752088],[-96.557434,15.653515],[-97.263592,15.917065],[-98.01303,16.107312],[-98.947676,16.566043],[-99.697397,16.706164],[-100.829499,17.171071],[-101.666089,17.649026],[-101.918528,17.91609],[-102.478132,17.975751],[-103.50099,18.292295],[-103.917527,18.748572],[-104.99201,19.316134],[-105.493038,19.946767],[-105.731396,20.434102],[-105.397773,20.531719],[-105.500661,20.816895],[-105.270752,21.076285],[-105.265817,21.422104],[-105.603161,21.871146],[-105.693414,22.26908],[-106.028716,22.773752],[-106.90998,23.767774],[-107.915449,24.548915],[-108.401905,25.172314],[-109.260199,25.580609],[-109.444089,25.824884],[-109.291644,26.442934],[-109.801458,26.676176],[-110.391732,27.162115],[-110.641019,27.859876],[-111.178919,27.941241],[-111.759607,28.467953],[-112.228235,28.954409],[-112.271824,29.266844],[-112.809594,30.021114],[-113.163811,30.786881],[-113.148669,31.170966],[-113.871881,31.567608],[-114.205737,31.524045],[-114.776451,31.799532],[-114.9367,31.393485],[-114.771232,30.913617],[-114.673899,30.162681],[-114.330974,29.750432],[-113.588875,29.061611],[-113.424053,28.826174],[-113.271969,28.754783],[-113.140039,28.411289],[-112.962298,28.42519],[-112.761587,27.780217],[-112.457911,27.525814],[-112.244952,27.171727],[-111.616489,26.662817],[-111.284675,25.73259],[-110.987819,25.294606],[-110.710007,24.826004],[-110.655049,24.298595],[-110.172856,24.265548],[-109.771847,23.811183],[-109.409104,23.364672],[-109.433392,23.185588],[-109.854219,22.818272],[-110.031392,22.823078],[-110.295071,23.430973],[-110.949501,24.000964],[-111.670568,24.484423],[-112.182036,24.738413],[-112.148989,25.470125],[-112.300711,26.012004],[-112.777297,26.32196],[-113.464671,26.768186],[-113.59673,26.63946],[-113.848937,26.900064],[-114.465747,27.14209],[-115.055142,27.722727],[-114.982253,27.7982],[-114.570366,27.741485],[-114.199329,28.115003],[-114.162018,28.566112],[-114.931842,29.279479],[-115.518654,29.556362],[-115.887365,30.180794],[-116.25835,30.836464],[-116.721526,31.635744],[-117.12776,32.53534],[-115.99135,32.61239],[-114.72139,32.72083],[-114.815,32.52528],[-113.30498,32.03914],[-111.02361,31.33472],[-109.035,31.34194],[-108.24194,31.34222],[-108.24,31.754854],[-106.50759,31.75452],[-106.1429,31.39995],[-105.63159,31.08383],[-105.03737,30.64402],[-104.70575,30.12173],[-104.45697,29.57196],[-103.94,29.27],[-103.11,28.97],[-102.48,29.76],[-101.6624,29.7793],[-100.9576,29.38071],[-100.45584,28.69612],[-100.11,28.11],[-99.52,27.54],[-99.3,26.84],[-99.02,26.37],[-98.24,26.06],[-97.53,25.84],[-97.140008,25.869997]]]}}, {"type":"Feature","id":"MKD","properties":{"name":"Macedonia"},"geometry":{"type":"Polygon","coordinates":[[[20.59023,41.85541],[20.71731,41.84711],[20.76216,42.05186],[21.3527,42.2068],[21.576636,42.245224],[21.91708,42.30364],[22.380526,42.32026],[22.881374,41.999297],[22.952377,41.337994],[22.76177,41.3048],[22.597308,41.130487],[22.055378,41.149866],[21.674161,40.931275],[21.02004,40.842727],[20.60518,41.08622],[20.46315,41.51509],[20.59023,41.85541]]]}}, {"type":"Feature","id":"MLI","properties":{"name":"Mali"},"geometry":{"type":"Polygon","coordinates":[[[-12.17075,14.616834],[-11.834208,14.799097],[-11.666078,15.388208],[-11.349095,15.411256],[-10.650791,15.132746],[-10.086846,15.330486],[-9.700255,15.264107],[-9.550238,15.486497],[-5.537744,15.50169],[-5.315277,16.201854],[-5.488523,16.325102],[-5.971129,20.640833],[-6.453787,24.956591],[-4.923337,24.974574],[-1.550055,22.792666],[1.823228,20.610809],[2.060991,20.142233],[2.683588,19.85623],[3.146661,19.693579],[3.158133,19.057364],[4.267419,19.155265],[4.27021,16.852227],[3.723422,16.184284],[3.638259,15.56812],[2.749993,15.409525],[1.385528,15.323561],[1.015783,14.968182],[0.374892,14.928908],[-0.266257,14.924309],[-0.515854,15.116158],[-1.066363,14.973815],[-2.001035,14.559008],[-2.191825,14.246418],[-2.967694,13.79815],[-3.103707,13.541267],[-3.522803,13.337662],[-4.006391,13.472485],[-4.280405,13.228444],[-4.427166,12.542646],[-5.220942,11.713859],[-5.197843,11.375146],[-5.470565,10.95127],[-5.404342,10.370737],[-5.816926,10.222555],[-6.050452,10.096361],[-6.205223,10.524061],[-6.493965,10.411303],[-6.666461,10.430811],[-6.850507,10.138994],[-7.622759,10.147236],[-7.89959,10.297382],[-8.029944,10.206535],[-8.335377,10.494812],[-8.282357,10.792597],[-8.407311,10.909257],[-8.620321,10.810891],[-8.581305,11.136246],[-8.376305,11.393646],[-8.786099,11.812561],[-8.905265,12.088358],[-9.127474,12.30806],[-9.327616,12.334286],[-9.567912,12.194243],[-9.890993,12.060479],[-10.165214,11.844084],[-10.593224,11.923975],[-10.87083,12.177887],[-11.036556,12.211245],[-11.297574,12.077971],[-11.456169,12.076834],[-11.513943,12.442988],[-11.467899,12.754519],[-11.553398,13.141214],[-11.927716,13.422075],[-12.124887,13.994727],[-12.17075,14.616834]]]}}, {"type":"Feature","id":"MLT","properties":{"name":"Malta"},"geometry":{"type":"MultiPolygon","coordinates":[[[[14.566171,35.852721],[14.532684,35.820191],[14.436463,35.821664],[14.352334,35.872281],[14.3513,35.978399],[14.448348,35.957444],[14.537025,35.886285],[14.566171,35.852721]]],[[[14.313473,36.027569],[14.253632,36.012143],[14.194204,36.042245],[14.180354,36.060383],[14.263243,36.075809],[14.303758,36.062295],[14.320914,36.03625],[14.313473,36.027569]]]]}}, {"type":"Feature","id":"MMR","properties":{"name":"Myanmar"},"geometry":{"type":"Polygon","coordinates":[[[99.543309,20.186598],[98.959676,19.752981],[98.253724,19.708203],[97.797783,18.62708],[97.375896,18.445438],[97.859123,17.567946],[98.493761,16.837836],[98.903348,16.177824],[98.537376,15.308497],[98.192074,15.123703],[98.430819,14.622028],[99.097755,13.827503],[99.212012,13.269294],[99.196354,12.804748],[99.587286,11.892763],[99.038121,10.960546],[98.553551,9.93296],[98.457174,10.675266],[98.764546,11.441292],[98.428339,12.032987],[98.509574,13.122378],[98.103604,13.64046],[97.777732,14.837286],[97.597072,16.100568],[97.16454,16.928734],[96.505769,16.427241],[95.369352,15.71439],[94.808405,15.803454],[94.188804,16.037936],[94.533486,17.27724],[94.324817,18.213514],[93.540988,19.366493],[93.663255,19.726962],[93.078278,19.855145],[92.368554,20.670883],[92.303234,21.475485],[92.652257,21.324048],[92.672721,22.041239],[93.166128,22.27846],[93.060294,22.703111],[93.286327,23.043658],[93.325188,24.078556],[94.106742,23.850741],[94.552658,24.675238],[94.603249,25.162495],[95.155153,26.001307],[95.124768,26.573572],[96.419366,27.264589],[97.133999,27.083774],[97.051989,27.699059],[97.402561,27.882536],[97.327114,28.261583],[97.911988,28.335945],[98.246231,27.747221],[98.68269,27.508812],[98.712094,26.743536],[98.671838,25.918703],[97.724609,25.083637],[97.60472,23.897405],[98.660262,24.063286],[98.898749,23.142722],[99.531992,22.949039],[99.240899,22.118314],[99.983489,21.742937],[100.416538,21.558839],[101.150033,21.849984],[101.180005,21.436573],[100.329101,20.786122],[100.115988,20.41785],[99.543309,20.186598]]]}}, {"type":"Feature","id":"MNE","properties":{"name":"Montenegro"},"geometry":{"type":"Polygon","coordinates":[[[19.801613,42.500093],[19.738051,42.688247],[19.30449,42.19574],[19.37177,41.87755],[19.16246,41.95502],[18.88214,42.28151],[18.45,42.48],[18.56,42.65],[18.70648,43.20011],[19.03165,43.43253],[19.21852,43.52384],[19.48389,43.35229],[19.63,43.21378],[19.95857,43.10604],[20.3398,42.89852],[20.25758,42.81275],[20.0707,42.58863],[19.801613,42.500093]]]}}, {"type":"Feature","id":"MNG","properties":{"name":"Mongolia"},"geometry":{"type":"Polygon","coordinates":[[[87.751264,49.297198],[88.805567,49.470521],[90.713667,50.331812],[92.234712,50.802171],[93.104219,50.49529],[94.147566,50.480537],[94.815949,50.013433],[95.814028,49.977467],[97.259728,49.726061],[98.231762,50.422401],[97.82574,51.010995],[98.861491,52.047366],[99.981732,51.634006],[100.88948,51.516856],[102.065223,51.259921],[102.255909,50.510561],[103.676545,50.089966],[104.621552,50.275329],[105.886591,50.406019],[106.888804,50.274296],[107.868176,49.793705],[108.475167,49.282548],[109.402449,49.292961],[110.662011,49.130128],[111.581231,49.377968],[112.89774,49.543565],[114.362456,50.248303],[114.96211,50.140247],[115.485695,49.805177],[116.678801,49.888531],[116.191802,49.134598],[115.485282,48.135383],[115.742837,47.726545],[116.308953,47.85341],[117.295507,47.697709],[118.064143,48.06673],[118.866574,47.74706],[119.772824,47.048059],[119.66327,46.69268],[118.874326,46.805412],[117.421701,46.672733],[116.717868,46.388202],[115.985096,45.727235],[114.460332,45.339817],[113.463907,44.808893],[112.436062,45.011646],[111.873306,45.102079],[111.348377,44.457442],[111.667737,44.073176],[111.829588,43.743118],[111.129682,43.406834],[110.412103,42.871234],[109.243596,42.519446],[107.744773,42.481516],[106.129316,42.134328],[104.964994,41.59741],[104.522282,41.908347],[103.312278,41.907468],[101.83304,42.514873],[100.845866,42.663804],[99.515817,42.524691],[97.451757,42.74889],[96.349396,42.725635],[95.762455,43.319449],[95.306875,44.241331],[94.688929,44.352332],[93.480734,44.975472],[92.133891,45.115076],[90.94554,45.286073],[90.585768,45.719716],[90.970809,46.888146],[90.280826,47.693549],[88.854298,48.069082],[88.013832,48.599463],[87.751264,49.297198]]]}}, {"type":"Feature","id":"MOZ","properties":{"name":"Mozambique"},"geometry":{"type":"Polygon","coordinates":[[[34.559989,-11.52002],[35.312398,-11.439146],[36.514082,-11.720938],[36.775151,-11.594537],[37.471284,-11.568751],[37.827645,-11.268769],[38.427557,-11.285202],[39.52103,-10.896854],[40.316589,-10.317096],[40.478387,-10.765441],[40.437253,-11.761711],[40.560811,-12.639177],[40.59962,-14.201975],[40.775475,-14.691764],[40.477251,-15.406294],[40.089264,-16.100774],[39.452559,-16.720891],[38.538351,-17.101023],[37.411133,-17.586368],[36.281279,-18.659688],[35.896497,-18.84226],[35.1984,-19.552811],[34.786383,-19.784012],[34.701893,-20.497043],[35.176127,-21.254361],[35.373428,-21.840837],[35.385848,-22.14],[35.562546,-22.09],[35.533935,-23.070788],[35.371774,-23.535359],[35.60747,-23.706563],[35.458746,-24.12261],[35.040735,-24.478351],[34.215824,-24.816314],[33.01321,-25.357573],[32.574632,-25.727318],[32.660363,-26.148584],[32.915955,-26.215867],[32.83012,-26.742192],[32.071665,-26.73382],[31.985779,-26.29178],[31.837778,-25.843332],[31.752408,-25.484284],[31.930589,-24.369417],[31.670398,-23.658969],[31.191409,-22.25151],[32.244988,-21.116489],[32.508693,-20.395292],[32.659743,-20.30429],[32.772708,-19.715592],[32.611994,-19.419383],[32.654886,-18.67209],[32.849861,-17.979057],[32.847639,-16.713398],[32.328239,-16.392074],[31.852041,-16.319417],[31.636498,-16.07199],[31.173064,-15.860944],[30.338955,-15.880839],[30.274256,-15.507787],[30.179481,-14.796099],[33.214025,-13.97186],[33.7897,-14.451831],[34.064825,-14.35995],[34.459633,-14.61301],[34.517666,-15.013709],[34.307291,-15.478641],[34.381292,-16.18356],[35.03381,-16.8013],[35.339063,-16.10744],[35.771905,-15.896859],[35.686845,-14.611046],[35.267956,-13.887834],[34.907151,-13.565425],[34.559989,-13.579998],[34.280006,-12.280025],[34.559989,-11.52002]]]}}, {"type":"Feature","id":"MRT","properties":{"name":"Mauritania"},"geometry":{"type":"Polygon","coordinates":[[[-12.17075,14.616834],[-12.830658,15.303692],[-13.435738,16.039383],[-14.099521,16.304302],[-14.577348,16.598264],[-15.135737,16.587282],[-15.623666,16.369337],[-16.12069,16.455663],[-16.463098,16.135036],[-16.549708,16.673892],[-16.270552,17.166963],[-16.146347,18.108482],[-16.256883,19.096716],[-16.377651,19.593817],[-16.277838,20.092521],[-16.536324,20.567866],[-17.063423,20.999752],[-16.845194,21.333323],[-12.929102,21.327071],[-13.118754,22.77122],[-12.874222,23.284832],[-11.937224,23.374594],[-11.969419,25.933353],[-8.687294,25.881056],[-8.6844,27.395744],[-4.923337,24.974574],[-6.453787,24.956591],[-5.971129,20.640833],[-5.488523,16.325102],[-5.315277,16.201854],[-5.537744,15.50169],[-9.550238,15.486497],[-9.700255,15.264107],[-10.086846,15.330486],[-10.650791,15.132746],[-11.349095,15.411256],[-11.666078,15.388208],[-11.834208,14.799097],[-12.17075,14.616834]]]}}, {"type":"Feature","id":"MWI","properties":{"name":"Malawi"},"geometry":{"type":"Polygon","coordinates":[[[34.559989,-11.52002],[34.280006,-12.280025],[34.559989,-13.579998],[34.907151,-13.565425],[35.267956,-13.887834],[35.686845,-14.611046],[35.771905,-15.896859],[35.339063,-16.10744],[35.03381,-16.8013],[34.381292,-16.18356],[34.307291,-15.478641],[34.517666,-15.013709],[34.459633,-14.61301],[34.064825,-14.35995],[33.7897,-14.451831],[33.214025,-13.97186],[32.688165,-13.712858],[32.991764,-12.783871],[33.306422,-12.435778],[33.114289,-11.607198],[33.31531,-10.79655],[33.485688,-10.525559],[33.231388,-9.676722],[32.759375,-9.230599],[33.739729,-9.417151],[33.940838,-9.693674],[34.280006,-10.16],[34.559989,-11.52002]]]}}, {"type":"Feature","id":"MYS","properties":{"name":"Malaysia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[101.075516,6.204867],[101.154219,5.691384],[101.814282,5.810808],[102.141187,6.221636],[102.371147,6.128205],[102.961705,5.524495],[103.381215,4.855001],[103.438575,4.181606],[103.332122,3.726698],[103.429429,3.382869],[103.502448,2.791019],[103.854674,2.515454],[104.247932,1.631141],[104.228811,1.293048],[103.519707,1.226334],[102.573615,1.967115],[101.390638,2.760814],[101.27354,3.270292],[100.695435,3.93914],[100.557408,4.76728],[100.196706,5.312493],[100.30626,6.040562],[100.085757,6.464489],[100.259596,6.642825],[101.075516,6.204867]]],[[[118.618321,4.478202],[117.882035,4.137551],[117.015214,4.306094],[115.865517,4.306559],[115.519078,3.169238],[115.134037,2.821482],[114.621355,1.430688],[113.80585,1.217549],[112.859809,1.49779],[112.380252,1.410121],[111.797548,0.904441],[111.159138,0.976478],[110.514061,0.773131],[109.830227,1.338136],[109.66326,2.006467],[110.396135,1.663775],[111.168853,1.850637],[111.370081,2.697303],[111.796928,2.885897],[112.995615,3.102395],[113.712935,3.893509],[114.204017,4.525874],[114.659596,4.007637],[114.869557,4.348314],[115.347461,4.316636],[115.4057,4.955228],[115.45071,5.44773],[116.220741,6.143191],[116.725103,6.924771],[117.129626,6.928053],[117.643393,6.422166],[117.689075,5.98749],[118.347691,5.708696],[119.181904,5.407836],[119.110694,5.016128],[118.439727,4.966519],[118.618321,4.478202]]]]}}, {"type":"Feature","id":"NAM","properties":{"name":"Namibia"},"geometry":{"type":"Polygon","coordinates":[[[16.344977,-28.576705],[15.601818,-27.821247],[15.210472,-27.090956],[14.989711,-26.117372],[14.743214,-25.39292],[14.408144,-23.853014],[14.385717,-22.656653],[14.257714,-22.111208],[13.868642,-21.699037],[13.352498,-20.872834],[12.826845,-19.673166],[12.608564,-19.045349],[11.794919,-18.069129],[11.734199,-17.301889],[12.215461,-17.111668],[12.814081,-16.941343],[13.462362,-16.971212],[14.058501,-17.423381],[14.209707,-17.353101],[18.263309,-17.309951],[18.956187,-17.789095],[21.377176,-17.930636],[23.215048,-17.523116],[24.033862,-17.295843],[24.682349,-17.353411],[25.07695,-17.578823],[25.084443,-17.661816],[24.520705,-17.887125],[24.217365,-17.889347],[23.579006,-18.281261],[23.196858,-17.869038],[21.65504,-18.219146],[20.910641,-18.252219],[20.881134,-21.814327],[19.895458,-21.849157],[19.895768,-24.76779],[19.894734,-28.461105],[19.002127,-28.972443],[18.464899,-29.045462],[17.836152,-28.856378],[17.387497,-28.783514],[17.218929,-28.355943],[16.824017,-28.082162],[16.344977,-28.576705]]]}}, {"type":"Feature","id":"NCL","properties":{"name":"New Caledonia"},"geometry":{"type":"Polygon","coordinates":[[[165.77999,-21.080005],[166.599991,-21.700019],[167.120011,-22.159991],[166.740035,-22.399976],[166.189732,-22.129708],[165.474375,-21.679607],[164.829815,-21.14982],[164.167995,-20.444747],[164.029606,-20.105646],[164.459967,-20.120012],[165.020036,-20.459991],[165.460009,-20.800022],[165.77999,-21.080005]]]}}, {"type":"Feature","id":"NER","properties":{"name":"Niger"},"geometry":{"type":"Polygon","coordinates":[[[2.154474,11.94015],[2.177108,12.625018],[1.024103,12.851826],[0.993046,13.33575],[0.429928,13.988733],[0.295646,14.444235],[0.374892,14.928908],[1.015783,14.968182],[1.385528,15.323561],[2.749993,15.409525],[3.638259,15.56812],[3.723422,16.184284],[4.27021,16.852227],[4.267419,19.155265],[5.677566,19.601207],[8.572893,21.565661],[11.999506,23.471668],[13.581425,23.040506],[14.143871,22.491289],[14.8513,22.86295],[15.096888,21.308519],[15.471077,21.048457],[15.487148,20.730415],[15.903247,20.387619],[15.685741,19.95718],[15.300441,17.92795],[15.247731,16.627306],[13.972202,15.684366],[13.540394,14.367134],[13.956699,13.996691],[13.954477,13.353449],[14.595781,13.330427],[14.495787,12.859396],[14.213531,12.802035],[14.181336,12.483657],[13.995353,12.461565],[13.318702,13.556356],[13.083987,13.596147],[12.302071,13.037189],[11.527803,13.32898],[10.989593,13.387323],[10.701032,13.246918],[10.114814,13.277252],[9.524928,12.851102],[9.014933,12.826659],[7.804671,13.343527],[7.330747,13.098038],[6.820442,13.115091],[6.445426,13.492768],[5.443058,13.865924],[4.368344,13.747482],[4.107946,13.531216],[3.967283,12.956109],[3.680634,12.552903],[3.61118,11.660167],[2.848643,12.235636],[2.490164,12.233052],[2.154474,11.94015]]]}}, {"type":"Feature","id":"NGA","properties":{"name":"Nigeria"},"geometry":{"type":"Polygon","coordinates":[[[8.500288,4.771983],[7.462108,4.412108],[7.082596,4.464689],[6.698072,4.240594],[5.898173,4.262453],[5.362805,4.887971],[5.033574,5.611802],[4.325607,6.270651],[3.57418,6.2583],[2.691702,6.258817],[2.749063,7.870734],[2.723793,8.506845],[2.912308,9.137608],[3.220352,9.444153],[3.705438,10.06321],[3.60007,10.332186],[3.797112,10.734746],[3.572216,11.327939],[3.61118,11.660167],[3.680634,12.552903],[3.967283,12.956109],[4.107946,13.531216],[4.368344,13.747482],[5.443058,13.865924],[6.445426,13.492768],[6.820442,13.115091],[7.330747,13.098038],[7.804671,13.343527],[9.014933,12.826659],[9.524928,12.851102],[10.114814,13.277252],[10.701032,13.246918],[10.989593,13.387323],[11.527803,13.32898],[12.302071,13.037189],[13.083987,13.596147],[13.318702,13.556356],[13.995353,12.461565],[14.181336,12.483657],[14.577178,12.085361],[14.468192,11.904752],[14.415379,11.572369],[13.57295,10.798566],[13.308676,10.160362],[13.1676,9.640626],[12.955468,9.417772],[12.753672,8.717763],[12.218872,8.305824],[12.063946,7.799808],[11.839309,7.397042],[11.745774,6.981383],[11.058788,6.644427],[10.497375,7.055358],[10.118277,7.03877],[9.522706,6.453482],[9.233163,6.444491],[8.757533,5.479666],[8.500288,4.771983]]]}}, {"type":"Feature","id":"NIC","properties":{"name":"Nicaragua"},"geometry":{"type":"Polygon","coordinates":[[[-85.71254,11.088445],[-86.058488,11.403439],[-86.52585,11.806877],[-86.745992,12.143962],[-87.167516,12.458258],[-87.668493,12.90991],[-87.557467,13.064552],[-87.392386,12.914018],[-87.316654,12.984686],[-87.005769,13.025794],[-86.880557,13.254204],[-86.733822,13.263093],[-86.755087,13.754845],[-86.520708,13.778487],[-86.312142,13.771356],[-86.096264,14.038187],[-85.801295,13.836055],[-85.698665,13.960078],[-85.514413,14.079012],[-85.165365,14.35437],[-85.148751,14.560197],[-85.052787,14.551541],[-84.924501,14.790493],[-84.820037,14.819587],[-84.649582,14.666805],[-84.449336,14.621614],[-84.228342,14.748764],[-83.975721,14.749436],[-83.628585,14.880074],[-83.489989,15.016267],[-83.147219,14.995829],[-83.233234,14.899866],[-83.284162,14.676624],[-83.182126,14.310703],[-83.4125,13.970078],[-83.519832,13.567699],[-83.552207,13.127054],[-83.498515,12.869292],[-83.473323,12.419087],[-83.626104,12.32085],[-83.719613,11.893124],[-83.650858,11.629032],[-83.85547,11.373311],[-83.808936,11.103044],[-83.655612,10.938764],[-83.895054,10.726839],[-84.190179,10.79345],[-84.355931,10.999226],[-84.673069,11.082657],[-84.903003,10.952303],[-85.561852,11.217119],[-85.71254,11.088445]]]}}, {"type":"Feature","id":"NLD","properties":{"name":"Netherlands"},"geometry":{"type":"Polygon","coordinates":[[[6.074183,53.510403],[6.90514,53.482162],[7.092053,53.144043],[6.84287,52.22844],[6.589397,51.852029],[5.988658,51.851616],[6.156658,50.803721],[5.606976,51.037298],[4.973991,51.475024],[4.047071,51.267259],[3.314971,51.345755],[3.830289,51.620545],[4.705997,53.091798],[6.074183,53.510403]]]}}, {"type":"Feature","id":"NOR","properties":{"name":"Norway"},"geometry":{"type":"MultiPolygon","coordinates":[[[[28.165547,71.185474],[31.293418,70.453788],[30.005435,70.186259],[31.101079,69.55808],[29.399581,69.156916],[28.59193,69.064777],[29.015573,69.766491],[27.732292,70.164193],[26.179622,69.825299],[25.689213,69.092114],[24.735679,68.649557],[23.66205,68.891247],[22.356238,68.841741],[21.244936,69.370443],[20.645593,69.106247],[20.025269,69.065139],[19.87856,68.407194],[17.993868,68.567391],[17.729182,68.010552],[16.768879,68.013937],[16.108712,67.302456],[15.108411,66.193867],[13.55569,64.787028],[13.919905,64.445421],[13.571916,64.049114],[12.579935,64.066219],[11.930569,63.128318],[11.992064,61.800362],[12.631147,61.293572],[12.300366,60.117933],[11.468272,59.432393],[11.027369,58.856149],[10.356557,59.469807],[8.382,58.313288],[7.048748,58.078884],[5.665835,58.588155],[5.308234,59.663232],[4.992078,61.970998],[5.9129,62.614473],[8.553411,63.454008],[10.527709,64.486038],[12.358347,65.879726],[14.761146,67.810642],[16.435927,68.563205],[19.184028,69.817444],[21.378416,70.255169],[23.023742,70.202072],[24.546543,71.030497],[26.37005,70.986262],[28.165547,71.185474]]],[[[24.72412,77.85385],[22.49032,77.44493],[20.72601,77.67704],[21.41611,77.93504],[20.8119,78.25463],[22.88426,78.45494],[23.28134,78.07954],[24.72412,77.85385]]],[[[18.25183,79.70175],[21.54383,78.95611],[19.02737,78.5626],[18.47172,77.82669],[17.59441,77.63796],[17.1182,76.80941],[15.91315,76.77045],[13.76259,77.38035],[14.66956,77.73565],[13.1706,78.02493],[11.22231,78.8693],[10.44453,79.65239],[13.17077,80.01046],[13.71852,79.66039],[15.14282,79.67431],[15.52255,80.01608],[16.99085,80.05086],[18.25183,79.70175]]],[[[25.447625,80.40734],[27.407506,80.056406],[25.924651,79.517834],[23.024466,79.400012],[20.075188,79.566823],[19.897266,79.842362],[18.462264,79.85988],[17.368015,80.318896],[20.455992,80.598156],[21.907945,80.357679],[22.919253,80.657144],[25.447625,80.40734]]]]}}, {"type":"Feature","id":"NPL","properties":{"name":"Nepal"},"geometry":{"type":"Polygon","coordinates":[[[88.120441,27.876542],[88.043133,27.445819],[88.174804,26.810405],[88.060238,26.414615],[87.227472,26.397898],[86.024393,26.630985],[85.251779,26.726198],[84.675018,27.234901],[83.304249,27.364506],[81.999987,27.925479],[81.057203,28.416095],[80.088425,28.79447],[80.476721,29.729865],[81.111256,30.183481],[81.525804,30.422717],[82.327513,30.115268],[83.337115,29.463732],[83.898993,29.320226],[84.23458,28.839894],[85.011638,28.642774],[85.82332,28.203576],[86.954517,27.974262],[88.120441,27.876542]]]}}, {"type":"Feature","id":"NZL","properties":{"name":"New Zealand"},"geometry":{"type":"MultiPolygon","coordinates":[[[[173.020375,-40.919052],[173.247234,-41.331999],[173.958405,-40.926701],[174.247587,-41.349155],[174.248517,-41.770008],[173.876447,-42.233184],[173.22274,-42.970038],[172.711246,-43.372288],[173.080113,-43.853344],[172.308584,-43.865694],[171.452925,-44.242519],[171.185138,-44.897104],[170.616697,-45.908929],[169.831422,-46.355775],[169.332331,-46.641235],[168.411354,-46.619945],[167.763745,-46.290197],[166.676886,-46.219917],[166.509144,-45.852705],[167.046424,-45.110941],[168.303763,-44.123973],[168.949409,-43.935819],[169.667815,-43.555326],[170.52492,-43.031688],[171.12509,-42.512754],[171.569714,-41.767424],[171.948709,-41.514417],[172.097227,-40.956104],[172.79858,-40.493962],[173.020375,-40.919052]]],[[[174.612009,-36.156397],[175.336616,-37.209098],[175.357596,-36.526194],[175.808887,-36.798942],[175.95849,-37.555382],[176.763195,-37.881253],[177.438813,-37.961248],[178.010354,-37.579825],[178.517094,-37.695373],[178.274731,-38.582813],[177.97046,-39.166343],[177.206993,-39.145776],[176.939981,-39.449736],[177.032946,-39.879943],[176.885824,-40.065978],[176.508017,-40.604808],[176.01244,-41.289624],[175.239567,-41.688308],[175.067898,-41.425895],[174.650973,-41.281821],[175.22763,-40.459236],[174.900157,-39.908933],[173.824047,-39.508854],[173.852262,-39.146602],[174.574802,-38.797683],[174.743474,-38.027808],[174.697017,-37.381129],[174.292028,-36.711092],[174.319004,-36.534824],[173.840997,-36.121981],[173.054171,-35.237125],[172.636005,-34.529107],[173.007042,-34.450662],[173.551298,-35.006183],[174.32939,-35.265496],[174.612009,-36.156397]]]]}}, {"type":"Feature","id":"OMN","properties":{"name":"Oman"},"geometry":{"type":"MultiPolygon","coordinates":[[[[58.861141,21.114035],[58.487986,20.428986],[58.034318,20.481437],[57.826373,20.243002],[57.665762,19.736005],[57.7887,19.06757],[57.694391,18.94471],[57.234264,18.947991],[56.609651,18.574267],[56.512189,18.087113],[56.283521,17.876067],[55.661492,17.884128],[55.269939,17.632309],[55.2749,17.228354],[54.791002,16.950697],[54.239253,17.044981],[53.570508,16.707663],[53.108573,16.651051],[52.782184,17.349742],[52.00001,19.000003],[54.999982,19.999994],[55.666659,22.000001],[55.208341,22.70833],[55.234489,23.110993],[55.525841,23.524869],[55.528632,23.933604],[55.981214,24.130543],[55.804119,24.269604],[55.886233,24.920831],[56.396847,24.924732],[56.84514,24.241673],[57.403453,23.878594],[58.136948,23.747931],[58.729211,23.565668],[59.180502,22.992395],[59.450098,22.660271],[59.80806,22.533612],[59.806148,22.310525],[59.442191,21.714541],[59.282408,21.433886],[58.861141,21.114035]]],[[[56.391421,25.895991],[56.261042,25.714606],[56.070821,26.055464],[56.362017,26.395934],[56.485679,26.309118],[56.391421,25.895991]]]]}}, {"type":"Feature","id":"PAK","properties":{"name":"Pakistan"},"geometry":{"type":"Polygon","coordinates":[[[75.158028,37.133031],[75.896897,36.666806],[76.192848,35.898403],[77.837451,35.49401],[76.871722,34.653544],[75.757061,34.504923],[74.240203,34.748887],[73.749948,34.317699],[74.104294,33.441473],[74.451559,32.7649],[75.258642,32.271105],[74.405929,31.692639],[74.42138,30.979815],[73.450638,29.976413],[72.823752,28.961592],[71.777666,27.91318],[70.616496,27.989196],[69.514393,26.940966],[70.168927,26.491872],[70.282873,25.722229],[70.844699,25.215102],[71.04324,24.356524],[68.842599,24.359134],[68.176645,23.691965],[67.443667,23.944844],[67.145442,24.663611],[66.372828,25.425141],[64.530408,25.237039],[62.905701,25.218409],[61.497363,25.078237],[61.874187,26.239975],[63.316632,26.756532],[63.233898,27.217047],[62.755426,27.378923],[62.72783,28.259645],[61.771868,28.699334],[61.369309,29.303276],[60.874248,29.829239],[62.549857,29.318572],[63.550261,29.468331],[64.148002,29.340819],[64.350419,29.560031],[65.046862,29.472181],[66.346473,29.887943],[66.381458,30.738899],[66.938891,31.304911],[67.683394,31.303154],[67.792689,31.58293],[68.556932,31.71331],[68.926677,31.620189],[69.317764,31.901412],[69.262522,32.501944],[69.687147,33.105499],[70.323594,33.358533],[69.930543,34.02012],[70.881803,33.988856],[71.156773,34.348911],[71.115019,34.733126],[71.613076,35.153203],[71.498768,35.650563],[71.262348,36.074388],[71.846292,36.509942],[72.920025,36.720007],[74.067552,36.836176],[74.575893,37.020841],[75.158028,37.133031]]]}}, {"type":"Feature","id":"PAN","properties":{"name":"Panama"},"geometry":{"type":"Polygon","coordinates":[[[-77.881571,7.223771],[-78.214936,7.512255],[-78.429161,8.052041],[-78.182096,8.319182],[-78.435465,8.387705],[-78.622121,8.718124],[-79.120307,8.996092],[-79.557877,8.932375],[-79.760578,8.584515],[-80.164481,8.333316],[-80.382659,8.298409],[-80.480689,8.090308],[-80.00369,7.547524],[-80.276671,7.419754],[-80.421158,7.271572],[-80.886401,7.220541],[-81.059543,7.817921],[-81.189716,7.647906],[-81.519515,7.70661],[-81.721311,8.108963],[-82.131441,8.175393],[-82.390934,8.292362],[-82.820081,8.290864],[-82.850958,8.073823],[-82.965783,8.225028],[-82.913176,8.423517],[-82.829771,8.626295],[-82.868657,8.807266],[-82.719183,8.925709],[-82.927155,9.07433],[-82.932891,9.476812],[-82.546196,9.566135],[-82.187123,9.207449],[-82.207586,8.995575],[-81.808567,8.950617],[-81.714154,9.031955],[-81.439287,8.786234],[-80.947302,8.858504],[-80.521901,9.111072],[-79.9146,9.312765],[-79.573303,9.61161],[-79.021192,9.552931],[-79.05845,9.454565],[-78.500888,9.420459],[-78.055928,9.24773],[-77.729514,8.946844],[-77.353361,8.670505],[-77.474723,8.524286],[-77.242566,7.935278],[-77.431108,7.638061],[-77.753414,7.70984],[-77.881571,7.223771]]]}}, {"type":"Feature","id":"PER","properties":{"name":"Peru"},"geometry":{"type":"Polygon","coordinates":[[[-69.590424,-17.580012],[-69.858444,-18.092694],[-70.372572,-18.347975],[-71.37525,-17.773799],[-71.462041,-17.363488],[-73.44453,-16.359363],[-75.237883,-15.265683],[-76.009205,-14.649286],[-76.423469,-13.823187],[-76.259242,-13.535039],[-77.106192,-12.222716],[-78.092153,-10.377712],[-79.036953,-8.386568],[-79.44592,-7.930833],[-79.760578,-7.194341],[-80.537482,-6.541668],[-81.249996,-6.136834],[-80.926347,-5.690557],[-81.410943,-4.736765],[-81.09967,-4.036394],[-80.302561,-3.404856],[-80.184015,-3.821162],[-80.469295,-4.059287],[-80.442242,-4.425724],[-80.028908,-4.346091],[-79.624979,-4.454198],[-79.205289,-4.959129],[-78.639897,-4.547784],[-78.450684,-3.873097],[-77.837905,-3.003021],[-76.635394,-2.608678],[-75.544996,-1.56161],[-75.233723,-0.911417],[-75.373223,-0.152032],[-75.106625,-0.057205],[-74.441601,-0.53082],[-74.122395,-1.002833],[-73.659504,-1.260491],[-73.070392,-2.308954],[-72.325787,-2.434218],[-71.774761,-2.16979],[-71.413646,-2.342802],[-70.813476,-2.256865],[-70.047709,-2.725156],[-70.692682,-3.742872],[-70.394044,-3.766591],[-69.893635,-4.298187],[-70.794769,-4.251265],[-70.928843,-4.401591],[-71.748406,-4.593983],[-72.891928,-5.274561],[-72.964507,-5.741251],[-73.219711,-6.089189],[-73.120027,-6.629931],[-73.724487,-6.918595],[-73.723401,-7.340999],[-73.987235,-7.52383],[-73.571059,-8.424447],[-73.015383,-9.032833],[-73.226713,-9.462213],[-72.563033,-9.520194],[-72.184891,-10.053598],[-71.302412,-10.079436],[-70.481894,-9.490118],[-70.548686,-11.009147],[-70.093752,-11.123972],[-69.529678,-10.951734],[-68.66508,-12.5613],[-68.88008,-12.899729],[-68.929224,-13.602684],[-68.948887,-14.453639],[-69.339535,-14.953195],[-69.160347,-15.323974],[-69.389764,-15.660129],[-68.959635,-16.500698],[-69.590424,-17.580012]]]}}, {"type":"Feature","id":"PHL","properties":{"name":"Philippines"},"geometry":{"type":"MultiPolygon","coordinates":[[[[126.376814,8.414706],[126.478513,7.750354],[126.537424,7.189381],[126.196773,6.274294],[125.831421,7.293715],[125.363852,6.786485],[125.683161,6.049657],[125.396512,5.581003],[124.219788,6.161355],[123.93872,6.885136],[124.243662,7.36061],[123.610212,7.833527],[123.296071,7.418876],[122.825506,7.457375],[122.085499,6.899424],[121.919928,7.192119],[122.312359,8.034962],[122.942398,8.316237],[123.487688,8.69301],[123.841154,8.240324],[124.60147,8.514158],[124.764612,8.960409],[125.471391,8.986997],[125.412118,9.760335],[126.222714,9.286074],[126.306637,8.782487],[126.376814,8.414706]]],[[[123.982438,10.278779],[123.623183,9.950091],[123.309921,9.318269],[122.995883,9.022189],[122.380055,9.713361],[122.586089,9.981045],[122.837081,10.261157],[122.947411,10.881868],[123.49885,10.940624],[123.337774,10.267384],[124.077936,11.232726],[123.982438,10.278779]]],[[[118.504581,9.316383],[117.174275,8.3675],[117.664477,9.066889],[118.386914,9.6845],[118.987342,10.376292],[119.511496,11.369668],[119.689677,10.554291],[119.029458,10.003653],[118.504581,9.316383]]],[[[121.883548,11.891755],[122.483821,11.582187],[123.120217,11.58366],[123.100838,11.165934],[122.637714,10.741308],[122.00261,10.441017],[121.967367,10.905691],[122.03837,11.415841],[121.883548,11.891755]]],[[[125.502552,12.162695],[125.783465,11.046122],[125.011884,11.311455],[125.032761,10.975816],[125.277449,10.358722],[124.801819,10.134679],[124.760168,10.837995],[124.459101,10.88993],[124.302522,11.495371],[124.891013,11.415583],[124.87799,11.79419],[124.266762,12.557761],[125.227116,12.535721],[125.502552,12.162695]]],[[[121.527394,13.06959],[121.26219,12.20556],[120.833896,12.704496],[120.323436,13.466413],[121.180128,13.429697],[121.527394,13.06959]]],[[[121.321308,18.504065],[121.937601,18.218552],[122.246006,18.47895],[122.336957,18.224883],[122.174279,17.810283],[122.515654,17.093505],[122.252311,16.262444],[121.662786,15.931018],[121.50507,15.124814],[121.728829,14.328376],[122.258925,14.218202],[122.701276,14.336541],[123.950295,13.782131],[123.855107,13.237771],[124.181289,12.997527],[124.077419,12.536677],[123.298035,13.027526],[122.928652,13.55292],[122.671355,13.185836],[122.03465,13.784482],[121.126385,13.636687],[120.628637,13.857656],[120.679384,14.271016],[120.991819,14.525393],[120.693336,14.756671],[120.564145,14.396279],[120.070429,14.970869],[119.920929,15.406347],[119.883773,16.363704],[120.286488,16.034629],[120.390047,17.599081],[120.715867,18.505227],[121.321308,18.504065]]]]}}, {"type":"Feature","id":"PNG","properties":{"name":"Papua New Guinea"},"geometry":{"type":"MultiPolygon","coordinates":[[[[155.880026,-6.819997],[155.599991,-6.919991],[155.166994,-6.535931],[154.729192,-5.900828],[154.514114,-5.139118],[154.652504,-5.042431],[154.759991,-5.339984],[155.062918,-5.566792],[155.547746,-6.200655],[156.019965,-6.540014],[155.880026,-6.819997]]],[[[151.982796,-5.478063],[151.459107,-5.56028],[151.30139,-5.840728],[150.754447,-6.083763],[150.241197,-6.317754],[149.709963,-6.316513],[148.890065,-6.02604],[148.318937,-5.747142],[148.401826,-5.437756],[149.298412,-5.583742],[149.845562,-5.505503],[149.99625,-5.026101],[150.139756,-5.001348],[150.236908,-5.53222],[150.807467,-5.455842],[151.089672,-5.113693],[151.647881,-4.757074],[151.537862,-4.167807],[152.136792,-4.14879],[152.338743,-4.312966],[152.318693,-4.867661],[151.982796,-5.478063]]],[[[147.191874,-7.388024],[148.084636,-8.044108],[148.734105,-9.104664],[149.306835,-9.071436],[149.266631,-9.514406],[150.038728,-9.684318],[149.738798,-9.872937],[150.801628,-10.293687],[150.690575,-10.582713],[150.028393,-10.652476],[149.78231,-10.393267],[148.923138,-10.280923],[147.913018,-10.130441],[147.135443,-9.492444],[146.567881,-8.942555],[146.048481,-8.067414],[144.744168,-7.630128],[143.897088,-7.91533],[143.286376,-8.245491],[143.413913,-8.983069],[142.628431,-9.326821],[142.068259,-9.159596],[141.033852,-9.117893],[141.017057,-5.859022],[141.00021,-2.600151],[142.735247,-3.289153],[144.583971,-3.861418],[145.27318,-4.373738],[145.829786,-4.876498],[145.981922,-5.465609],[147.648073,-6.083659],[147.891108,-6.614015],[146.970905,-6.721657],[147.191874,-7.388024]]],[[[153.140038,-4.499983],[152.827292,-4.766427],[152.638673,-4.176127],[152.406026,-3.789743],[151.953237,-3.462062],[151.384279,-3.035422],[150.66205,-2.741486],[150.939965,-2.500002],[151.479984,-2.779985],[151.820015,-2.999972],[152.239989,-3.240009],[152.640017,-3.659983],[153.019994,-3.980015],[153.140038,-4.499983]]]]}}, {"type":"Feature","id":"POL","properties":{"name":"Poland"},"geometry":{"type":"Polygon","coordinates":[[[15.016996,51.106674],[14.607098,51.745188],[14.685026,52.089947],[14.4376,52.62485],[14.074521,52.981263],[14.353315,53.248171],[14.119686,53.757029],[14.8029,54.050706],[16.363477,54.513159],[17.622832,54.851536],[18.620859,54.682606],[18.696255,54.438719],[19.66064,54.426084],[20.892245,54.312525],[22.731099,54.327537],[23.243987,54.220567],[23.484128,53.912498],[23.527536,53.470122],[23.804935,53.089731],[23.799199,52.691099],[23.199494,52.486977],[23.508002,52.023647],[23.527071,51.578454],[24.029986,50.705407],[23.922757,50.424881],[23.426508,50.308506],[22.51845,49.476774],[22.776419,49.027395],[22.558138,49.085738],[21.607808,49.470107],[20.887955,49.328772],[20.415839,49.431453],[19.825023,49.217125],[19.320713,49.571574],[18.909575,49.435846],[18.853144,49.49623],[18.392914,49.988629],[17.649445,50.049038],[17.554567,50.362146],[16.868769,50.473974],[16.719476,50.215747],[16.176253,50.422607],[16.238627,50.697733],[15.490972,50.78473],[15.016996,51.106674]]]}}, {"type":"Feature","id":"PRI","properties":{"name":"Puerto Rico"},"geometry":{"type":"Polygon","coordinates":[[[-66.282434,18.514762],[-65.771303,18.426679],[-65.591004,18.228035],[-65.847164,17.975906],[-66.599934,17.981823],[-67.184162,17.946553],[-67.242428,18.37446],[-67.100679,18.520601],[-66.282434,18.514762]]]}}, {"type":"Feature","id":"PRK","properties":{"name":"North Korea"},"geometry":{"type":"Polygon","coordinates":[[[130.640016,42.395009],[130.780007,42.220007],[130.400031,42.280004],[129.965949,41.941368],[129.667362,41.601104],[129.705189,40.882828],[129.188115,40.661808],[129.0104,40.485436],[128.633368,40.189847],[127.967414,40.025413],[127.533436,39.75685],[127.50212,39.323931],[127.385434,39.213472],[127.783343,39.050898],[128.349716,38.612243],[128.205746,38.370397],[127.780035,38.304536],[127.073309,38.256115],[126.68372,37.804773],[126.237339,37.840378],[126.174759,37.749686],[125.689104,37.94001],[125.568439,37.752089],[125.27533,37.669071],[125.240087,37.857224],[124.981033,37.948821],[124.712161,38.108346],[124.985994,38.548474],[125.221949,38.665857],[125.132859,38.848559],[125.38659,39.387958],[125.321116,39.551385],[124.737482,39.660344],[124.265625,39.928493],[125.079942,40.569824],[126.182045,41.107336],[126.869083,41.816569],[127.343783,41.503152],[128.208433,41.466772],[128.052215,41.994285],[129.596669,42.424982],[129.994267,42.985387],[130.640016,42.395009]]]}}, {"type":"Feature","id":"PRT","properties":{"name":"Portugal"},"geometry":{"type":"Polygon","coordinates":[[[-9.034818,41.880571],[-8.671946,42.134689],[-8.263857,42.280469],[-8.013175,41.790886],[-7.422513,41.792075],[-7.251309,41.918346],[-6.668606,41.883387],[-6.389088,41.381815],[-6.851127,41.111083],[-6.86402,40.330872],[-7.026413,40.184524],[-7.066592,39.711892],[-7.498632,39.629571],[-7.098037,39.030073],[-7.374092,38.373059],[-7.029281,38.075764],[-7.166508,37.803894],[-7.537105,37.428904],[-7.453726,37.097788],[-7.855613,36.838269],[-8.382816,36.97888],[-8.898857,36.868809],[-8.746101,37.651346],[-8.839998,38.266243],[-9.287464,38.358486],[-9.526571,38.737429],[-9.446989,39.392066],[-9.048305,39.755093],[-8.977353,40.159306],[-8.768684,40.760639],[-8.790853,41.184334],[-8.990789,41.543459],[-9.034818,41.880571]]]}}, {"type":"Feature","id":"PRY","properties":{"name":"Paraguay"},"geometry":{"type":"Polygon","coordinates":[[[-62.685057,-22.249029],[-62.291179,-21.051635],[-62.265961,-20.513735],[-61.786326,-19.633737],[-60.043565,-19.342747],[-59.115042,-19.356906],[-58.183471,-19.868399],[-58.166392,-20.176701],[-57.870674,-20.732688],[-57.937156,-22.090176],[-56.88151,-22.282154],[-56.473317,-22.0863],[-55.797958,-22.35693],[-55.610683,-22.655619],[-55.517639,-23.571998],[-55.400747,-23.956935],[-55.027902,-24.001274],[-54.652834,-23.839578],[-54.29296,-24.021014],[-54.293476,-24.5708],[-54.428946,-25.162185],[-54.625291,-25.739255],[-54.788795,-26.621786],[-55.695846,-27.387837],[-56.486702,-27.548499],[-57.60976,-27.395899],[-58.618174,-27.123719],[-57.63366,-25.603657],[-57.777217,-25.16234],[-58.807128,-24.771459],[-60.028966,-24.032796],[-60.846565,-23.880713],[-62.685057,-22.249029]]]}}, {"type":"Feature","id":"QAT","properties":{"name":"Qatar"},"geometry":{"type":"Polygon","coordinates":[[[50.810108,24.754743],[50.743911,25.482424],[51.013352,26.006992],[51.286462,26.114582],[51.589079,25.801113],[51.6067,25.21567],[51.389608,24.627386],[51.112415,24.556331],[50.810108,24.754743]]]}}, {"type":"Feature","id":"ROU","properties":{"name":"Romania"},"geometry":{"type":"Polygon","coordinates":[[[22.710531,47.882194],[23.142236,48.096341],[23.760958,47.985598],[24.402056,47.981878],[24.866317,47.737526],[25.207743,47.891056],[25.945941,47.987149],[26.19745,48.220881],[26.619337,48.220726],[26.924176,48.123264],[27.233873,47.826771],[27.551166,47.405117],[28.12803,46.810476],[28.160018,46.371563],[28.054443,45.944586],[28.233554,45.488283],[28.679779,45.304031],[29.149725,45.464925],[29.603289,45.293308],[29.626543,45.035391],[29.141612,44.82021],[28.837858,44.913874],[28.558081,43.707462],[27.970107,43.812468],[27.2424,44.175986],[26.065159,43.943494],[25.569272,43.688445],[24.100679,43.741051],[23.332302,43.897011],[22.944832,43.823785],[22.65715,44.234923],[22.474008,44.409228],[22.705726,44.578003],[22.459022,44.702517],[22.145088,44.478422],[21.562023,44.768947],[21.483526,45.18117],[20.874313,45.416375],[20.762175,45.734573],[20.220192,46.127469],[21.021952,46.316088],[21.626515,46.994238],[22.099768,47.672439],[22.710531,47.882194]]]}}, {"type":"Feature","id":"RUS","properties":{"name":"Russia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[143.648007,50.7476],[144.654148,48.976391],[143.173928,49.306551],[142.558668,47.861575],[143.533492,46.836728],[143.505277,46.137908],[142.747701,46.740765],[142.09203,45.966755],[141.906925,46.805929],[142.018443,47.780133],[141.904445,48.859189],[142.1358,49.615163],[142.179983,50.952342],[141.594076,51.935435],[141.682546,53.301966],[142.606934,53.762145],[142.209749,54.225476],[142.654786,54.365881],[142.914616,53.704578],[143.260848,52.74076],[143.235268,51.75666],[143.648007,50.7476]]],[[[22.731099,54.327537],[20.892245,54.312525],[19.66064,54.426084],[19.888481,54.86616],[21.268449,55.190482],[22.315724,55.015299],[22.757764,54.856574],[22.651052,54.582741],[22.731099,54.327537]]],[[[-175.01425,66.58435],[-174.33983,66.33556],[-174.57182,67.06219],[-171.85731,66.91308],[-169.89958,65.97724],[-170.89107,65.54139],[-172.53025,65.43791],[-172.555,64.46079],[-172.95533,64.25269],[-173.89184,64.2826],[-174.65392,64.63125],[-175.98353,64.92288],[-176.20716,65.35667],[-177.22266,65.52024],[-178.35993,65.39052],[-178.90332,65.74044],[-178.68611,66.11211],[-179.88377,65.87456],[-179.43268,65.40411],[-180,64.979709],[-180,68.963636],[-177.55,68.2],[-174.92825,67.20589],[-175.01425,66.58435]]],[[[180,70.832199],[178.903425,70.78114],[178.7253,71.0988],[180,71.515714],[180,70.832199]]],[[[-178.69378,70.89302],[-180,70.832199],[-180,71.515714],[-179.871875,71.55762],[-179.02433,71.55553],[-177.577945,71.26948],[-177.663575,71.13277],[-178.69378,70.89302]]],[[[143.60385,73.21244],[142.08763,73.20544],[140.038155,73.31692],[139.86312,73.36983],[140.81171,73.76506],[142.06207,73.85758],[143.48283,73.47525],[143.60385,73.21244]]],[[[150.73167,75.08406],[149.575925,74.68892],[147.977465,74.778355],[146.11919,75.17298],[146.358485,75.49682],[148.22223,75.345845],[150.73167,75.08406]]],[[[145.086285,75.562625],[144.3,74.82],[140.61381,74.84768],[138.95544,74.61148],[136.97439,75.26167],[137.51176,75.94917],[138.831075,76.13676],[141.471615,76.09289],[145.086285,75.562625]]],[[[57.535693,70.720464],[56.944979,70.632743],[53.677375,70.762658],[53.412017,71.206662],[51.601895,71.474759],[51.455754,72.014881],[52.478275,72.229442],[52.444169,72.774731],[54.427614,73.627548],[53.50829,73.749814],[55.902459,74.627486],[55.631933,75.081412],[57.868644,75.60939],[61.170044,76.251883],[64.498368,76.439055],[66.210977,76.809782],[68.15706,76.939697],[68.852211,76.544811],[68.180573,76.233642],[64.637326,75.737755],[61.583508,75.260885],[58.477082,74.309056],[56.986786,73.333044],[55.419336,72.371268],[55.622838,71.540595],[57.535693,70.720464]]],[[[106.97013,76.97419],[107.24,76.48],[108.1538,76.72335],[111.07726,76.71],[113.33151,76.22224],[114.13417,75.84764],[113.88539,75.32779],[112.77918,75.03186],[110.15125,74.47673],[109.4,74.18],[110.64,74.04],[112.11919,73.78774],[113.01954,73.97693],[113.52958,73.33505],[113.96881,73.59488],[115.56782,73.75285],[118.77633,73.58772],[119.02,73.12],[123.20066,72.97122],[123.25777,73.73503],[125.38,73.56],[126.97644,73.56549],[128.59126,73.03871],[129.05157,72.39872],[128.46,71.98],[129.71599,71.19304],[131.28858,70.78699],[132.2535,71.8363],[133.85766,71.38642],[135.56193,71.65525],[137.49755,71.34763],[138.23409,71.62803],[139.86983,71.48783],[139.14791,72.41619],[140.46817,72.84941],[149.5,72.2],[150.35118,71.60643],[152.9689,70.84222],[157.00688,71.03141],[158.99779,70.86672],[159.83031,70.45324],[159.70866,69.72198],[160.94053,69.43728],[162.27907,69.64204],[164.05248,69.66823],[165.94037,69.47199],[167.83567,69.58269],[169.57763,68.6938],[170.81688,69.01363],[170.0082,69.65276],[170.45345,70.09703],[173.64391,69.81743],[175.72403,69.87725],[178.6,69.4],[180,68.963636],[180,64.979709],[179.99281,64.97433],[178.7072,64.53493],[177.41128,64.60821],[178.313,64.07593],[178.90825,63.25197],[179.37034,62.98262],[179.48636,62.56894],[179.22825,62.3041],[177.3643,62.5219],[174.56929,61.76915],[173.68013,61.65261],[172.15,60.95],[170.6985,60.33618],[170.33085,59.88177],[168.90046,60.57355],[166.29498,59.78855],[165.84,60.16],[164.87674,59.7316],[163.53929,59.86871],[163.21711,59.21101],[162.01733,58.24328],[162.05297,57.83912],[163.19191,57.61503],[163.05794,56.15924],[162.12958,56.12219],[161.70146,55.28568],[162.11749,54.85514],[160.36877,54.34433],[160.02173,53.20257],[158.53094,52.95868],[158.23118,51.94269],[156.78979,51.01105],[156.42,51.7],[155.99182,53.15895],[155.43366,55.38103],[155.91442,56.76792],[156.75815,57.3647],[156.81035,57.83204],[158.36433,58.05575],[160.15064,59.31477],[161.87204,60.343],[163.66969,61.1409],[164.47355,62.55061],[163.25842,62.46627],[162.65791,61.6425],[160.12148,60.54423],[159.30232,61.77396],[156.72068,61.43442],[154.21806,59.75818],[155.04375,59.14495],[152.81185,58.88385],[151.26573,58.78089],[151.33815,59.50396],[149.78371,59.65573],[148.54481,59.16448],[145.48722,59.33637],[142.19782,59.03998],[138.95848,57.08805],[135.12619,54.72959],[136.70171,54.60355],[137.19342,53.97732],[138.1647,53.75501],[138.80463,54.25455],[139.90151,54.18968],[141.34531,53.08957],[141.37923,52.23877],[140.59742,51.23967],[140.51308,50.04553],[140.06193,48.44671],[138.55472,46.99965],[138.21971,46.30795],[136.86232,45.1435],[135.51535,43.989],[134.86939,43.39821],[133.53687,42.81147],[132.90627,42.79849],[132.27807,43.28456],[130.93587,42.55274],[130.78,42.22],[130.64,42.395],[130.633866,42.903015],[131.144688,42.92999],[131.288555,44.11152],[131.02519,44.96796],[131.883454,45.321162],[133.09712,45.14409],[133.769644,46.116927],[134.11235,47.21248],[134.50081,47.57845],[135.026311,48.47823],[133.373596,48.183442],[132.50669,47.78896],[130.98726,47.79013],[130.582293,48.729687],[129.397818,49.4406],[127.6574,49.76027],[127.287456,50.739797],[126.939157,51.353894],[126.564399,51.784255],[125.946349,52.792799],[125.068211,53.161045],[123.57147,53.4588],[122.245748,53.431726],[121.003085,53.251401],[120.177089,52.753886],[120.725789,52.516226],[120.7382,51.96411],[120.18208,51.64355],[119.27939,50.58292],[119.288461,50.142883],[117.879244,49.510983],[116.678801,49.888531],[115.485695,49.805177],[114.96211,50.140247],[114.362456,50.248303],[112.89774,49.543565],[111.581231,49.377968],[110.662011,49.130128],[109.402449,49.292961],[108.475167,49.282548],[107.868176,49.793705],[106.888804,50.274296],[105.886591,50.406019],[104.62158,50.27532],[103.676545,50.089966],[102.25589,50.51056],[102.06521,51.25991],[100.88948,51.516856],[99.981732,51.634006],[98.861491,52.047366],[97.82574,51.010995],[98.231762,50.422401],[97.25976,49.72605],[95.81402,49.97746],[94.815949,50.013433],[94.147566,50.480537],[93.10421,50.49529],[92.234712,50.802171],[90.713667,50.331812],[88.805567,49.470521],[87.751264,49.297198],[87.35997,49.214981],[86.829357,49.826675],[85.54127,49.692859],[85.11556,50.117303],[84.416377,50.3114],[83.935115,50.889246],[83.383004,51.069183],[81.945986,50.812196],[80.568447,51.388336],[80.03556,50.864751],[77.800916,53.404415],[76.525179,54.177003],[76.8911,54.490524],[74.38482,53.54685],[73.425679,53.48981],[73.508516,54.035617],[72.22415,54.376655],[71.180131,54.133285],[70.865267,55.169734],[69.068167,55.38525],[68.1691,54.970392],[65.66687,54.60125],[65.178534,54.354228],[61.4366,54.00625],[60.978066,53.664993],[61.699986,52.979996],[60.739993,52.719986],[60.927269,52.447548],[59.967534,51.96042],[61.588003,51.272659],[61.337424,50.79907],[59.932807,50.842194],[59.642282,50.545442],[58.36332,51.06364],[56.77798,51.04355],[55.71694,50.62171],[54.532878,51.02624],[52.328724,51.718652],[50.766648,51.692762],[48.702382,50.605128],[48.577841,49.87476],[47.54948,50.454698],[46.751596,49.356006],[47.043672,49.152039],[46.466446,48.394152],[47.31524,47.71585],[48.05725,47.74377],[48.694734,47.075628],[48.59325,46.56104],[49.10116,46.39933],[48.64541,45.80629],[47.67591,45.64149],[46.68201,44.6092],[47.59094,43.66016],[47.49252,42.98658],[48.58437,41.80888],[47.987283,41.405819],[47.815666,41.151416],[47.373315,41.219732],[46.686071,41.827137],[46.404951,41.860675],[45.7764,42.09244],[45.470279,42.502781],[44.537623,42.711993],[43.93121,42.55496],[43.75599,42.74083],[42.3944,43.2203],[40.92219,43.38215],[40.076965,43.553104],[39.955009,43.434998],[38.68,44.28],[37.53912,44.65721],[36.67546,45.24469],[37.40317,45.40451],[38.23295,46.24087],[37.67372,46.63657],[39.14767,47.04475],[39.1212,47.26336],[38.223538,47.10219],[38.255112,47.5464],[38.77057,47.82562],[39.738278,47.898937],[39.89562,48.23241],[39.67465,48.78382],[40.080789,49.30743],[40.06904,49.60105],[38.594988,49.926462],[38.010631,49.915662],[37.39346,50.383953],[36.626168,50.225591],[35.356116,50.577197],[35.37791,50.77394],[35.022183,51.207572],[34.224816,51.255993],[34.141978,51.566413],[34.391731,51.768882],[33.7527,52.335075],[32.715761,52.238465],[32.412058,52.288695],[32.15944,52.06125],[31.78597,52.10168],[31.540018,52.742052],[31.305201,53.073996],[31.49764,53.16743],[32.304519,53.132726],[32.693643,53.351421],[32.405599,53.618045],[31.731273,53.794029],[31.791424,53.974639],[31.384472,54.157056],[30.757534,54.811771],[30.971836,55.081548],[30.873909,55.550976],[29.896294,55.789463],[29.371572,55.670091],[29.229513,55.918344],[28.176709,56.16913],[27.855282,56.759326],[27.770016,57.244258],[27.288185,57.474528],[27.716686,57.791899],[27.42015,58.72457],[28.131699,59.300825],[27.98112,59.47537],[29.1177,60.02805],[28.07,60.50352],[30.211107,61.780028],[31.139991,62.357693],[31.516092,62.867687],[30.035872,63.552814],[30.444685,64.204453],[29.54443,64.948672],[30.21765,65.80598],[29.054589,66.944286],[29.977426,67.698297],[28.445944,68.364613],[28.59193,69.064777],[29.39955,69.15692],[31.10108,69.55811],[32.13272,69.90595],[33.77547,69.30142],[36.51396,69.06342],[40.29234,67.9324],[41.05987,67.45713],[41.12595,66.79158],[40.01583,66.26618],[38.38295,65.99953],[33.91871,66.75961],[33.18444,66.63253],[34.81477,65.90015],[34.878574,65.436213],[34.94391,64.41437],[36.23129,64.10945],[37.01273,63.84983],[37.14197,64.33471],[36.539579,64.76446],[37.17604,65.14322],[39.59345,64.52079],[40.4356,64.76446],[39.7626,65.49682],[42.09309,66.47623],[43.01604,66.41858],[43.94975,66.06908],[44.53226,66.75634],[43.69839,67.35245],[44.18795,67.95051],[43.45282,68.57079],[46.25,68.25],[46.82134,67.68997],[45.55517,67.56652],[45.56202,67.01005],[46.34915,66.66767],[47.89416,66.88455],[48.13876,67.52238],[50.22766,67.99867],[53.71743,68.85738],[54.47171,68.80815],[53.48582,68.20131],[54.72628,68.09702],[55.44268,68.43866],[57.31702,68.46628],[58.802,68.88082],[59.94142,68.27844],[61.07784,68.94069],[60.03,69.52],[60.55,69.85],[63.504,69.54739],[64.888115,69.234835],[68.51216,68.09233],[69.18068,68.61563],[68.16444,69.14436],[68.13522,69.35649],[66.93008,69.45461],[67.25976,69.92873],[66.72492,70.70889],[66.69466,71.02897],[68.54006,71.9345],[69.19636,72.84336],[69.94,73.04],[72.58754,72.77629],[72.79603,72.22006],[71.84811,71.40898],[72.47011,71.09019],[72.79188,70.39114],[72.5647,69.02085],[73.66787,68.4079],[73.2387,67.7404],[71.28,66.32],[72.42301,66.17267],[72.82077,66.53267],[73.92099,66.78946],[74.18651,67.28429],[75.052,67.76047],[74.46926,68.32899],[74.93584,68.98918],[73.84236,69.07146],[73.60187,69.62763],[74.3998,70.63175],[73.1011,71.44717],[74.89082,72.12119],[74.65926,72.83227],[75.15801,72.85497],[75.68351,72.30056],[75.28898,71.33556],[76.35911,71.15287],[75.90313,71.87401],[77.57665,72.26717],[79.65202,72.32011],[81.5,71.75],[80.61071,72.58285],[80.51109,73.6482],[82.25,73.85],[84.65526,73.80591],[86.8223,73.93688],[86.00956,74.45967],[87.16682,75.11643],[88.31571,75.14393],[90.26,75.64],[92.90058,75.77333],[93.23421,76.0472],[95.86,76.14],[96.67821,75.91548],[98.92254,76.44689],[100.75967,76.43028],[101.03532,76.86189],[101.99084,77.28754],[104.3516,77.69792],[106.06664,77.37389],[104.705,77.1274],[106.97013,76.97419]]],[[[105.07547,78.30689],[99.43814,77.921],[101.2649,79.23399],[102.08635,79.34641],[102.837815,79.28129],[105.37243,78.71334],[105.07547,78.30689]]],[[[51.136187,80.54728],[49.793685,80.415428],[48.894411,80.339567],[48.754937,80.175468],[47.586119,80.010181],[46.502826,80.247247],[47.072455,80.559424],[44.846958,80.58981],[46.799139,80.771918],[48.318477,80.78401],[48.522806,80.514569],[49.09719,80.753986],[50.039768,80.918885],[51.522933,80.699726],[51.136187,80.54728]]],[[[99.93976,78.88094],[97.75794,78.7562],[94.97259,79.044745],[93.31288,79.4265],[92.5454,80.14379],[91.18107,80.34146],[93.77766,81.0246],[95.940895,81.2504],[97.88385,80.746975],[100.186655,79.780135],[99.93976,78.88094]]]]}}, {"type":"Feature","id":"RWA","properties":{"name":"Rwanda"},"geometry":{"type":"Polygon","coordinates":[[[30.419105,-1.134659],[30.816135,-1.698914],[30.758309,-2.28725],[30.469696,-2.413858],[29.938359,-2.348487],[29.632176,-2.917858],[29.024926,-2.839258],[29.117479,-2.292211],[29.254835,-2.21511],[29.291887,-1.620056],[29.579466,-1.341313],[29.821519,-1.443322],[30.419105,-1.134659]]]}}, {"type":"Feature","id":"ESH","properties":{"name":"Western Sahara"},"geometry":{"type":"Polygon","coordinates":[[[-8.794884,27.120696],[-8.817828,27.656426],[-8.66559,27.656426],[-8.665124,27.589479],[-8.6844,27.395744],[-8.687294,25.881056],[-11.969419,25.933353],[-11.937224,23.374594],[-12.874222,23.284832],[-13.118754,22.77122],[-12.929102,21.327071],[-16.845194,21.333323],[-17.063423,20.999752],[-17.020428,21.42231],[-17.002962,21.420734],[-14.750955,21.5006],[-14.630833,21.86094],[-14.221168,22.310163],[-13.89111,23.691009],[-12.500963,24.770116],[-12.030759,26.030866],[-11.71822,26.104092],[-11.392555,26.883424],[-10.551263,26.990808],[-10.189424,26.860945],[-9.735343,26.860945],[-9.413037,27.088476],[-8.794884,27.120696]]]}}, {"type":"Feature","id":"SAU","properties":{"name":"Saudi Arabia"},"geometry":{"type":"Polygon","coordinates":[[[42.779332,16.347891],[42.649573,16.774635],[42.347989,17.075806],[42.270888,17.474722],[41.754382,17.833046],[41.221391,18.6716],[40.939341,19.486485],[40.247652,20.174635],[39.801685,20.338862],[39.139399,21.291905],[39.023696,21.986875],[39.066329,22.579656],[38.492772,23.688451],[38.02386,24.078686],[37.483635,24.285495],[37.154818,24.858483],[37.209491,25.084542],[36.931627,25.602959],[36.639604,25.826228],[36.249137,26.570136],[35.640182,27.37652],[35.130187,28.063352],[34.632336,28.058546],[34.787779,28.607427],[34.83222,28.957483],[34.956037,29.356555],[36.068941,29.197495],[36.501214,29.505254],[36.740528,29.865283],[37.503582,30.003776],[37.66812,30.338665],[37.998849,30.5085],[37.002166,31.508413],[39.004886,32.010217],[39.195468,32.161009],[40.399994,31.889992],[41.889981,31.190009],[44.709499,29.178891],[46.568713,29.099025],[47.459822,29.002519],[47.708851,28.526063],[48.416094,28.552004],[48.807595,27.689628],[49.299554,27.461218],[49.470914,27.109999],[50.152422,26.689663],[50.212935,26.277027],[50.113303,25.943972],[50.239859,25.60805],[50.527387,25.327808],[50.660557,24.999896],[50.810108,24.754743],[51.112415,24.556331],[51.389608,24.627386],[51.579519,24.245497],[51.617708,24.014219],[52.000733,23.001154],[55.006803,22.496948],[55.208341,22.70833],[55.666659,22.000001],[54.999982,19.999994],[52.00001,19.000003],[49.116672,18.616668],[48.183344,18.166669],[47.466695,17.116682],[47.000005,16.949999],[46.749994,17.283338],[46.366659,17.233315],[45.399999,17.333335],[45.216651,17.433329],[44.062613,17.410359],[43.791519,17.319977],[43.380794,17.579987],[43.115798,17.08844],[43.218375,16.66689],[42.779332,16.347891]]]}}, {"type":"Feature","id":"SDN","properties":{"name":"Sudan"},"geometry":{"type":"Polygon","coordinates":[[[33.963393,9.464285],[33.824963,9.484061],[33.842131,9.981915],[33.721959,10.325262],[33.206938,10.720112],[33.086766,11.441141],[33.206938,12.179338],[32.743419,12.248008],[32.67475,12.024832],[32.073892,11.97333],[32.314235,11.681484],[32.400072,11.080626],[31.850716,10.531271],[31.352862,9.810241],[30.837841,9.707237],[29.996639,10.290927],[29.618957,10.084919],[29.515953,9.793074],[29.000932,9.604232],[28.966597,9.398224],[27.97089,9.398224],[27.833551,9.604232],[27.112521,9.638567],[26.752006,9.466893],[26.477328,9.55273],[25.962307,10.136421],[25.790633,10.411099],[25.069604,10.27376],[24.794926,9.810241],[24.537415,8.917538],[24.194068,8.728696],[23.88698,8.61973],[23.805813,8.666319],[23.459013,8.954286],[23.394779,9.265068],[23.55725,9.681218],[23.554304,10.089255],[22.977544,10.714463],[22.864165,11.142395],[22.87622,11.38461],[22.50869,11.67936],[22.49762,12.26024],[22.28801,12.64605],[21.93681,12.58818],[22.03759,12.95546],[22.29658,13.37232],[22.18329,13.78648],[22.51202,14.09318],[22.30351,14.32682],[22.56795,14.94429],[23.02459,15.68072],[23.88689,15.61084],[23.83766,19.58047],[23.85,20],[25,20.00304],[25,22],[29.02,22],[32.9,22],[36.86623,22],[37.18872,21.01885],[36.96941,20.83744],[37.1147,19.80796],[37.48179,18.61409],[37.86276,18.36786],[38.41009,17.998307],[37.904,17.42754],[37.16747,17.26314],[36.85253,16.95655],[36.75389,16.29186],[36.32322,14.82249],[36.42951,14.42211],[36.27022,13.56333],[35.86363,12.57828],[35.26049,12.08286],[34.83163,11.31896],[34.73115,10.91017],[34.25745,10.63009],[33.96162,9.58358],[33.963393,9.464285]]]}}, {"type":"Feature","id":"SSD","properties":{"name":"South Sudan"},"geometry":{"type":"Polygon","coordinates":[[[33.963393,9.464285],[33.97498,8.68456],[33.8255,8.37916],[33.2948,8.35458],[32.95418,7.78497],[33.56829,7.71334],[34.0751,7.22595],[34.25032,6.82607],[34.70702,6.59422],[35.298007,5.506],[34.620196,4.847123],[34.005,4.249885],[33.39,3.79],[32.68642,3.79232],[31.88145,3.55827],[31.24556,3.7819],[30.83385,3.50917],[29.95349,4.1737],[29.715995,4.600805],[29.159078,4.389267],[28.696678,4.455077],[28.428994,4.287155],[27.979977,4.408413],[27.374226,5.233944],[27.213409,5.550953],[26.465909,5.946717],[26.213418,6.546603],[25.796648,6.979316],[25.124131,7.500085],[25.114932,7.825104],[24.567369,8.229188],[23.88698,8.61973],[24.194068,8.728696],[24.537415,8.917538],[24.794926,9.810241],[25.069604,10.27376],[25.790633,10.411099],[25.962307,10.136421],[26.477328,9.55273],[26.752006,9.466893],[27.112521,9.638567],[27.833551,9.604232],[27.97089,9.398224],[28.966597,9.398224],[29.000932,9.604232],[29.515953,9.793074],[29.618957,10.084919],[29.996639,10.290927],[30.837841,9.707237],[31.352862,9.810241],[31.850716,10.531271],[32.400072,11.080626],[32.314235,11.681484],[32.073892,11.97333],[32.67475,12.024832],[32.743419,12.248008],[33.206938,12.179338],[33.086766,11.441141],[33.206938,10.720112],[33.721959,10.325262],[33.842131,9.981915],[33.824963,9.484061],[33.963393,9.464285]]]}}, {"type":"Feature","id":"SEN","properties":{"name":"Senegal"},"geometry":{"type":"Polygon","coordinates":[[[-16.713729,13.594959],[-17.126107,14.373516],[-17.625043,14.729541],[-17.185173,14.919477],[-16.700706,15.621527],[-16.463098,16.135036],[-16.12069,16.455663],[-15.623666,16.369337],[-15.135737,16.587282],[-14.577348,16.598264],[-14.099521,16.304302],[-13.435738,16.039383],[-12.830658,15.303692],[-12.17075,14.616834],[-12.124887,13.994727],[-11.927716,13.422075],[-11.553398,13.141214],[-11.467899,12.754519],[-11.513943,12.442988],[-11.658301,12.386583],[-12.203565,12.465648],[-12.278599,12.35444],[-12.499051,12.33209],[-13.217818,12.575874],[-13.700476,12.586183],[-15.548477,12.62817],[-15.816574,12.515567],[-16.147717,12.547762],[-16.677452,12.384852],[-16.841525,13.151394],[-15.931296,13.130284],[-15.691001,13.270353],[-15.511813,13.27857],[-15.141163,13.509512],[-14.712197,13.298207],[-14.277702,13.280585],[-13.844963,13.505042],[-14.046992,13.794068],[-14.376714,13.62568],[-14.687031,13.630357],[-15.081735,13.876492],[-15.39877,13.860369],[-15.624596,13.623587],[-16.713729,13.594959]]]}}, {"type":"Feature","id":"SLB","properties":{"name":"Solomon Islands"},"geometry":{"type":"MultiPolygon","coordinates":[[[[162.119025,-10.482719],[162.398646,-10.826367],[161.700032,-10.820011],[161.319797,-10.204751],[161.917383,-10.446701],[162.119025,-10.482719]]],[[[160.852229,-9.872937],[160.462588,-9.89521],[159.849447,-9.794027],[159.640003,-9.63998],[159.702945,-9.24295],[160.362956,-9.400304],[160.688518,-9.610162],[160.852229,-9.872937]]],[[[161.679982,-9.599982],[161.529397,-9.784312],[160.788253,-8.917543],[160.579997,-8.320009],[160.920028,-8.320009],[161.280006,-9.120011],[161.679982,-9.599982]]],[[[159.875027,-8.33732],[159.917402,-8.53829],[159.133677,-8.114181],[158.586114,-7.754824],[158.21115,-7.421872],[158.359978,-7.320018],[158.820001,-7.560003],[159.640003,-8.020027],[159.875027,-8.33732]]],[[[157.538426,-7.34782],[157.33942,-7.404767],[156.90203,-7.176874],[156.491358,-6.765943],[156.542828,-6.599338],[157.14,-7.021638],[157.538426,-7.34782]]]]}}, {"type":"Feature","id":"SLE","properties":{"name":"Sierra Leone"},"geometry":{"type":"Polygon","coordinates":[[[-11.438779,6.785917],[-11.708195,6.860098],[-12.428099,7.262942],[-12.949049,7.798646],[-13.124025,8.163946],[-13.24655,8.903049],[-12.711958,9.342712],[-12.596719,9.620188],[-12.425929,9.835834],[-12.150338,9.858572],[-11.917277,10.046984],[-11.117481,10.045873],[-10.839152,9.688246],[-10.622395,9.26791],[-10.65477,8.977178],[-10.494315,8.715541],[-10.505477,8.348896],[-10.230094,8.406206],[-10.695595,7.939464],[-11.146704,7.396706],[-11.199802,7.105846],[-11.438779,6.785917]]]}}, {"type":"Feature","id":"SLV","properties":{"name":"El Salvador"},"geometry":{"type":"Polygon","coordinates":[[[-87.793111,13.38448],[-87.904112,13.149017],[-88.483302,13.163951],[-88.843228,13.259734],[-89.256743,13.458533],[-89.812394,13.520622],[-90.095555,13.735338],[-90.064678,13.88197],[-89.721934,14.134228],[-89.534219,14.244816],[-89.587343,14.362586],[-89.353326,14.424133],[-89.058512,14.340029],[-88.843073,14.140507],[-88.541231,13.980155],[-88.503998,13.845486],[-88.065343,13.964626],[-87.859515,13.893312],[-87.723503,13.78505],[-87.793111,13.38448]]]}}, {"type":"Feature","id":"-99","properties":{"name":"Somaliland"},"geometry":{"type":"Polygon","coordinates":[[[48.93813,9.451749],[48.486736,8.837626],[47.78942,8.003],[46.948328,7.996877],[43.67875,9.18358],[43.296975,9.540477],[42.92812,10.02194],[42.55876,10.57258],[42.776852,10.926879],[43.145305,11.46204],[43.47066,11.27771],[43.666668,10.864169],[44.117804,10.445538],[44.614259,10.442205],[45.556941,10.698029],[46.645401,10.816549],[47.525658,11.127228],[48.021596,11.193064],[48.378784,11.375482],[48.948206,11.410622],[48.942005,11.394266],[48.938491,10.982327],[48.938233,9.9735],[48.93813,9.451749]]]}}, {"type":"Feature","id":"SOM","properties":{"name":"Somalia"},"geometry":{"type":"Polygon","coordinates":[[[49.72862,11.5789],[50.25878,11.67957],[50.73202,12.0219],[51.1112,12.02464],[51.13387,11.74815],[51.04153,11.16651],[51.04531,10.6409],[50.83418,10.27972],[50.55239,9.19874],[50.07092,8.08173],[49.4527,6.80466],[48.59455,5.33911],[47.74079,4.2194],[46.56476,2.85529],[45.56399,2.04576],[44.06815,1.05283],[43.13597,0.2922],[42.04157,-0.91916],[41.81095,-1.44647],[41.58513,-1.68325],[40.993,-0.85829],[40.98105,2.78452],[41.855083,3.918912],[42.12861,4.23413],[42.76967,4.25259],[43.66087,4.95755],[44.9636,5.00162],[47.78942,8.003],[48.486736,8.837626],[48.93813,9.451749],[48.938233,9.9735],[48.938491,10.982327],[48.942005,11.394266],[48.948205,11.410617],[49.26776,11.43033],[49.72862,11.5789]]]}}, {"type":"Feature","id":"SRB","properties":{"name":"Republic of Serbia"},"geometry":{"type":"Polygon","coordinates":[[[20.874313,45.416375],[21.483526,45.18117],[21.562023,44.768947],[22.145088,44.478422],[22.459022,44.702517],[22.705726,44.578003],[22.474008,44.409228],[22.65715,44.234923],[22.410446,44.008063],[22.500157,43.642814],[22.986019,43.211161],[22.604801,42.898519],[22.436595,42.580321],[22.545012,42.461362],[22.380526,42.32026],[21.91708,42.30364],[21.576636,42.245224],[21.54332,42.32025],[21.66292,42.43922],[21.77505,42.6827],[21.63302,42.67717],[21.43866,42.86255],[21.27421,42.90959],[21.143395,43.068685],[20.95651,43.13094],[20.81448,43.27205],[20.63508,43.21671],[20.49679,42.88469],[20.25758,42.81275],[20.3398,42.89852],[19.95857,43.10604],[19.63,43.21378],[19.48389,43.35229],[19.21852,43.52384],[19.454,43.5681],[19.59976,44.03847],[19.11761,44.42307],[19.36803,44.863],[19.00548,44.86023],[19.390476,45.236516],[19.072769,45.521511],[18.82982,45.90888],[19.596045,46.17173],[20.220192,46.127469],[20.762175,45.734573],[20.874313,45.416375]]]}}, {"type":"Feature","id":"SUR","properties":{"name":"Suriname"},"geometry":{"type":"Polygon","coordinates":[[[-57.147436,5.97315],[-55.949318,5.772878],[-55.84178,5.953125],[-55.03325,6.025291],[-53.958045,5.756548],[-54.478633,4.896756],[-54.399542,4.212611],[-54.006931,3.620038],[-54.181726,3.18978],[-54.269705,2.732392],[-54.524754,2.311849],[-55.097587,2.523748],[-55.569755,2.421506],[-55.973322,2.510364],[-56.073342,2.220795],[-55.9056,2.021996],[-55.995698,1.817667],[-56.539386,1.899523],[-57.150098,2.768927],[-57.281433,3.333492],[-57.601569,3.334655],[-58.044694,4.060864],[-57.86021,4.576801],[-57.914289,4.812626],[-57.307246,5.073567],[-57.147436,5.97315]]]}}, {"type":"Feature","id":"SVK","properties":{"name":"Slovakia"},"geometry":{"type":"Polygon","coordinates":[[[18.853144,49.49623],[18.909575,49.435846],[19.320713,49.571574],[19.825023,49.217125],[20.415839,49.431453],[20.887955,49.328772],[21.607808,49.470107],[22.558138,49.085738],[22.280842,48.825392],[22.085608,48.422264],[21.872236,48.319971],[20.801294,48.623854],[20.473562,48.56285],[20.239054,48.327567],[19.769471,48.202691],[19.661364,48.266615],[19.174365,48.111379],[18.777025,48.081768],[18.696513,47.880954],[17.857133,47.758429],[17.488473,47.867466],[16.979667,48.123497],[16.879983,48.470013],[16.960288,48.596982],[17.101985,48.816969],[17.545007,48.800019],[17.886485,48.903475],[17.913512,48.996493],[18.104973,49.043983],[18.170498,49.271515],[18.399994,49.315001],[18.554971,49.495015],[18.853144,49.49623]]]}}, {"type":"Feature","id":"SVN","properties":{"name":"Slovenia"},"geometry":{"type":"Polygon","coordinates":[[[13.806475,46.509306],[14.632472,46.431817],[15.137092,46.658703],[16.011664,46.683611],[16.202298,46.852386],[16.370505,46.841327],[16.564808,46.503751],[15.768733,46.238108],[15.67153,45.834154],[15.323954,45.731783],[15.327675,45.452316],[14.935244,45.471695],[14.595109,45.634941],[14.411968,45.466166],[13.71506,45.500324],[13.93763,45.591016],[13.69811,46.016778],[13.806475,46.509306]]]}}, {"type":"Feature","id":"SWE","properties":{"name":"Sweden"},"geometry":{"type":"MultiPolygon","coordinates":[[[[22.183173,65.723741],[21.213517,65.026005],[21.369631,64.413588],[19.778876,63.609554],[17.847779,62.7494],[17.119555,61.341166],[17.831346,60.636583],[18.787722,60.081914],[17.869225,58.953766],[16.829185,58.719827],[16.44771,57.041118],[15.879786,56.104302],[14.666681,56.200885],[14.100721,55.407781],[12.942911,55.361737],[12.625101,56.30708],[11.787942,57.441817],[11.027369,58.856149],[11.468272,59.432393],[12.300366,60.117933],[12.631147,61.293572],[11.992064,61.800362],[11.930569,63.128318],[12.579935,64.066219],[13.571916,64.049114],[13.919905,64.445421],[13.55569,64.787028],[15.108411,66.193867],[16.108712,67.302456],[16.768879,68.013937],[17.729182,68.010552],[17.993868,68.567391],[19.87856,68.407194],[20.025269,69.065139],[20.645593,69.106247],[21.978535,68.616846],[23.539473,67.936009],[23.56588,66.396051],[23.903379,66.006927],[22.183173,65.723741]]],[[[17.061767,57.385783],[17.210083,57.326521],[16.430053,56.179196],[16.364135,56.556455],[17.061767,57.385783]]],[[[19.357910,57.958588],[18.803100,57.651279],[18.825073,57.444949],[18.995361,57.441993],[18.951416,57.370976],[18.693237,57.305756],[18.709716,57.204734],[18.462524,57.127295],[18.319702,56.926992],[18.105468,56.891003],[18.187866,57.109402],[18.072509,57.267163],[18.154907,57.394664],[18.094482,57.545312],[18.660278,57.929434],[19.039306,57.941098],[19.105224,57.993543],[19.374389,57.996454],[19.357910,57.958588]]],[[[20.846557,63.823710],[21.066284,63.829768],[20.972900,63.715670],[20.824584,63.579121],[20.695495,63.591340],[20.819091,63.714454],[20.799865,63.780059],[20.846557,63.823710]]]]}}, {"type":"Feature","id":"SWZ","properties":{"name":"Swaziland"},"geometry":{"type":"Polygon","coordinates":[[[32.071665,-26.73382],[31.86806,-27.177927],[31.282773,-27.285879],[30.685962,-26.743845],[30.676609,-26.398078],[30.949667,-26.022649],[31.04408,-25.731452],[31.333158,-25.660191],[31.837778,-25.843332],[31.985779,-26.29178],[32.071665,-26.73382]]]}}, {"type":"Feature","id":"SYR","properties":{"name":"Syria"},"geometry":{"type":"Polygon","coordinates":[[[38.792341,33.378686],[36.834062,32.312938],[35.719918,32.709192],[35.700798,32.716014],[35.836397,32.868123],[35.821101,33.277426],[36.06646,33.824912],[36.61175,34.201789],[36.448194,34.593935],[35.998403,34.644914],[35.905023,35.410009],[36.149763,35.821535],[36.41755,36.040617],[36.685389,36.259699],[36.739494,36.81752],[37.066761,36.623036],[38.167727,36.90121],[38.699891,36.712927],[39.52258,36.716054],[40.673259,37.091276],[41.212089,37.074352],[42.349591,37.229873],[41.837064,36.605854],[41.289707,36.358815],[41.383965,35.628317],[41.006159,34.419372],[38.792341,33.378686]]]}}, {"type":"Feature","id":"TCD","properties":{"name":"Chad"},"geometry":{"type":"Polygon","coordinates":[[[14.495787,12.859396],[14.595781,13.330427],[13.954477,13.353449],[13.956699,13.996691],[13.540394,14.367134],[13.97217,15.68437],[15.247731,16.627306],[15.300441,17.92795],[15.685741,19.95718],[15.903247,20.387619],[15.487148,20.730415],[15.47106,21.04845],[15.096888,21.308519],[14.8513,22.86295],[15.86085,23.40972],[19.84926,21.49509],[23.83766,19.58047],[23.88689,15.61084],[23.02459,15.68072],[22.56795,14.94429],[22.30351,14.32682],[22.51202,14.09318],[22.18329,13.78648],[22.29658,13.37232],[22.03759,12.95546],[21.93681,12.58818],[22.28801,12.64605],[22.49762,12.26024],[22.50869,11.67936],[22.87622,11.38461],[22.864165,11.142395],[22.231129,10.971889],[21.723822,10.567056],[21.000868,9.475985],[20.059685,9.012706],[19.094008,9.074847],[18.81201,8.982915],[18.911022,8.630895],[18.389555,8.281304],[17.96493,7.890914],[16.705988,7.508328],[16.456185,7.734774],[16.290562,7.754307],[16.106232,7.497088],[15.27946,7.421925],[15.436092,7.692812],[15.120866,8.38215],[14.979996,8.796104],[14.544467,8.965861],[13.954218,9.549495],[14.171466,10.021378],[14.627201,9.920919],[14.909354,9.992129],[15.467873,9.982337],[14.923565,10.891325],[14.960152,11.555574],[14.89336,12.21905],[14.495787,12.859396]]]}}, {"type":"Feature","id":"TGO","properties":{"name":"Togo"},"geometry":{"type":"Polygon","coordinates":[[[1.865241,6.142158],[1.060122,5.928837],[0.836931,6.279979],[0.570384,6.914359],[0.490957,7.411744],[0.712029,8.312465],[0.461192,8.677223],[0.365901,9.465004],[0.36758,10.191213],[-0.049785,10.706918],[0.023803,11.018682],[0.899563,10.997339],[0.772336,10.470808],[1.077795,10.175607],[1.425061,9.825395],[1.463043,9.334624],[1.664478,9.12859],[1.618951,6.832038],[1.865241,6.142158]]]}}, {"type":"Feature","id":"THA","properties":{"name":"Thailand"},"geometry":{"type":"Polygon","coordinates":[[[102.584932,12.186595],[101.687158,12.64574],[100.83181,12.627085],[100.978467,13.412722],[100.097797,13.406856],[100.018733,12.307001],[99.478921,10.846367],[99.153772,9.963061],[99.222399,9.239255],[99.873832,9.207862],[100.279647,8.295153],[100.459274,7.429573],[101.017328,6.856869],[101.623079,6.740622],[102.141187,6.221636],[101.814282,5.810808],[101.154219,5.691384],[101.075516,6.204867],[100.259596,6.642825],[100.085757,6.464489],[99.690691,6.848213],[99.519642,7.343454],[98.988253,7.907993],[98.503786,8.382305],[98.339662,7.794512],[98.150009,8.350007],[98.25915,8.973923],[98.553551,9.93296],[99.038121,10.960546],[99.587286,11.892763],[99.196354,12.804748],[99.212012,13.269294],[99.097755,13.827503],[98.430819,14.622028],[98.192074,15.123703],[98.537376,15.308497],[98.903348,16.177824],[98.493761,16.837836],[97.859123,17.567946],[97.375896,18.445438],[97.797783,18.62708],[98.253724,19.708203],[98.959676,19.752981],[99.543309,20.186598],[100.115988,20.41785],[100.548881,20.109238],[100.606294,19.508344],[101.282015,19.462585],[101.035931,18.408928],[101.059548,17.512497],[102.113592,18.109102],[102.413005,17.932782],[102.998706,17.961695],[103.200192,18.309632],[103.956477,18.240954],[104.716947,17.428859],[104.779321,16.441865],[105.589039,15.570316],[105.544338,14.723934],[105.218777,14.273212],[104.281418,14.416743],[102.988422,14.225721],[102.348099,13.394247],[102.584932,12.186595]]]}}, {"type":"Feature","id":"TJK","properties":{"name":"Tajikistan"},"geometry":{"type":"Polygon","coordinates":[[[71.014198,40.244366],[70.648019,39.935754],[69.55961,40.103211],[69.464887,39.526683],[70.549162,39.604198],[71.784694,39.279463],[73.675379,39.431237],[73.928852,38.505815],[74.257514,38.606507],[74.864816,38.378846],[74.829986,37.990007],[74.980002,37.41999],[73.948696,37.421566],[73.260056,37.495257],[72.63689,37.047558],[72.193041,36.948288],[71.844638,36.738171],[71.448693,37.065645],[71.541918,37.905774],[71.239404,37.953265],[71.348131,38.258905],[70.806821,38.486282],[70.376304,38.138396],[70.270574,37.735165],[70.116578,37.588223],[69.518785,37.608997],[69.196273,37.151144],[68.859446,37.344336],[68.135562,37.023115],[67.83,37.144994],[68.392033,38.157025],[68.176025,38.901553],[67.44222,39.140144],[67.701429,39.580478],[68.536416,39.533453],[69.011633,40.086158],[69.329495,40.727824],[70.666622,40.960213],[70.45816,40.496495],[70.601407,40.218527],[71.014198,40.244366]]]}}, {"type":"Feature","id":"TKM","properties":{"name":"Turkmenistan"},"geometry":{"type":"Polygon","coordinates":[[[61.210817,35.650072],[61.123071,36.491597],[60.377638,36.527383],[59.234762,37.412988],[58.436154,37.522309],[57.330434,38.029229],[56.619366,38.121394],[56.180375,37.935127],[55.511578,37.964117],[54.800304,37.392421],[53.921598,37.198918],[53.735511,37.906136],[53.880929,38.952093],[53.101028,39.290574],[53.357808,39.975286],[52.693973,40.033629],[52.915251,40.876523],[53.858139,40.631034],[54.736845,40.951015],[54.008311,41.551211],[53.721713,42.123191],[52.91675,41.868117],[52.814689,41.135371],[52.50246,41.783316],[52.944293,42.116034],[54.079418,42.324109],[54.755345,42.043971],[55.455251,41.259859],[55.968191,41.308642],[57.096391,41.32231],[56.932215,41.826026],[57.78653,42.170553],[58.629011,42.751551],[59.976422,42.223082],[60.083341,41.425146],[60.465953,41.220327],[61.547179,41.26637],[61.882714,41.084857],[62.37426,40.053886],[63.518015,39.363257],[64.170223,38.892407],[65.215999,38.402695],[66.54615,37.974685],[66.518607,37.362784],[66.217385,37.39379],[65.745631,37.661164],[65.588948,37.305217],[64.746105,37.111818],[64.546479,36.312073],[63.982896,36.007957],[63.193538,35.857166],[62.984662,35.404041],[62.230651,35.270664],[61.210817,35.650072]]]}}, {"type":"Feature","id":"TLS","properties":{"name":"East Timor"},"geometry":{"type":"Polygon","coordinates":[[[124.968682,-8.89279],[125.086246,-8.656887],[125.947072,-8.432095],[126.644704,-8.398247],[126.957243,-8.273345],[127.335928,-8.397317],[126.967992,-8.668256],[125.925885,-9.106007],[125.08852,-9.393173],[125.07002,-9.089987],[124.968682,-8.89279]]]}}, {"type":"Feature","id":"TTO","properties":{"name":"Trinidad and Tobago"},"geometry":{"type":"Polygon","coordinates":[[[-61.68,10.76],[-61.105,10.89],[-60.895,10.855],[-60.935,10.11],[-61.77,10],[-61.95,10.09],[-61.66,10.365],[-61.68,10.76]]]}}, {"type":"Feature","id":"TUN","properties":{"name":"Tunisia"},"geometry":{"type":"Polygon","coordinates":[[[9.48214,30.307556],[9.055603,32.102692],[8.439103,32.506285],[8.430473,32.748337],[7.612642,33.344115],[7.524482,34.097376],[8.140981,34.655146],[8.376368,35.479876],[8.217824,36.433177],[8.420964,36.946427],[9.509994,37.349994],[10.210002,37.230002],[10.18065,36.724038],[11.028867,37.092103],[11.100026,36.899996],[10.600005,36.41],[10.593287,35.947444],[10.939519,35.698984],[10.807847,34.833507],[10.149593,34.330773],[10.339659,33.785742],[10.856836,33.76874],[11.108501,33.293343],[11.488787,33.136996],[11.432253,32.368903],[10.94479,32.081815],[10.636901,31.761421],[9.950225,31.37607],[10.056575,30.961831],[9.970017,30.539325],[9.48214,30.307556]]]}}, {"type":"Feature","id":"TUR","properties":{"name":"Turkey"},"geometry":{"type":"MultiPolygon","coordinates":[[[[36.913127,41.335358],[38.347665,40.948586],[39.512607,41.102763],[40.373433,41.013673],[41.554084,41.535656],[42.619549,41.583173],[43.582746,41.092143],[43.752658,40.740201],[43.656436,40.253564],[44.400009,40.005],[44.79399,39.713003],[44.109225,39.428136],[44.421403,38.281281],[44.225756,37.971584],[44.772699,37.170445],[44.293452,37.001514],[43.942259,37.256228],[42.779126,37.385264],[42.349591,37.229873],[41.212089,37.074352],[40.673259,37.091276],[39.52258,36.716054],[38.699891,36.712927],[38.167727,36.90121],[37.066761,36.623036],[36.739494,36.81752],[36.685389,36.259699],[36.41755,36.040617],[36.149763,35.821535],[35.782085,36.274995],[36.160822,36.650606],[35.550936,36.565443],[34.714553,36.795532],[34.026895,36.21996],[32.509158,36.107564],[31.699595,36.644275],[30.621625,36.677865],[30.391096,36.262981],[29.699976,36.144357],[28.732903,36.676831],[27.641187,36.658822],[27.048768,37.653361],[26.318218,38.208133],[26.8047,38.98576],[26.170785,39.463612],[27.28002,40.420014],[28.819978,40.460011],[29.240004,41.219991],[31.145934,41.087622],[32.347979,41.736264],[33.513283,42.01896],[35.167704,42.040225],[36.913127,41.335358]]],[[[27.192377,40.690566],[26.358009,40.151994],[26.043351,40.617754],[26.056942,40.824123],[26.294602,40.936261],[26.604196,41.562115],[26.117042,41.826905],[27.135739,42.141485],[27.99672,42.007359],[28.115525,41.622886],[28.988443,41.299934],[28.806438,41.054962],[27.619017,40.999823],[27.192377,40.690566]]]]}}, {"type":"Feature","id":"TWN","properties":{"name":"Taiwan"},"geometry":{"type":"Polygon","coordinates":[[[121.777818,24.394274],[121.175632,22.790857],[120.74708,21.970571],[120.220083,22.814861],[120.106189,23.556263],[120.69468,24.538451],[121.495044,25.295459],[121.951244,24.997596],[121.777818,24.394274]]]}}, {"type":"Feature","id":"TZA","properties":{"name":"United Republic of Tanzania"},"geometry":{"type":"Polygon","coordinates":[[[33.903711,-0.95],[34.07262,-1.05982],[37.69869,-3.09699],[37.7669,-3.67712],[39.20222,-4.67677],[38.74054,-5.90895],[38.79977,-6.47566],[39.44,-6.84],[39.47,-7.1],[39.19469,-7.7039],[39.25203,-8.00781],[39.18652,-8.48551],[39.53574,-9.11237],[39.9496,-10.0984],[40.31659,-10.3171],[39.521,-10.89688],[38.427557,-11.285202],[37.82764,-11.26879],[37.47129,-11.56876],[36.775151,-11.594537],[36.514082,-11.720938],[35.312398,-11.439146],[34.559989,-11.52002],[34.28,-10.16],[33.940838,-9.693674],[33.73972,-9.41715],[32.759375,-9.230599],[32.191865,-8.930359],[31.556348,-8.762049],[31.157751,-8.594579],[30.74,-8.34],[30.2,-7.08],[29.62,-6.52],[29.419993,-5.939999],[29.519987,-5.419979],[29.339998,-4.499983],[29.753512,-4.452389],[30.11632,-4.09012],[30.50554,-3.56858],[30.75224,-3.35931],[30.74301,-3.03431],[30.52766,-2.80762],[30.46967,-2.41383],[30.758309,-2.28725],[30.816135,-1.698914],[30.419105,-1.134659],[30.76986,-1.01455],[31.86617,-1.02736],[33.903711,-0.95]]]}}, {"type":"Feature","id":"UGA","properties":{"name":"Uganda"},"geometry":{"type":"Polygon","coordinates":[[[31.86617,-1.02736],[30.76986,-1.01455],[30.419105,-1.134659],[29.821519,-1.443322],[29.579466,-1.341313],[29.587838,-0.587406],[29.8195,-0.2053],[29.875779,0.59738],[30.086154,1.062313],[30.468508,1.583805],[30.85267,1.849396],[31.174149,2.204465],[30.77332,2.33989],[30.83385,3.50917],[31.24556,3.7819],[31.88145,3.55827],[32.68642,3.79232],[33.39,3.79],[34.005,4.249885],[34.47913,3.5556],[34.59607,3.05374],[35.03599,1.90584],[34.6721,1.17694],[34.18,0.515],[33.893569,0.109814],[33.903711,-0.95],[31.86617,-1.02736]]]}}, {"type":"Feature","id":"UKR","properties":{"name":"Ukraine"},"geometry":{"type":"Polygon","coordinates":[[[31.785998,52.101678],[32.159412,52.061267],[32.412058,52.288695],[32.715761,52.238465],[33.7527,52.335075],[34.391731,51.768882],[34.141978,51.566413],[34.224816,51.255993],[35.022183,51.207572],[35.377924,50.773955],[35.356116,50.577197],[36.626168,50.225591],[37.39346,50.383953],[38.010631,49.915662],[38.594988,49.926462],[40.069058,49.601055],[40.080789,49.30743],[39.674664,48.783818],[39.895632,48.232405],[39.738278,47.898937],[38.770585,47.825608],[38.255112,47.5464],[38.223538,47.10219],[37.425137,47.022221],[36.759855,46.6987],[35.823685,46.645964],[34.962342,46.273197],[35.020788,45.651219],[35.510009,45.409993],[36.529998,45.46999],[36.334713,45.113216],[35.239999,44.939996],[33.882511,44.361479],[33.326421,44.564877],[33.546924,45.034771],[32.454174,45.327466],[32.630804,45.519186],[33.588162,45.851569],[33.298567,46.080598],[31.74414,46.333348],[31.675307,46.706245],[30.748749,46.5831],[30.377609,46.03241],[29.603289,45.293308],[29.149725,45.464925],[28.679779,45.304031],[28.233554,45.488283],[28.485269,45.596907],[28.659987,45.939987],[28.933717,46.25883],[28.862972,46.437889],[29.072107,46.517678],[29.170654,46.379262],[29.759972,46.349988],[30.024659,46.423937],[29.83821,46.525326],[29.908852,46.674361],[29.559674,46.928583],[29.415135,47.346645],[29.050868,47.510227],[29.122698,47.849095],[28.670891,48.118149],[28.259547,48.155562],[27.522537,48.467119],[26.857824,48.368211],[26.619337,48.220726],[26.19745,48.220881],[25.945941,47.987149],[25.207743,47.891056],[24.866317,47.737526],[24.402056,47.981878],[23.760958,47.985598],[23.142236,48.096341],[22.710531,47.882194],[22.64082,48.15024],[22.085608,48.422264],[22.280842,48.825392],[22.558138,49.085738],[22.776419,49.027395],[22.51845,49.476774],[23.426508,50.308506],[23.922757,50.424881],[24.029986,50.705407],[23.527071,51.578454],[24.005078,51.617444],[24.553106,51.888461],[25.327788,51.910656],[26.337959,51.832289],[27.454066,51.592303],[28.241615,51.572227],[28.617613,51.427714],[28.992835,51.602044],[29.254938,51.368234],[30.157364,51.416138],[30.555117,51.319503],[30.619454,51.822806],[30.927549,52.042353],[31.785998,52.101678]]]}}, {"type":"Feature","id":"URY","properties":{"name":"Uruguay"},"geometry":{"type":"Polygon","coordinates":[[[-57.625133,-30.216295],[-56.976026,-30.109686],[-55.973245,-30.883076],[-55.60151,-30.853879],[-54.572452,-31.494511],[-53.787952,-32.047243],[-53.209589,-32.727666],[-53.650544,-33.202004],[-53.373662,-33.768378],[-53.806426,-34.396815],[-54.935866,-34.952647],[-55.67409,-34.752659],[-56.215297,-34.859836],[-57.139685,-34.430456],[-57.817861,-34.462547],[-58.427074,-33.909454],[-58.349611,-33.263189],[-58.132648,-33.040567],[-58.14244,-32.044504],[-57.874937,-31.016556],[-57.625133,-30.216295]]]}}, {"type":"Feature","id":"USA","properties":{"name":"United States of America"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-155.54211,19.08348],[-155.68817,18.91619],[-155.93665,19.05939],[-155.90806,19.33888],[-156.07347,19.70294],[-156.02368,19.81422],[-155.85008,19.97729],[-155.91907,20.17395],[-155.86108,20.26721],[-155.78505,20.2487],[-155.40214,20.07975],[-155.22452,19.99302],[-155.06226,19.8591],[-154.80741,19.50871],[-154.83147,19.45328],[-155.22217,19.23972],[-155.54211,19.08348]]],[[[-156.07926,20.64397],[-156.41445,20.57241],[-156.58673,20.783],[-156.70167,20.8643],[-156.71055,20.92676],[-156.61258,21.01249],[-156.25711,20.91745],[-155.99566,20.76404],[-156.07926,20.64397]]],[[[-156.75824,21.17684],[-156.78933,21.06873],[-157.32521,21.09777],[-157.25027,21.21958],[-156.75824,21.17684]]],[[[-157.65283,21.32217],[-157.70703,21.26442],[-157.7786,21.27729],[-158.12667,21.31244],[-158.2538,21.53919],[-158.29265,21.57912],[-158.0252,21.71696],[-157.94161,21.65272],[-157.65283,21.32217]]],[[[-159.34512,21.982],[-159.46372,21.88299],[-159.80051,22.06533],[-159.74877,22.1382],[-159.5962,22.23618],[-159.36569,22.21494],[-159.34512,21.982]]],[[[-94.81758,49.38905],[-94.64,48.84],[-94.32914,48.67074],[-93.63087,48.60926],[-92.61,48.45],[-91.64,48.14],[-90.83,48.27],[-89.6,48.01],[-89.272917,48.019808],[-88.378114,48.302918],[-87.439793,47.94],[-86.461991,47.553338],[-85.652363,47.220219],[-84.87608,46.900083],[-84.779238,46.637102],[-84.543749,46.538684],[-84.6049,46.4396],[-84.3367,46.40877],[-84.14212,46.512226],[-84.091851,46.275419],[-83.890765,46.116927],[-83.616131,46.116927],[-83.469551,45.994686],[-83.592851,45.816894],[-82.550925,45.347517],[-82.337763,44.44],[-82.137642,43.571088],[-82.43,42.98],[-82.9,42.43],[-83.12,42.08],[-83.142,41.975681],[-83.02981,41.832796],[-82.690089,41.675105],[-82.439278,41.675105],[-81.277747,42.209026],[-80.247448,42.3662],[-78.939362,42.863611],[-78.92,42.965],[-79.01,43.27],[-79.171674,43.466339],[-78.72028,43.625089],[-77.737885,43.629056],[-76.820034,43.628784],[-76.5,44.018459],[-76.375,44.09631],[-75.31821,44.81645],[-74.867,45.00048],[-73.34783,45.00738],[-71.50506,45.0082],[-71.405,45.255],[-71.08482,45.30524],[-70.66,45.46],[-70.305,45.915],[-69.99997,46.69307],[-69.237216,47.447781],[-68.905,47.185],[-68.23444,47.35486],[-67.79046,47.06636],[-67.79134,45.70281],[-67.13741,45.13753],[-66.96466,44.8097],[-68.03252,44.3252],[-69.06,43.98],[-70.11617,43.68405],[-70.645476,43.090238],[-70.81489,42.8653],[-70.825,42.335],[-70.495,41.805],[-70.08,41.78],[-70.185,42.145],[-69.88497,41.92283],[-69.96503,41.63717],[-70.64,41.475],[-71.12039,41.49445],[-71.86,41.32],[-72.295,41.27],[-72.87643,41.22065],[-73.71,40.931102],[-72.24126,41.11948],[-71.945,40.93],[-73.345,40.63],[-73.982,40.628],[-73.952325,40.75075],[-74.25671,40.47351],[-73.96244,40.42763],[-74.17838,39.70926],[-74.90604,38.93954],[-74.98041,39.1964],[-75.20002,39.24845],[-75.52805,39.4985],[-75.32,38.96],[-75.071835,38.782032],[-75.05673,38.40412],[-75.37747,38.01551],[-75.94023,37.21689],[-76.03127,37.2566],[-75.72205,37.93705],[-76.23287,38.319215],[-76.35,39.15],[-76.542725,38.717615],[-76.32933,38.08326],[-76.989998,38.239992],[-76.30162,37.917945],[-76.25874,36.9664],[-75.9718,36.89726],[-75.86804,36.55125],[-75.72749,35.55074],[-76.36318,34.80854],[-77.397635,34.51201],[-78.05496,33.92547],[-78.55435,33.86133],[-79.06067,33.49395],[-79.20357,33.15839],[-80.301325,32.509355],[-80.86498,32.0333],[-81.33629,31.44049],[-81.49042,30.72999],[-81.31371,30.03552],[-80.98,29.18],[-80.535585,28.47213],[-80.53,28.04],[-80.056539,26.88],[-80.088015,26.205765],[-80.13156,25.816775],[-80.38103,25.20616],[-80.68,25.08],[-81.17213,25.20126],[-81.33,25.64],[-81.71,25.87],[-82.24,26.73],[-82.70515,27.49504],[-82.85526,27.88624],[-82.65,28.55],[-82.93,29.1],[-83.70959,29.93656],[-84.1,30.09],[-85.10882,29.63615],[-85.28784,29.68612],[-85.7731,30.15261],[-86.4,30.4],[-87.53036,30.27433],[-88.41782,30.3849],[-89.18049,30.31598],[-89.593831,30.159994],[-89.413735,29.89419],[-89.43,29.48864],[-89.21767,29.29108],[-89.40823,29.15961],[-89.77928,29.30714],[-90.15463,29.11743],[-90.880225,29.148535],[-91.626785,29.677],[-92.49906,29.5523],[-93.22637,29.78375],[-93.84842,29.71363],[-94.69,29.48],[-95.60026,28.73863],[-96.59404,28.30748],[-97.14,27.83],[-97.37,27.38],[-97.38,26.69],[-97.33,26.21],[-97.14,25.87],[-97.53,25.84],[-98.24,26.06],[-99.02,26.37],[-99.3,26.84],[-99.52,27.54],[-100.11,28.11],[-100.45584,28.69612],[-100.9576,29.38071],[-101.6624,29.7793],[-102.48,29.76],[-103.11,28.97],[-103.94,29.27],[-104.45697,29.57196],[-104.70575,30.12173],[-105.03737,30.64402],[-105.63159,31.08383],[-106.1429,31.39995],[-106.50759,31.75452],[-108.24,31.754854],[-108.24194,31.34222],[-109.035,31.34194],[-111.02361,31.33472],[-113.30498,32.03914],[-114.815,32.52528],[-114.72139,32.72083],[-115.99135,32.61239],[-117.12776,32.53534],[-117.295938,33.046225],[-117.944,33.621236],[-118.410602,33.740909],[-118.519895,34.027782],[-119.081,34.078],[-119.438841,34.348477],[-120.36778,34.44711],[-120.62286,34.60855],[-120.74433,35.15686],[-121.71457,36.16153],[-122.54747,37.55176],[-122.51201,37.78339],[-122.95319,38.11371],[-123.7272,38.95166],[-123.86517,39.76699],[-124.39807,40.3132],[-124.17886,41.14202],[-124.2137,41.99964],[-124.53284,42.76599],[-124.14214,43.70838],[-124.020535,44.615895],[-123.89893,45.52341],[-124.079635,46.86475],[-124.39567,47.72017],[-124.68721,48.184433],[-124.566101,48.379715],[-123.12,48.04],[-122.58736,47.096],[-122.34,47.36],[-122.5,48.18],[-122.84,49],[-120,49],[-117.03121,49],[-116.04818,49],[-113,49],[-110.05,49],[-107.05,49],[-104.04826,48.99986],[-100.65,49],[-97.22872,49.0007],[-95.15907,49],[-95.15609,49.38425],[-94.81758,49.38905]]],[[[-153.006314,57.115842],[-154.00509,56.734677],[-154.516403,56.992749],[-154.670993,57.461196],[-153.76278,57.816575],[-153.228729,57.968968],[-152.564791,57.901427],[-152.141147,57.591059],[-153.006314,57.115842]]],[[[-165.579164,59.909987],[-166.19277,59.754441],[-166.848337,59.941406],[-167.455277,60.213069],[-166.467792,60.38417],[-165.67443,60.293607],[-165.579164,59.909987]]],[[[-171.731657,63.782515],[-171.114434,63.592191],[-170.491112,63.694975],[-169.682505,63.431116],[-168.689439,63.297506],[-168.771941,63.188598],[-169.52944,62.976931],[-170.290556,63.194438],[-170.671386,63.375822],[-171.553063,63.317789],[-171.791111,63.405846],[-171.731657,63.782515]]],[[[-155.06779,71.147776],[-154.344165,70.696409],[-153.900006,70.889989],[-152.210006,70.829992],[-152.270002,70.600006],[-150.739992,70.430017],[-149.720003,70.53001],[-147.613362,70.214035],[-145.68999,70.12001],[-144.920011,69.989992],[-143.589446,70.152514],[-142.07251,69.851938],[-140.985988,69.711998],[-140.992499,66.000029],[-140.99777,60.306397],[-140.012998,60.276838],[-139.039,60.000007],[-138.34089,59.56211],[-137.4525,58.905],[-136.47972,59.46389],[-135.47583,59.78778],[-134.945,59.27056],[-134.27111,58.86111],[-133.355549,58.410285],[-132.73042,57.69289],[-131.70781,56.55212],[-130.00778,55.91583],[-129.979994,55.284998],[-130.53611,54.802753],[-131.085818,55.178906],[-131.967211,55.497776],[-132.250011,56.369996],[-133.539181,57.178887],[-134.078063,58.123068],[-135.038211,58.187715],[-136.628062,58.212209],[-137.800006,58.499995],[-139.867787,59.537762],[-140.825274,59.727517],[-142.574444,60.084447],[-143.958881,59.99918],[-145.925557,60.45861],[-147.114374,60.884656],[-148.224306,60.672989],[-148.018066,59.978329],[-148.570823,59.914173],[-149.727858,59.705658],[-150.608243,59.368211],[-151.716393,59.155821],[-151.859433,59.744984],[-151.409719,60.725803],[-150.346941,61.033588],[-150.621111,61.284425],[-151.895839,60.727198],[-152.57833,60.061657],[-154.019172,59.350279],[-153.287511,58.864728],[-154.232492,58.146374],[-155.307491,57.727795],[-156.308335,57.422774],[-156.556097,56.979985],[-158.117217,56.463608],[-158.433321,55.994154],[-159.603327,55.566686],[-160.28972,55.643581],[-161.223048,55.364735],[-162.237766,55.024187],[-163.069447,54.689737],[-164.785569,54.404173],[-164.942226,54.572225],[-163.84834,55.039431],[-162.870001,55.348043],[-161.804175,55.894986],[-160.563605,56.008055],[-160.07056,56.418055],[-158.684443,57.016675],[-158.461097,57.216921],[-157.72277,57.570001],[-157.550274,58.328326],[-157.041675,58.918885],[-158.194731,58.615802],[-158.517218,58.787781],[-159.058606,58.424186],[-159.711667,58.93139],[-159.981289,58.572549],[-160.355271,59.071123],[-161.355003,58.670838],[-161.968894,58.671665],[-162.054987,59.266925],[-161.874171,59.633621],[-162.518059,59.989724],[-163.818341,59.798056],[-164.662218,60.267484],[-165.346388,60.507496],[-165.350832,61.073895],[-166.121379,61.500019],[-165.734452,62.074997],[-164.919179,62.633076],[-164.562508,63.146378],[-163.753332,63.219449],[-163.067224,63.059459],[-162.260555,63.541936],[-161.53445,63.455817],[-160.772507,63.766108],[-160.958335,64.222799],[-161.518068,64.402788],[-160.777778,64.788604],[-161.391926,64.777235],[-162.45305,64.559445],[-162.757786,64.338605],[-163.546394,64.55916],[-164.96083,64.446945],[-166.425288,64.686672],[-166.845004,65.088896],[-168.11056,65.669997],[-166.705271,66.088318],[-164.47471,66.57666],[-163.652512,66.57666],[-163.788602,66.077207],[-161.677774,66.11612],[-162.489715,66.735565],[-163.719717,67.116395],[-164.430991,67.616338],[-165.390287,68.042772],[-166.764441,68.358877],[-166.204707,68.883031],[-164.430811,68.915535],[-163.168614,69.371115],[-162.930566,69.858062],[-161.908897,70.33333],[-160.934797,70.44769],[-159.039176,70.891642],[-158.119723,70.824721],[-156.580825,71.357764],[-155.06779,71.147776]]]]}}, {"type":"Feature","id":"UZB","properties":{"name":"Uzbekistan"},"geometry":{"type":"Polygon","coordinates":[[[66.518607,37.362784],[66.54615,37.974685],[65.215999,38.402695],[64.170223,38.892407],[63.518015,39.363257],[62.37426,40.053886],[61.882714,41.084857],[61.547179,41.26637],[60.465953,41.220327],[60.083341,41.425146],[59.976422,42.223082],[58.629011,42.751551],[57.78653,42.170553],[56.932215,41.826026],[57.096391,41.32231],[55.968191,41.308642],[55.928917,44.995858],[58.503127,45.586804],[58.689989,45.500014],[60.239972,44.784037],[61.05832,44.405817],[62.0133,43.504477],[63.185787,43.650075],[64.900824,43.728081],[66.098012,42.99766],[66.023392,41.994646],[66.510649,41.987644],[66.714047,41.168444],[67.985856,41.135991],[68.259896,40.662325],[68.632483,40.668681],[69.070027,41.384244],[70.388965,42.081308],[70.962315,42.266154],[71.259248,42.167711],[70.420022,41.519998],[71.157859,41.143587],[71.870115,41.3929],[73.055417,40.866033],[71.774875,40.145844],[71.014198,40.244366],[70.601407,40.218527],[70.45816,40.496495],[70.666622,40.960213],[69.329495,40.727824],[69.011633,40.086158],[68.536416,39.533453],[67.701429,39.580478],[67.44222,39.140144],[68.176025,38.901553],[68.392033,38.157025],[67.83,37.144994],[67.075782,37.356144],[66.518607,37.362784]]]}}, {"type":"Feature","id":"VEN","properties":{"name":"Venezuela"},"geometry":{"type":"Polygon","coordinates":[[[-71.331584,11.776284],[-71.360006,11.539994],[-71.94705,11.423282],[-71.620868,10.96946],[-71.633064,10.446494],[-72.074174,9.865651],[-71.695644,9.072263],[-71.264559,9.137195],[-71.039999,9.859993],[-71.350084,10.211935],[-71.400623,10.968969],[-70.155299,11.375482],[-70.293843,11.846822],[-69.943245,12.162307],[-69.5843,11.459611],[-68.882999,11.443385],[-68.233271,10.885744],[-68.194127,10.554653],[-67.296249,10.545868],[-66.227864,10.648627],[-65.655238,10.200799],[-64.890452,10.077215],[-64.329479,10.389599],[-64.318007,10.641418],[-63.079322,10.701724],[-61.880946,10.715625],[-62.730119,10.420269],[-62.388512,9.948204],[-61.588767,9.873067],[-60.830597,9.38134],[-60.671252,8.580174],[-60.150096,8.602757],[-59.758285,8.367035],[-60.550588,7.779603],[-60.637973,7.415],[-60.295668,7.043911],[-60.543999,6.856584],[-61.159336,6.696077],[-61.139415,6.234297],[-61.410303,5.959068],[-60.733574,5.200277],[-60.601179,4.918098],[-60.966893,4.536468],[-62.08543,4.162124],[-62.804533,4.006965],[-63.093198,3.770571],[-63.888343,4.02053],[-64.628659,4.148481],[-64.816064,4.056445],[-64.368494,3.79721],[-64.408828,3.126786],[-64.269999,2.497006],[-63.422867,2.411068],[-63.368788,2.2009],[-64.083085,1.916369],[-64.199306,1.492855],[-64.611012,1.328731],[-65.354713,1.095282],[-65.548267,0.789254],[-66.325765,0.724452],[-66.876326,1.253361],[-67.181294,2.250638],[-67.447092,2.600281],[-67.809938,2.820655],[-67.303173,3.318454],[-67.337564,3.542342],[-67.621836,3.839482],[-67.823012,4.503937],[-67.744697,5.221129],[-67.521532,5.55687],[-67.34144,6.095468],[-67.695087,6.267318],[-68.265052,6.153268],[-68.985319,6.206805],[-69.38948,6.099861],[-70.093313,6.960376],[-70.674234,7.087785],[-71.960176,6.991615],[-72.198352,7.340431],[-72.444487,7.423785],[-72.479679,7.632506],[-72.360901,8.002638],[-72.439862,8.405275],[-72.660495,8.625288],[-72.78873,9.085027],[-73.304952,9.152],[-73.027604,9.73677],[-72.905286,10.450344],[-72.614658,10.821975],[-72.227575,11.108702],[-71.973922,11.608672],[-71.331584,11.776284]]]}}, {"type":"Feature","id":"VNM","properties":{"name":"Vietnam"},"geometry":{"type":"Polygon","coordinates":[[[108.05018,21.55238],[106.715068,20.696851],[105.881682,19.75205],[105.662006,19.058165],[106.426817,18.004121],[107.361954,16.697457],[108.269495,16.079742],[108.877107,15.276691],[109.33527,13.426028],[109.200136,11.666859],[108.36613,11.008321],[107.220929,10.364484],[106.405113,9.53084],[105.158264,8.59976],[104.795185,9.241038],[105.076202,9.918491],[104.334335,10.486544],[105.199915,10.88931],[106.24967,10.961812],[105.810524,11.567615],[107.491403,12.337206],[107.614548,13.535531],[107.382727,14.202441],[107.564525,15.202173],[107.312706,15.908538],[106.556008,16.604284],[105.925762,17.485315],[105.094598,18.666975],[103.896532,19.265181],[104.183388,19.624668],[104.822574,19.886642],[104.435,20.758733],[103.203861,20.766562],[102.754896,21.675137],[102.170436,22.464753],[102.706992,22.708795],[103.504515,22.703757],[104.476858,22.81915],[105.329209,23.352063],[105.811247,22.976892],[106.725403,22.794268],[106.567273,22.218205],[107.04342,21.811899],[108.05018,21.55238]]]}}, {"type":"Feature","id":"VUT","properties":{"name":"Vanuatu"},"geometry":{"type":"MultiPolygon","coordinates":[[[[167.844877,-16.466333],[167.515181,-16.59785],[167.180008,-16.159995],[167.216801,-15.891846],[167.844877,-16.466333]]],[[[167.107712,-14.93392],[167.270028,-15.740021],[167.001207,-15.614602],[166.793158,-15.668811],[166.649859,-15.392704],[166.629137,-14.626497],[167.107712,-14.93392]]]]}}, {"type":"Feature","id":"PSE","properties":{"name":"West Bank"},"geometry":{"type":"Polygon","coordinates":[[[35.545665,32.393992],[35.545252,31.782505],[35.397561,31.489086],[34.927408,31.353435],[34.970507,31.616778],[35.225892,31.754341],[34.974641,31.866582],[35.18393,32.532511],[35.545665,32.393992]]]}}, {"type":"Feature","id":"YEM","properties":{"name":"Yemen"},"geometry":{"type":"Polygon","coordinates":[[[53.108573,16.651051],[52.385206,16.382411],[52.191729,15.938433],[52.168165,15.59742],[51.172515,15.17525],[49.574576,14.708767],[48.679231,14.003202],[48.238947,13.94809],[47.938914,14.007233],[47.354454,13.59222],[46.717076,13.399699],[45.877593,13.347764],[45.62505,13.290946],[45.406459,13.026905],[45.144356,12.953938],[44.989533,12.699587],[44.494576,12.721653],[44.175113,12.58595],[43.482959,12.6368],[43.222871,13.22095],[43.251448,13.767584],[43.087944,14.06263],[42.892245,14.802249],[42.604873,15.213335],[42.805015,15.261963],[42.702438,15.718886],[42.823671,15.911742],[42.779332,16.347891],[43.218375,16.66689],[43.115798,17.08844],[43.380794,17.579987],[43.791519,17.319977],[44.062613,17.410359],[45.216651,17.433329],[45.399999,17.333335],[46.366659,17.233315],[46.749994,17.283338],[47.000005,16.949999],[47.466695,17.116682],[48.183344,18.166669],[49.116672,18.616668],[52.00001,19.000003],[52.782184,17.349742],[53.108573,16.651051]]]}}, {"type":"Feature","id":"ZAF","properties":{"name":"South Africa"},"geometry":{"type":"Polygon","coordinates":[[[31.521001,-29.257387],[31.325561,-29.401978],[30.901763,-29.909957],[30.622813,-30.423776],[30.055716,-31.140269],[28.925553,-32.172041],[28.219756,-32.771953],[27.464608,-33.226964],[26.419452,-33.61495],[25.909664,-33.66704],[25.780628,-33.944646],[25.172862,-33.796851],[24.677853,-33.987176],[23.594043,-33.794474],[22.988189,-33.916431],[22.574157,-33.864083],[21.542799,-34.258839],[20.689053,-34.417175],[20.071261,-34.795137],[19.616405,-34.819166],[19.193278,-34.462599],[18.855315,-34.444306],[18.424643,-33.997873],[18.377411,-34.136521],[18.244499,-33.867752],[18.25008,-33.281431],[17.92519,-32.611291],[18.24791,-32.429131],[18.221762,-31.661633],[17.566918,-30.725721],[17.064416,-29.878641],[17.062918,-29.875954],[16.344977,-28.576705],[16.824017,-28.082162],[17.218929,-28.355943],[17.387497,-28.783514],[17.836152,-28.856378],[18.464899,-29.045462],[19.002127,-28.972443],[19.894734,-28.461105],[19.895768,-24.76779],[20.165726,-24.917962],[20.758609,-25.868136],[20.66647,-26.477453],[20.889609,-26.828543],[21.605896,-26.726534],[22.105969,-26.280256],[22.579532,-25.979448],[22.824271,-25.500459],[23.312097,-25.26869],[23.73357,-25.390129],[24.211267,-25.670216],[25.025171,-25.71967],[25.664666,-25.486816],[25.765849,-25.174845],[25.941652,-24.696373],[26.485753,-24.616327],[26.786407,-24.240691],[27.11941,-23.574323],[28.017236,-22.827754],[29.432188,-22.091313],[29.839037,-22.102216],[30.322883,-22.271612],[30.659865,-22.151567],[31.191409,-22.25151],[31.670398,-23.658969],[31.930589,-24.369417],[31.752408,-25.484284],[31.837778,-25.843332],[31.333158,-25.660191],[31.04408,-25.731452],[30.949667,-26.022649],[30.676609,-26.398078],[30.685962,-26.743845],[31.282773,-27.285879],[31.86806,-27.177927],[32.071665,-26.73382],[32.83012,-26.742192],[32.580265,-27.470158],[32.462133,-28.301011],[32.203389,-28.752405],[31.521001,-29.257387]],[[28.978263,-28.955597],[28.5417,-28.647502],[28.074338,-28.851469],[27.532511,-29.242711],[26.999262,-29.875954],[27.749397,-30.645106],[28.107205,-30.545732],[28.291069,-30.226217],[28.8484,-30.070051],[29.018415,-29.743766],[29.325166,-29.257387],[28.978263,-28.955597]]]}}, {"type":"Feature","id":"ZMB","properties":{"name":"Zambia"},"geometry":{"type":"Polygon","coordinates":[[[32.759375,-9.230599],[33.231388,-9.676722],[33.485688,-10.525559],[33.31531,-10.79655],[33.114289,-11.607198],[33.306422,-12.435778],[32.991764,-12.783871],[32.688165,-13.712858],[33.214025,-13.97186],[30.179481,-14.796099],[30.274256,-15.507787],[29.516834,-15.644678],[28.947463,-16.043051],[28.825869,-16.389749],[28.467906,-16.4684],[27.598243,-17.290831],[27.044427,-17.938026],[26.706773,-17.961229],[26.381935,-17.846042],[25.264226,-17.73654],[25.084443,-17.661816],[25.07695,-17.578823],[24.682349,-17.353411],[24.033862,-17.295843],[23.215048,-17.523116],[22.562478,-16.898451],[21.887843,-16.08031],[21.933886,-12.898437],[24.016137,-12.911046],[23.930922,-12.565848],[24.079905,-12.191297],[23.904154,-11.722282],[24.017894,-11.237298],[23.912215,-10.926826],[24.257155,-10.951993],[24.314516,-11.262826],[24.78317,-11.238694],[25.418118,-11.330936],[25.75231,-11.784965],[26.553088,-11.92444],[27.16442,-11.608748],[27.388799,-12.132747],[28.155109,-12.272481],[28.523562,-12.698604],[28.934286,-13.248958],[29.699614,-13.257227],[29.616001,-12.178895],[29.341548,-12.360744],[28.642417,-11.971569],[28.372253,-11.793647],[28.49607,-10.789884],[28.673682,-9.605925],[28.449871,-9.164918],[28.734867,-8.526559],[29.002912,-8.407032],[30.346086,-8.238257],[30.740015,-8.340007],[31.157751,-8.594579],[31.556348,-8.762049],[32.191865,-8.930359],[32.759375,-9.230599]]]}}, {"type":"Feature","id":"ZWE","properties":{"name":"Zimbabwe"},"geometry":{"type":"Polygon","coordinates":[[[31.191409,-22.25151],[30.659865,-22.151567],[30.322883,-22.271612],[29.839037,-22.102216],[29.432188,-22.091313],[28.794656,-21.639454],[28.02137,-21.485975],[27.727228,-20.851802],[27.724747,-20.499059],[27.296505,-20.39152],[26.164791,-19.293086],[25.850391,-18.714413],[25.649163,-18.536026],[25.264226,-17.73654],[26.381935,-17.846042],[26.706773,-17.961229],[27.044427,-17.938026],[27.598243,-17.290831],[28.467906,-16.4684],[28.825869,-16.389749],[28.947463,-16.043051],[29.516834,-15.644678],[30.274256,-15.507787],[30.338955,-15.880839],[31.173064,-15.860944],[31.636498,-16.07199],[31.852041,-16.319417],[32.328239,-16.392074],[32.847639,-16.713398],[32.849861,-17.979057],[32.654886,-18.67209],[32.611994,-19.419383],[32.772708,-19.715592],[32.659743,-20.30429],[32.508693,-20.395292],[32.244988,-21.116489],[31.191409,-22.25151]]]}} ]} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categories common_Series=Series common_Values=Values common_Value=Value common_Locations=Locations common_Rows=Group By common_Columns=Columns common_noData=No data googleDisplayer_resetAnchor=reset googleBubbleDisplayer_XAxis=X Axis googleBubbleDisplayer_YAxis=Y Axis googleBubbleDisplayer_BubbleColor=Bubble color googleBubbleDisplayer_BubbleSize=Bubble size ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants_de.properties ================================================ common_Categories=Kategorien common_Series=Serie common_Values=Werte common_Value=Wert common_Locations=Speicherorte common_Columns=Spalten common_noData=Keine Daten googleDisplayer_resetAnchor=zurücksetzen googleBubbleDisplayer_XAxis=X-Achse googleBubbleDisplayer_YAxis=Y-Achse googleBubbleDisplayer_BubbleColor=Blasen-Farbe googleBubbleDisplayer_BubbleSize=Blasen-Größe ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categorías common_Series=Serie common_Values=Valores common_Value=Valor common_Locations=Ubicaciones common_Rows=Agrupar por common_Columns=Columnas common_noData=No hay datos googleDisplayer_resetAnchor=restablecer googleBubbleDisplayer_XAxis=Eje X googleBubbleDisplayer_YAxis=Eje Y googleBubbleDisplayer_BubbleColor=Color de la burbuja googleBubbleDisplayer_BubbleSize=Tamaño de la burbuja ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Catégories common_Series=Séries common_Values=Valeurs common_Value=Valeur common_Locations=Sites common_Rows=Grouper par common_Columns=Colonnes common_noData=Aucune donnée googleDisplayer_resetAnchor=réinitialiser googleBubbleDisplayer_XAxis=Axe X googleBubbleDisplayer_YAxis=Axe Y googleBubbleDisplayer_BubbleColor=Couleur de la bulle googleBubbleDisplayer_BubbleSize=Taille de la bulle ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categorie common_Series=Serie common_Values=Valori common_Value=Valore common_Locations=Posizioni common_Rows=Raggruppa per common_Columns=Colonne common_noData=Nessun dato googleDisplayer_resetAnchor=reset googleBubbleDisplayer_XAxis=Asse X googleBubbleDisplayer_YAxis=Asse Y googleBubbleDisplayer_BubbleColor=Colore bolle googleBubbleDisplayer_BubbleSize=Dimensione bolle ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=カテゴリ common_Series=シリーズ common_Values=値 common_Value=値 common_Locations=場所 common_Rows=グループ化 common_Columns=カラム common_noData=データなし googleDisplayer_resetAnchor=リセット googleBubbleDisplayer_XAxis=X 軸 googleBubbleDisplayer_YAxis=Y 軸 googleBubbleDisplayer_BubbleColor=バブル色 googleBubbleDisplayer_BubbleSize=バブルサイズ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants_pt_BR.properties ================================================ common_Categories=Categorias common_Series=Séries common_Values=Valores common_Value=Valor common_Locations=Locais common_Columns=Colunas common_noData=Não há dados googleDisplayer_resetAnchor=reiniciar googleBubbleDisplayer_XAxis=X Axis googleBubbleDisplayer_YAxis=Y Axis googleBubbleDisplayer_BubbleColor=Cor do Bubble googleBubbleDisplayer_BubbleSize=Tamanho do Bubble ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/main/resources/org/dashbuilder/renderer/c3/client/resources/i18n/C3DisplayerConstants_zh_CN.properties ================================================ common_Categories=类别 common_Series=序列 common_Values=值 common_Value=值 common_Locations=位置 common_Columns=列 common_noData=没有数据 googleDisplayer_resetAnchor=重置 googleBubbleDisplayer_XAxis=X 轴 googleBubbleDisplayer_YAxis=Y 轴 googleBubbleDisplayer_BubbleColor=Bubble 颜色 googleBubbleDisplayer_BubbleSize=Bubble 大小 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/C3BaseTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.renderer.c3.client.charts.area.C3AreaChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.line.C3LineChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.map.D3MapDisplayer; import org.dashbuilder.renderer.c3.client.charts.map.geojson.CountriesGeoJsonService; import org.dashbuilder.renderer.c3.client.charts.meter.C3MeterChartDisplayer; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisInfo; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisX; import org.dashbuilder.renderer.c3.client.jsbinding.C3AxisY; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartData; import org.dashbuilder.renderer.c3.client.jsbinding.C3JsTypesFactory; import org.dashbuilder.renderer.c3.client.jsbinding.C3Tick; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.Silent.class) public class C3BaseTest extends AbstractDisplayerTest { @Mock C3JsTypesFactory c3Factory; @Mock protected C3AxisInfo c3AxisInfo; @Mock protected C3AxisY c3AxisY; @Mock protected C3AxisX c3AxisX; @Mock protected C3Tick c3Tick; @Mock protected C3ChartConf c3Conf; @Mock protected C3ChartData c3ChartData; @Mock FilterLabelSet filterLabelSet; @Mock C3LineChartDisplayer.View c3LineChartview; @Mock C3AreaChartDisplayer.View c3AreaChartview; @Mock C3MeterChartDisplayer.View c3Meterview; @Mock D3MapDisplayer.View d3MapDisplayerView; @Mock CountriesGeoJsonService geoService; public C3LineChartDisplayer c3LineChartDisplayer(DisplayerSettings settings) { c3Factory = mockC3JsTypesFactory(); return initDisplayer(new C3LineChartDisplayer(c3LineChartview, filterLabelSet, c3Factory), settings); } public C3AreaChartDisplayer c3AreaChartDisplayer(DisplayerSettings settings) { c3Factory = mockC3JsTypesFactory(); return initDisplayer(new C3AreaChartDisplayer(c3AreaChartview, filterLabelSet, c3Factory), settings); } public C3MeterChartDisplayer c3MeterChartDisplayer(DisplayerSettings settings) { c3Factory = mockC3JsTypesFactory(); return initDisplayer(new C3MeterChartDisplayer(c3Meterview, filterLabelSet, c3Factory), settings); } public D3MapDisplayer d3MapDisplayer(DisplayerSettings settings) { return initDisplayer(new D3MapDisplayer(filterLabelSet, d3MapDisplayerView, geoService), settings); } private C3JsTypesFactory mockC3JsTypesFactory() { when(c3AxisInfo.getX()).thenReturn(c3AxisX); lenient().when(c3AxisInfo.getY()).thenReturn(c3AxisY); when(c3AxisX.getTick()).thenReturn(c3Tick); when(c3Conf.getAxis()).thenReturn(c3AxisInfo); when(c3Factory.c3ChartData(any(), any(), any(), any(), any())).thenReturn(c3ChartData); when(c3Factory.c3ChartConf(any(), any(), any(), any(), any(), any(), any(), any(), any())).thenReturn(c3Conf); return c3Factory; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/C3DisplayerTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_AMOUNT; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_DATE; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_ID; import static org.dashbuilder.dataset.group.AggregateFunctionType.SUM; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import java.util.List; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.renderer.c3.client.charts.line.C3LineChartDisplayer; import org.dashbuilder.renderer.c3.client.jsbinding.C3ChartConf; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.Silent.class) public class C3DisplayerTest extends C3BaseTest { private static final boolean RECEIVE_NOTIFICATION = true; private static final String LEGEND_POSITION = "right"; private static final int SIZE = 300; private static final String TITLE = "Title"; private static final String BLACK = "black"; DisplayerSettings simpleSettings = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .width(SIZE) .height(SIZE) .title(TITLE) .backgroundColor(BLACK) .titleVisible(true) .legendOn(LEGEND_POSITION) .filterOn(RECEIVE_NOTIFICATION, RECEIVE_NOTIFICATION, RECEIVE_NOTIFICATION) .buildSettings(); private C3LineChartDisplayer displayer; @Before public void conf() { displayer = c3LineChartDisplayer(simpleSettings); displayer.draw(); } /** * Tests if C3 configuration is built based on settings values */ @Test public void c3ConfigurationTest() { verify(c3Factory).c3ChartSize(SIZE, SIZE); verify(c3Factory).c3AxisInfo(eq(false), any(), any()); verify(c3Factory).c3Legend(true, LEGEND_POSITION); verify(c3Factory).c3Selection(RECEIVE_NOTIFICATION, true, false); } /** * Check if settings are passed to view */ @Test public void viewParametersTest() { C3LineChartDisplayer.View view = displayer.getView(); verify(view).init(any()); verify(view).updateChart(any(C3ChartConf.class)); verify(view).showTitle(TITLE); verify(view).setBackgroundColor(BLACK); } /** * Verify if data is generated correctly */ @Test public void c3DataTest() { DataSet lastDataSet = displayer.getDataSetHandler().getLastDataSet(); List categories = lastDataSet.getColumns().get(0).getValues(); DataColumn seriesColumn = lastDataSet.getColumns().get(1); String[][] createdSeries = displayer.createSeries(); assertArrayEquals(displayer.createCategories(), categories.toArray()); assertEquals(createdSeries[0].length, seriesColumn.getValues().size() + 1); assertEquals(createdSeries[0][0], seriesColumn.getId()); } @Test public void c3NoData() { DisplayerSettings noData = DisplayerSettingsFactory.newLineChartSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .buildSettings(); displayer = c3LineChartDisplayer(noData); displayer.draw(); C3LineChartDisplayer.View view = displayer.getView(); verify(view).noData(); } @Test public void tableDataTest() { String[][] expectedDataTable = { { "2012", "2013", "2014", "2015" }, { "6126.13", "5252.96", "4015.48", "7336.69"} }; displayer.draw(); C3LineChartDisplayer.View view = displayer.getView(); String[][] dataTable = displayer.getDataTable(); assertArrayEquals(expectedDataTable, dataTable); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/C3RendererTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import static org.mockito.Mockito.when; import static org.dashbuilder.displayer.DisplayerSubType.AREA_STACKED; import static org.dashbuilder.displayer.DisplayerSubType.BAR; import static org.dashbuilder.displayer.DisplayerSubType.BAR_STACKED; import static org.dashbuilder.displayer.DisplayerSubType.COLUMN; import static org.dashbuilder.displayer.DisplayerSubType.COLUMN_STACKED; import static org.dashbuilder.displayer.DisplayerSubType.DONUT; import static org.dashbuilder.displayer.DisplayerSubType.LINE; import static org.dashbuilder.displayer.DisplayerSubType.PIE; import static org.dashbuilder.displayer.DisplayerSubType.SMOOTH; import static org.dashbuilder.displayer.DisplayerType.AREACHART; import static org.dashbuilder.displayer.DisplayerType.BARCHART; import static org.dashbuilder.displayer.DisplayerType.BUBBLECHART; import static org.dashbuilder.displayer.DisplayerType.LINECHART; import static org.dashbuilder.displayer.DisplayerType.METERCHART; import static org.dashbuilder.displayer.DisplayerType.PIECHART; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.renderer.c3.client.charts.area.C3AreaChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.bar.C3BarChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.bubble.C3BubbleChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.line.C3LineChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.meter.C3MeterChartDisplayer; import org.dashbuilder.renderer.c3.client.charts.pie.C3PieChartDisplayer; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class C3RendererTest { @Mock SyncBeanManager beanManager; @InjectMocks C3Renderer renderer; @Mock private SyncBeanDef areaChartDisplayerBeanDef; @Mock private SyncBeanDef barChartDisplayerBeanDef; @Mock private SyncBeanDef lineChartDisplayerBeanDef; @Mock private SyncBeanDef pieChartDisplayerBeanDef; @Mock private SyncBeanDef bubbleChartDisplayerBeanDef; @Mock private SyncBeanDef meterChartDisplayerBeanDef; @Mock private C3AreaChartDisplayer c3AreaChartDisplayer; @Mock private C3BarChartDisplayer c3BarChartDisplayer; @Mock private C3LineChartDisplayer c3LineChartDisplayer; @Mock private C3PieChartDisplayer c3PieChartDisplayer; @Mock private C3BubbleChartDisplayer c3BubbleChartDisplayer; @Mock private C3MeterChartDisplayer c3MeterChartDisplayer; private DisplayerSettings settings; @Before public void prepareTypes() { when(beanManager.lookupBean(C3AreaChartDisplayer.class)).thenReturn(areaChartDisplayerBeanDef); when(areaChartDisplayerBeanDef.newInstance()).thenReturn(c3AreaChartDisplayer); when(beanManager.lookupBean(C3BarChartDisplayer.class)).thenReturn(barChartDisplayerBeanDef); when(barChartDisplayerBeanDef.newInstance()).thenReturn(c3BarChartDisplayer); when(beanManager.lookupBean(C3LineChartDisplayer.class)).thenReturn(lineChartDisplayerBeanDef); when(lineChartDisplayerBeanDef.newInstance()).thenReturn(c3LineChartDisplayer); when(beanManager.lookupBean(C3PieChartDisplayer.class)).thenReturn(pieChartDisplayerBeanDef); when(pieChartDisplayerBeanDef.newInstance()).thenReturn(c3PieChartDisplayer); when(beanManager.lookupBean(C3BubbleChartDisplayer.class)).thenReturn(bubbleChartDisplayerBeanDef); when(bubbleChartDisplayerBeanDef.newInstance()).thenReturn(c3BubbleChartDisplayer); when(beanManager.lookupBean(C3MeterChartDisplayer.class)).thenReturn(meterChartDisplayerBeanDef); when(meterChartDisplayerBeanDef.newInstance()).thenReturn(c3MeterChartDisplayer); settings = mock(DisplayerSettings.class); } @Test public void lookupAreaChartTest() { when(settings.getType()).thenReturn(AREACHART); when(settings.getSubtype()).thenReturn(AREA_STACKED); renderer.lookupDisplayer(settings); verify(c3AreaChartDisplayer).stacked(); } @Test public void lookupBarChartColumnStacked() { when(settings.getType()).thenReturn(BARCHART); when(settings.getSubtype()).thenReturn(COLUMN_STACKED); renderer.lookupDisplayer(settings); verify(c3BarChartDisplayer).stacked(); } @Test public void lookuBarChartColumn() { when(settings.getType()).thenReturn(BARCHART); when(settings.getSubtype()).thenReturn(COLUMN); renderer.lookupDisplayer(settings); verify(c3BarChartDisplayer).notRotated(); } @Test public void lookupBarChartStacked() { when(settings.getType()).thenReturn(BARCHART); when(settings.getSubtype()).thenReturn(BAR_STACKED); renderer.lookupDisplayer(settings); verify(c3BarChartDisplayer).stackedAndRotated(); } @Test public void lookupBarChartBar() { when(settings.getType()).thenReturn(BARCHART); when(settings.getSubtype()).thenReturn(BAR); renderer.lookupDisplayer(settings); verify(c3BarChartDisplayer).rotated(); } @Test public void lookupLineChart() { when(settings.getType()).thenReturn(LINECHART); when(settings.getSubtype()).thenReturn(LINE); renderer.lookupDisplayer(settings); verify(c3LineChartDisplayer, times(0)).smooth(); } @Test public void lookupLineChartSmooth() { when(settings.getType()).thenReturn(LINECHART); when(settings.getSubtype()).thenReturn(SMOOTH); renderer.lookupDisplayer(settings); verify(c3LineChartDisplayer).smooth(); } @Test public void lookupPieChart() { when(settings.getType()).thenReturn(PIECHART); when(settings.getSubtype()).thenReturn(PIE); renderer.lookupDisplayer(settings); verify(c3PieChartDisplayer, times(0)).donut(); } @Test public void lookupPieChartDonut() { when(settings.getType()).thenReturn(PIECHART); when(settings.getSubtype()).thenReturn(DONUT); renderer.lookupDisplayer(settings); verify(c3PieChartDisplayer).donut(); } @Test public void lookupBubbleChart() { when(settings.getType()).thenReturn(BUBBLECHART); renderer.lookupDisplayer(settings); verify(bubbleChartDisplayerBeanDef).newInstance(); } @Test public void lookupMeterChart() { when(settings.getType()).thenReturn(METERCHART); renderer.lookupDisplayer(settings); verify(meterChartDisplayerBeanDef).newInstance(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/C3ResizableChartTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_AMOUNT; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_DATE; import static org.dashbuilder.dataset.group.AggregateFunctionType.SUM; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.renderer.c3.client.charts.line.C3LineChartDisplayer; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.Silent.class) public class C3ResizableChartTest extends C3BaseTest { private static final int SIZE = 300; private C3LineChartDisplayer displayer; @Test public void c3Resizable() { DisplayerSettings resizableSettings = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .width(SIZE) .height(SIZE) .resizableOn(SIZE, SIZE) .buildSettings(); displayer = c3LineChartDisplayer(resizableSettings); displayer.draw(); C3LineChartDisplayer.View view = displayer.getView(); verify(c3Factory, times(0)).c3ChartSize(300, 300); verify(view).setResizable(SIZE, SIZE); } @Test public void c3NotResizable() { DisplayerSettings notResizableSettings = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .width(SIZE) .height(SIZE) .buildSettings(); displayer = c3LineChartDisplayer(notResizableSettings); displayer.draw(); C3LineChartDisplayer.View view = displayer.getView(); verify(c3Factory).c3ChartSize(300, 300); verify(view, times(0)).setResizable(SIZE, SIZE); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/charts/area/C3AreaChartDisplayerTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.area; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_AMOUNT; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_DATE; import static org.dashbuilder.dataset.group.AggregateFunctionType.SUM; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.any; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.renderer.c3.client.C3BaseTest; import org.dashbuilder.renderer.c3.client.charts.area.C3AreaChartDisplayer.View; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.Silent.class) public class C3AreaChartDisplayerTest extends C3BaseTest { private static final boolean RECEIVE_NOTIFICATION = true; private static final String LEGEND_POSITION = "right"; private static final int SIZE = 300; private static final String TITLE = "Title"; private static final String BLACK = "black"; DisplayerSettings simpleSettings = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .width(SIZE) .height(SIZE) .title(TITLE) .backgroundColor(BLACK) .titleVisible(true) .legendOn(LEGEND_POSITION) .filterOn(RECEIVE_NOTIFICATION, RECEIVE_NOTIFICATION, RECEIVE_NOTIFICATION) .buildSettings(); private C3AreaChartDisplayer displayer; @Before public void conf() { displayer = c3AreaChartDisplayer(simpleSettings); displayer.draw(); } @Test public void fixAreaCallbackRegisteredTest() { verify(c3Conf).setOnrendered(displayer.fixAreaOpacityCallback); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/charts/map/D3MapDisplayerTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_AMOUNT; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_DATE; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_ID; import static org.dashbuilder.dataset.group.AggregateFunctionType.SUM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.text.ParseException; import java.util.Map; import org.dashbuilder.dataset.RawDataSet; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.renderer.c3.client.C3BaseTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.Silent.class) public class D3MapDisplayerTest extends C3BaseTest { private static final String COUNTRY_1= "Country1"; private static final String COUNTRY_2= "Country2"; private static final Integer VAL_1= 1; private static final Integer VAL_2= 2; private static final String CL_TITLE = "Title in Column"; private static final String BG_COLOR = "red"; RawDataSet twoColumnsRawDS = new RawDataSet( new String [] {"cl", "cl2"}, new Class[] {String.class, String.class}, new String[][]{ {COUNTRY_1, VAL_1.toString()}, {COUNTRY_2, VAL_2.toString()} }); private D3MapDisplayer displayer; @Before public void conf() { DisplayerSettings noData = DisplayerSettingsFactory.newLineChartSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM, CL_TITLE) .backgroundColor(BG_COLOR) .buildSettings(); displayer = d3MapDisplayer(noData); displayer.draw(); } @Test public void dataRetrievalTest() throws ParseException { Map data = displayer.retrieveData(twoColumnsRawDS.toDataSet()); Double val1 = data.get(COUNTRY_1); assertNotNull(val1); assertEquals(VAL_1.intValue(), val1.intValue()); } @Test public void mapConfTest() throws ParseException { displayer.updateVisualizationWithData(); D3MapConf conf = displayer.getConf(); assertEquals(CL_TITLE, conf.getTitle()); assertEquals(BG_COLOR, conf.getBackgroundColor()); Mockito.verify(displayer.getView()).createMap(conf); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/charts/map/geojson/impl/CountriesGeoJsonServiceImplTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.map.geojson.impl; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import jsinterop.base.JsPropertyMap; import org.dashbuilder.renderer.c3.client.charts.map.geojson.GeoJsonLoader; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.Feature; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.FeatureCollection; import org.dashbuilder.renderer.c3.client.jsbinding.geojson.Geometry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.client.views.pfly.widgets.D3; import static org.dashbuilder.renderer.c3.client.charts.map.geojson.impl.CountriesGeoJsonServiceImpl.COUNTRY_NAME_PROPERTY; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class CountriesGeoJsonServiceImplTest { private static final String COUNTRY_LOCATION = "2.0, 1.0"; private static final Double[] LONG_LAT = {1.0, 2.0}; private static final String COUNTRY_CODE = "ID"; private static final String COUNTRY_NAME = "Name"; @Mock GeoJsonLoader geoJsonLoader; @Mock JsPropertyMap properties; @Mock Feature feature; @Mock FeatureCollection featureCollection; @Mock Geometry geometry; @Mock D3 d3; @InjectMocks CountriesGeoJsonServiceImpl countriesGeoJsonServiceImpl; @Before public void setup() { when(properties.get(COUNTRY_NAME_PROPERTY)).thenReturn(COUNTRY_NAME); when(feature.getProperties()).thenReturn(properties); when(feature.getId()).thenReturn(COUNTRY_CODE); when(featureCollection.getFeatures()).thenReturn(new Feature[]{feature}); } @Test public void getCountryNameTest() { String countryName = countriesGeoJsonServiceImpl.getCountryName(feature); assertEquals(COUNTRY_NAME, countryName); countryName = countriesGeoJsonServiceImpl.getCountryName(null); assertTrue(countryName.isEmpty()); } @Test public void getCountryNameByCodeTest() { String countryName = countriesGeoJsonServiceImpl.getCountryNameByCode(COUNTRY_CODE); assertEquals(COUNTRY_NAME, countryName); countryName = countriesGeoJsonServiceImpl.getCountryNameByCode("123"); assertTrue(countryName.isEmpty()); countryName = countriesGeoJsonServiceImpl.getCountryNameByCode(null); assertTrue(countryName.isEmpty()); } @Test public void countryByIdOrNameTest() { Optional countryByIdOrName = countriesGeoJsonServiceImpl.countryByIdOrName(COUNTRY_CODE); assertTrue(countryByIdOrName.isPresent()); assertEquals(feature, countryByIdOrName.get()); countryByIdOrName = countriesGeoJsonServiceImpl.countryByIdOrName(COUNTRY_NAME); assertTrue(countryByIdOrName.isPresent()); assertEquals(feature, countryByIdOrName.get()); countryByIdOrName = countriesGeoJsonServiceImpl.countryByIdOrName("123"); assertTrue(!countryByIdOrName.isPresent()); } @Test public void entryByCountryTest() { Optional> entryByCountry; Map data = new HashMap<>(); data.put(COUNTRY_NAME, 1d); entryByCountry = countriesGeoJsonServiceImpl.entryByCountry(data, feature); assertTrue(entryByCountry.isPresent()); entryByCountry = countriesGeoJsonServiceImpl.entryByCountry(data, null); assertTrue(!entryByCountry.isPresent()); entryByCountry = countriesGeoJsonServiceImpl.entryByCountry(new HashMap<>(), feature); assertTrue(!entryByCountry.isPresent()); } @Test public void valueByCountryTest() { Double val = 1d; Optional valueByCountry; Map data = new HashMap<>(); data.put(COUNTRY_NAME, val); valueByCountry = countriesGeoJsonServiceImpl.valueByCountry(data, feature); assertTrue(valueByCountry.isPresent()); assertEquals(val, valueByCountry.get()); valueByCountry = countriesGeoJsonServiceImpl.valueByCountry(data, null); assertFalse(valueByCountry.isPresent()); valueByCountry = countriesGeoJsonServiceImpl.valueByCountry(new HashMap<>(), null); assertFalse(valueByCountry.isPresent()); } @Test public void entryByLocationTest() { when(d3.geoContains(any(), any())).thenReturn(true); Optional> entryByLocation; Map data = new HashMap<>(); data.put(COUNTRY_LOCATION, 1d); entryByLocation = countriesGeoJsonServiceImpl.entriesByLocation(data, feature).findFirst(); ; assertTrue(entryByLocation.isPresent()); verify(d3).geoContains(any(), any()); when(d3.geoContains(any(), any())).thenReturn(false); entryByLocation = countriesGeoJsonServiceImpl.entriesByLocation(data, null).findFirst(); assertFalse(entryByLocation.isPresent()); entryByLocation = countriesGeoJsonServiceImpl.entriesByLocation(new HashMap<>(), feature).findFirst(); assertFalse(entryByLocation.isPresent()); when(d3.geoContains(any(), any())).thenReturn(false); entryByLocation = countriesGeoJsonServiceImpl.entriesByLocation(data, feature).findFirst(); assertFalse(entryByLocation.isPresent()); } @Test public void valueByLocationTest() { when(d3.geoContains(any(), any())).thenReturn(true); Double val = 1d; Optional valueByLocation; Map data = new HashMap<>(); data.put(COUNTRY_LOCATION, val); valueByLocation = countriesGeoJsonServiceImpl.valueByLocation(data, feature); assertTrue(valueByLocation.isPresent()); assertEquals(val, valueByLocation.get()); verify(d3).geoContains(feature, LONG_LAT); when(d3.geoContains(any(), any())).thenReturn(false); valueByLocation = countriesGeoJsonServiceImpl.valueByLocation(data, null); assertFalse(valueByLocation.isPresent()); valueByLocation = countriesGeoJsonServiceImpl.valueByLocation(new HashMap<>(), null); assertFalse(valueByLocation.isPresent()); } @Test public void findCountryWithLocationTest() { when(d3.geoContains(any(), any())).thenReturn(true); Map data = new HashMap<>(); data.put(COUNTRY_LOCATION, 1d); Optional findCountry = countriesGeoJsonServiceImpl.findCountry(COUNTRY_LOCATION); assertTrue(findCountry.isPresent()); assertEquals(COUNTRY_CODE, findCountry.get().getId()); assertEquals(COUNTRY_NAME, countriesGeoJsonServiceImpl.getCountryName(findCountry.get())); verify(d3).geoContains(feature, LONG_LAT); } @Test public void findCountryWithCountryNameTest() { Map data = new HashMap<>(); data.put(COUNTRY_NAME, 1d); Optional findCountry = countriesGeoJsonServiceImpl.findCountry(COUNTRY_NAME); assertTrue(findCountry.isPresent()); assertEquals(COUNTRY_CODE, findCountry.get().getId()); assertEquals(COUNTRY_NAME, countriesGeoJsonServiceImpl.getCountryName(findCountry.get())); verify(d3, times(0)).geoContains(any(), any()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-c3/src/test/java/org/dashbuilder/renderer/c3/client/charts/meter/C3MeterDisplayerTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.c3.client.charts.meter; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_AMOUNT; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_DATE; import static org.dashbuilder.dataset.ExpenseReportsData.COLUMN_ID; import static org.dashbuilder.dataset.group.AggregateFunctionType.SUM; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import java.text.ParseException; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.RawDataSet; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.renderer.c3.client.C3BaseTest; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.Silent.class) public class C3MeterDisplayerTest extends C3BaseTest { private static final String CL1 = "CL1"; private static final String CL2 = "CL2"; RawDataSet twoColumnsRawDS = new RawDataSet( new String [] {CL1,CL2}, new Class[] {String.class, String.class}, new String[][]{ {"VAL1", "1"}, {"VAL2", "2"} }); RawDataSet oneColumnsRawDS = new RawDataSet( new String [] {CL1}, new Class[] {String.class}, new String[][]{ {"1"}, {"2"} }); DisplayerSettings meterSettings = DisplayerSettingsFactory.newMeterChartSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM).format("","0.0000") .buildSettings(); DisplayerSettings meterSettingsOneColumn = DisplayerSettingsFactory.newMeterChartSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .column(COLUMN_AMOUNT).format("","0.0") .buildSettings(); @Test public void c3meterColumnsExtractorsTest() throws ParseException { C3MeterChartDisplayer c3MeterChartDisplayer = c3MeterChartDisplayer(meterSettings); c3MeterChartDisplayer.draw(); DataSet twoColumnDS = twoColumnsRawDS.toDataSet(); DataSet oneColumnDS = oneColumnsRawDS.toDataSet(); DataColumn cl1 = twoColumnDS.getColumnById(CL1); DataColumn cl2 = twoColumnDS.getColumnById(CL2); String[][] valuesWhenUsingGrouping = c3MeterChartDisplayer.extractGroupingValues(cl1, cl2); assertEquals(2, valuesWhenUsingGrouping.length); assertArrayEquals(new String[] {"VAL1", "1"}, valuesWhenUsingGrouping[0]); assertArrayEquals(new String[] {"VAL2", "2"}, valuesWhenUsingGrouping[1]); cl1 = oneColumnDS.getColumnById(CL1); String[] singleColumnValues = c3MeterChartDisplayer.extractSingleColumnValues(cl1); assertEquals(3, singleColumnValues.length); assertArrayEquals(new String[] {CL1, "1", "2"}, singleColumnValues); } @Test public void columnFormatTest() throws ParseException { C3MeterChartDisplayer c3MeterChartDisplayer = c3MeterChartDisplayer(meterSettings); c3MeterChartDisplayer.draw(); Object formattedTooltip = c3MeterChartDisplayer.formatTooltip(1l, null, null); assertEquals("1.0000", formattedTooltip); c3MeterChartDisplayer = c3MeterChartDisplayer(meterSettingsOneColumn); c3MeterChartDisplayer.draw(); formattedTooltip = c3MeterChartDisplayer.formatTooltip(1l, null, null); assertEquals("1.0", formattedTooltip); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/pom.xml ================================================ dashbuilder-renderers org.dashbuilder 7.75.0-SNAPSHOT 4.0.0 dashbuilder-renderer-chartjs jar Dashbuilder Renderer ChartJS Dashbuilder Renderer for the Chart JS API com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 org.dashbuilder dashbuilder-common-client org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-client src/main/java src/main/resources ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/ChartJsBarChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.chartjs; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; @Dependent public class ChartJsBarChartDisplayer extends ChartJsDisplayer { public interface View extends ChartJsDisplayer.View { } private View view; public ChartJsBarChartDisplayer() { this(new ChartJsBarChartDisplayerView()); } @Inject public ChartJsBarChartDisplayer(View view) { this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(10) .setMinColumns(2) .setExtraColumnsAllowed(true) .setExtraColumnsType(ColumnType.NUMBER) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[]{ ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/ChartJsBarChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.chartjs; import org.dashbuilder.renderer.chartjs.lib.BarChart; import org.dashbuilder.renderer.chartjs.lib.Chart; public class ChartJsBarChartDisplayerView extends ChartJsDisplayerView implements ChartJsBarChartDisplayer.View { @Override protected Chart createChart() { BarChart chart = new BarChart(); if (title != null) { chart.setTitle(title); } String displayerId = getPresenter().getDisplayerId(); chart.setTooltipTemplate("<%= label %>: <%= window.chartJsFormatValue('" + displayerId + "', value, 1) %>"); chart.setMultiTooltipTemplate("<%= datasetLabel %>: <%= window.chartJsFormatValue('" + displayerId + "', value, 1) %>"); chart.setScaleStepWidth(10); chart.setLegendTemplate("
    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
"); chart.setDataProvider(super.createAreaDataProvider()); return chart; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/ChartJsDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.chartjs; import java.util.List; import java.util.Set; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.client.AbstractGwtDisplayer; public abstract class ChartJsDisplayer extends AbstractGwtDisplayer { public interface View

extends AbstractGwtDisplayer.View

{ void setWidth(int width); void setHeight(int height); void setMarginTop(int marginTop); void setMarginBottom(int marginBottom); void setMarginRight(int marginRight); void setMarginLeft(int marginLeft); void dataClear(); void dataAddLabel(String label); void dataAddSerie(String columnName, String color, double[] values); String getGroupsTitle(); String getColumnsTitle(); void setTitle(String title); void setFilterEnabled(boolean enabled); void clearFilterStatus(); void addFilterValue(String value); void addFilterReset(); void nodata(); void drawChart(); } public static final String[] COLOR_ARRAY = new String[] { "blue", "red", "orange", "brown", "coral", "aqua", "fuchsia", "gold", "green", "grey", "lime", "magenta", "pink", "silver", "yellow"}; @Override protected void createVisualization() { if (displayerSettings.isTitleVisible()) { getView().setTitle(displayerSettings.getTitle()); } getView().setFilterEnabled(displayerSettings.isFilterEnabled()); getView().setWidth(displayerSettings.getChartWidth()); getView().setHeight(displayerSettings.getChartHeight()); getView().setMarginTop(displayerSettings.getChartMarginTop()); getView().setMarginBottom(displayerSettings.getChartMarginBottom()); getView().setMarginLeft(displayerSettings.getChartMarginLeft()); getView().setMarginRight(displayerSettings.getChartMarginRight()); drawChart(); } @Override protected void updateVisualization() { updateFilterStatus(); drawChart(); } protected void drawChart() { if (dataSet.getRowCount() == 0) { getView().nodata(); } else { pushDataToView(); getView().drawChart(); } } protected void updateFilterStatus() { getView().clearFilterStatus(); Set columnFilters = filterColumns(); if (displayerSettings.isFilterEnabled() && !columnFilters.isEmpty()) { for (String columnId : columnFilters) { List selectedValues = filterIntervals(columnId); DataColumn column = dataSet.getColumnById(columnId); for (Interval interval : selectedValues) { String formattedValue = formatInterval(interval, column); getView().addFilterValue(formattedValue); } } getView().addFilterReset(); } } // View notifications void onFilterResetClicked() { filterReset(); // Update the displayer view in order to reflect the current selection // (only if not has already been redrawn in the previous filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } // Data generation protected void pushDataToView() { getView().dataClear(); for (int i=0; i columns = dataSet.getColumns(); for (int i=1; i extends AbstractGwtDisplayerView

implements ChartJsDisplayer.View

{ private Panel container = new FlowPanel(); private Panel filterPanel = new HorizontalPanel(); private Panel displayerPanel = new FlowPanel(); private HTML titleHtml = new HTML(); private Chart chart = null; private List labels = new ArrayList(); private JsArray series; protected boolean filterEnabled = false; protected String title = null; protected int width = 500; protected int height= 300; protected int marginTop = 10; protected int marginBottom = 10; protected int marginRight = 10; protected int marginLeft = 10; public void showDisplayer(Widget w) { displayerPanel.clear(); displayerPanel.add(w); } @Override public void init(P presenter) { super.setPresenter(presenter); super.setVisualization(container); container.add(titleHtml); container.add(filterPanel); container.add(displayerPanel); filterPanel.getElement().setAttribute("cellpadding", "2"); } @Override public void clear() { super.clear(); ChartJsRenderer.closeDisplayer(getPresenter()); } @Override public void setWidth(int width) { this.width = width; } @Override public void setHeight(int height) { this.height = height; } @Override public void setMarginTop(int marginTop) { this.marginTop = marginTop; } @Override public void setMarginBottom(int marginBottom) { this.marginBottom = marginBottom; } @Override public void setMarginRight(int marginRight) { this.marginRight = marginRight; } @Override public void setMarginLeft(int marginLeft) { this.marginLeft = marginLeft; } @Override public void dataClear() { labels.clear(); series = JavaScriptObject.createArray().cast(); } @Override public void dataAddLabel(String label) { labels.add(label); } @Override public void dataAddSerie(String columnName, String color, double[] values) { series.push(SeriesBuilder.create() .withLabel(columnName) .withFillColor(color) .withStoreColor(color) .withPointColor(color) .withPointStrokeColor("#FFFF") .withData(values) .get()); } @Override public String getGroupsTitle() { return ChartJsDisplayerConstants.INSTANCE.common_Categories(); } @Override public String getColumnsTitle() { return ChartJsDisplayerConstants.INSTANCE.common_Series(); } @Override public void setTitle(String title) { titleHtml.setText(title); } @Override public void setFilterEnabled(boolean enabled) { this.filterEnabled = enabled; } @Override public void clearFilterStatus() { if (filterPanel != null) { filterPanel.clear(); } } @Override public void addFilterValue(String value) { filterPanel.add(new Label(value)); } @Override public void addFilterReset() { Anchor anchor = new Anchor(ChartJsDisplayerConstants.INSTANCE.chartjsDisplayer_resetAnchor()); filterPanel.add(anchor); anchor.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { getPresenter().onFilterResetClicked(); } }); } @Override public void nodata() { showDisplayer(new Label(ChartJsDisplayerConstants.INSTANCE.common_noData())); } @Override public void drawChart() { if (chart == null) { chart = createChart(); showDisplayer(chart); } if (filterEnabled) { chart.addDataSelectionHandler(new DataSelectionHandler() { public void onDataSelected(DataSelectionEvent event) { // TODO Object o = event.getSource(); } }); } adjustChartSize(chart); chart.update(); } // Common methods used in subclasses protected Chart createChart() { return null; } protected void adjustChartSize(Chart chart) { int chartWidth = width-marginLeft; int chartHeight = height-marginTop; chart.getElement().getStyle().setPaddingTop(marginTop, Style.Unit.PX); chart.getElement().getStyle().setPaddingLeft(marginLeft, Style.Unit.PX); chart.setPixelWidth(chartWidth); chart.setPixelHeight(chartHeight); } protected AreaChartDataProvider createAreaDataProvider() { return new AreaChartDataProvider() { public JavaScriptObject getData() { return createChartData(); } public void reload(AsyncCallback callback) { AreaChartData data = createChartData(); callback.onSuccess(data); } }; } protected AreaChartData createChartData() { String[] labelsArray = new String[labels.size()]; labels.toArray(labelsArray); AreaChartData data = JavaScriptObject.createObject().cast(); data.setLabels(labelsArray); data.setSeries(series); return data; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/ChartJsRenderer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.chartjs; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.AbstractRendererLibrary; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.renderer.chartjs.lib.ChartJs; import static org.dashbuilder.displayer.DisplayerSubType.*; import static org.dashbuilder.displayer.DisplayerType.*; /** * Chart JS renderer */ @ApplicationScoped public class ChartJsRenderer extends AbstractRendererLibrary { public static final String UUID = "chartjs"; @PostConstruct private void init() { publishChartJsFunctions(); } @Override public String getUUID() { return UUID; } @Override public String getName() { return "Chart JS"; } @Override public List getSupportedTypes() { return Arrays.asList(BARCHART); } @Override public List getSupportedSubtypes(DisplayerType displayerType) { switch (displayerType) { case BARCHART: return Arrays.asList(COLUMN); case PIECHART: return Arrays.asList(PIE, DONUT); case AREACHART: return Arrays.asList(AREA); case LINECHART: return Arrays.asList(LINE); default: return Arrays.asList(); } } @Override public Displayer lookupDisplayer(DisplayerSettings displayerSettings) { ChartJsDisplayer displayer = _lookupDisplayer(displayerSettings); if (displayer != null) { _displayerMap.put(displayerSettings.getUUID(), displayer); } return displayer; } protected ChartJsDisplayer _lookupDisplayer(DisplayerSettings displayerSettings) { ChartJs.ensureInjected(); DisplayerType type = displayerSettings.getType(); if ( DisplayerType.BARCHART.equals(type)) { return new ChartJsBarChartDisplayer(); } return null; } private native void publishChartJsFunctions() /*-{ $wnd.chartJsFormatValue = $entry(@org.dashbuilder.renderer.chartjs.ChartJsRenderer::formatValue(Ljava/lang/String;DI)); }-*/; protected static Map _displayerMap = new HashMap(); public static String formatValue(String displayerId, double value, int column) { ChartJsDisplayer displayer = _displayerMap.get(displayerId); if (displayer == null) return Double.toString(value); DataColumn dataColumn = displayer.getDataSetHandler().getLastDataSet().getColumnByIndex(column); return displayer.formatValue(value, dataColumn); } public static void closeDisplayer(ChartJsDisplayer displayer) { _displayerMap.remove(displayer.getDisplayerId()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/BarChart.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.user.client.rpc.AsyncCallback; import org.dashbuilder.renderer.chartjs.lib.data.AreaChartData; import org.dashbuilder.renderer.chartjs.lib.data.AreaChartDataProvider; public class BarChart extends ChartWithScale { private AreaChartDataProvider provider; @Override public void draw() { reload(); } private native void drawBar(JavaScriptObject data)/*-{ canvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeElement()(); nativeCanvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeCanvas()(); if(nativeCanvas != null) { nativeCanvas.destroy(); } var options = this.@org.dashbuilder.renderer.chartjs.lib.Chart::constructOptions()(); nativeCanvas = new $wnd.Chart(canvas.getContext("2d")).Bar(data, options); this.@org.dashbuilder.renderer.chartjs.lib.Chart::setNativeCanvas(Lcom/google/gwt/core/client/JavaScriptObject;)(nativeCanvas); }-*/; @Override public void update() { if(provider == null) throw new NullPointerException("PieCharDataProvider is not specified before invoking update()"); drawBar(provider.getData()); } @Override public void reload() { if(provider == null) throw new NullPointerException("PieCharDataProvider is not specified before invoking reload()"); //TODO : show loading provider.reload(new AsyncCallback() { @Override public void onSuccess(AreaChartData result) { drawBar(result); } @Override public void onFailure(Throwable caught) { // TODO Auto-generated method stub } }); } public void setDataProvider(AreaChartDataProvider provider){ this.provider = provider; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/Chart.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.CanvasElement; import com.google.gwt.dom.client.Document; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.HasClickHandlers; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.SimplePanel; import org.dashbuilder.renderer.chartjs.lib.event.*; import org.dashbuilder.renderer.chartjs.lib.options.*; import org.dashbuilder.renderer.chartjs.lib.resources.ChartStyle; import org.dashbuilder.renderer.chartjs.lib.resources.Resources; import java.util.ArrayList; import java.util.List; /** * Base class for all chart widgets
* Class describes generic behavior of all chart widgets */ public abstract class Chart extends SimplePanel implements HasAnimationCompleteHandlers, HasClickHandlers,HasAnimation, HasDataSelectionEventHandlers, IsResponsive{ private static Resources resources; protected LegendOption options = LegendOption.get(); protected JavaScriptObject nativeCanvas; private CanvasElement canvas; protected ChartStyle style; protected List callbackList = new ArrayList(); static{ resources = GWT.create(Resources.class); } /** * This constructor creates new chart instance with custom {@link ChartStyle} * @param style - new CssResource used for styling charts */ public Chart(ChartStyle style){ //setChartStyle(style); registerNativeAnimationHandlers(); canvas = Document.get().createCanvasElement(); getElement().appendChild(canvas); sinkEvents(Event.ONCLICK); addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent clickEvent) { JavaScriptObject obj = clickEvent.getNativeEvent().cast(); JavaScriptObject data = getClickPoints(obj, nativeCanvas); if (data != null) DataSelectionEvent.fire(Chart.this, Chart.this, data); } }); } /** * Constructor creates chart with default style */ public Chart() { this(resources.chartStyle()); } private native JavaScriptObject getClickPoints(JavaScriptObject event, JavaScriptObject canvas)/*-{ if(canvas == null || event == null) return null; try { return canvas.getPointsAtEvent(event); } catch(e){ //exception occurred when added additional ClickHandler which destroys chart before processing. return null; } }-*/; /** * Set new style to the char widget. New style will be injected automatically.
* NOTICE: new style will be applied after re-drawing of chart
* @param style */ public void setChartStyle(ChartStyle style){ style.ensureInjected(); setStylePrimaryName(style.chart()); } protected void processEvents(JavaScriptObject object){ this.nativeCanvas = object; } @Override protected void onAttach() { ChartJs.ensureInjected(); super.onAttach(); draw(); } /** * Method re-drawing chart widget without re-requesting data from data provider.
* To update data call {@link #reload()} method instead */ public abstract void update(); /** * Method requesting data from data provider and re-drawing chart. */ public abstract void reload(); /** * Method preparing data and invoking native draw method
* This method should not be overridden by sub-classes */ protected abstract void draw(); /** * Method sets pixel width of chart area * @param width - width in pixels * TODO: replace it with generic {@link #setWidth(String)} and {@link #setSize(String, String)} */ public void setPixelWidth(int width) { canvas.setWidth(width); } public void setWidth(String width) { canvas.getStyle().setProperty("width", width); } public void setHeight(String height){ canvas.getStyle().setProperty("height", height); } /** * Method sets pixel height of chart area * @param height - height in pixels * TODO: replace it with generic {@link #setHeight(String)} and {@link #setSize(String, String)} */ public void setPixelHeight(int height) { canvas.setHeight(height); } @Override public void addAnimationCompleteHandler(AnimationCompleteHandler handler) { addHandler(handler, AnimationCompleteEvent.getType()); } /** * Creates snapshot of current state of chart as image * @return Image object or null if Chart not rendered (or in progress) */ public Image getSnapshot(){ String code= getBase64Image(nativeCanvas); if(code == null) return null; Image image = new Image(code); return image; } private native String getBase64Image(JavaScriptObject nativeCanvas)/*-{ if(nativeCanvas != null) return nativeCanvas.toBase64Image(); return null; }-*/; @Override /** * Important Note : clickHandler added internally by default to handle DataSelectionEvent. * In case external clickHandler destroying chart (eg update() method invoked) this will lead * to DataSelectionEvent won't be created */ public HandlerRegistration addClickHandler(ClickHandler clickHandler) { return addHandler(clickHandler, ClickEvent.getType()); } @Override public HandlerRegistration addDataSelectionHandler(DataSelectionHandler handler) { return addHandler(handler, DataSelectionEvent.getType()); } protected JavaScriptObject getNativeCanvas(){ return nativeCanvas; } protected CanvasElement getNativeElement(){ return canvas; } protected void setNativeCanvas(JavaScriptObject object){ this.nativeCanvas = object; processEvents(object); } /** * Specify should chart be animated or not * Default value is true * @param enabled */ public void setAnimationEnabled(boolean enabled){ if(!enabled) //"animation" : false interpreted by chart.js as "true" options.clearProperty(ANIMATION); else options.setProperty(ANIMATION, enabled); } /** * Specify animation easing * Default value is {@link org.dashbuilder.renderer.chartjs.lib.options.Type#EASE_OUT_QUART} * @param type */ public void setAnimationType(Type type){ if(type == null) options.clearProperty(ANIMATION_EASING); else options.setProperty(ANIMATION_EASING, type.getValue()); } /** * Add animation callback to handle animation state changes * @param callback */ public void addAnimationCallback(AnimationCallback callback){ if(callback != null) callbackList.add(callback); } @Override public void setAnimationSteps(int steps) { if(steps <= 0) throw new IndexOutOfBoundsException("Number of animation steps should be positive. Found '"+steps+"'"); options.setProperty(ANIMATION_STEPS, steps); } /** * Method returns custom options for chart * @return */ protected JavaScriptObject constructOptions(){ return options; } protected native void registerNativeAnimationHandlers()/*-{ options = this.@org.dashbuilder.renderer.chartjs.lib.Chart::constructOptions()(); self = this; options.onAnimationProgress = function(progress){ self.@org.dashbuilder.renderer.chartjs.lib.Chart::onAnimationProgress(D)(progress); return; } options.onAnimationComplete = function(){ self.@org.dashbuilder.renderer.chartjs.lib.Chart::onAnimationComplete()(); return; } }-*/; protected void onAnimationProgress(double progress){ for(AnimationCallback callback : callbackList){ if(callback != null) callback.onProgress(progress); } } protected void onAnimationComplete(){ for(AnimationCallback callback : callbackList){ if(callback != null) callback.onAnimationComplete(); } } @Override public void setResponsive(boolean responsive){ if(!responsive) options.clearProperty(RESPONSIVE); else options.setProperty(RESPONSIVE, true); } @Override public void setMaintainAspectRatio(boolean aspectRatio){ if(!aspectRatio) options.clearProperty(MAINTAIN_ASPECT_RATIO); else options.setProperty(MAINTAIN_ASPECT_RATIO, true); } public void setLegendTemplate(String template) { options.setLegendTemplate(template); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/ChartJs.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.ScriptElement; import org.dashbuilder.renderer.chartjs.lib.resources.Resources; import com.google.gwt.core.client.GWT; /** * Utility class which helps to inject native chart.js code into browser */ public final class ChartJs { private static boolean injected = false; /** * Method injecting native chart.js code into the browser
* In case code already been injected do nothing */ public static void ensureInjected(){ //TODO: do real injection (lazy loading) if(injected) return; Resources res = GWT.create(Resources.class); String source = res.chartJsSource().getText(); ScriptElement scriptElement = Document.get().createScriptElement(); scriptElement.setId("_chartjs"); scriptElement.setInnerText(source); Document.get().getBody().appendChild(scriptElement); injected = true; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/ChartWithAnimation.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import org.dashbuilder.renderer.chartjs.lib.event.AnimationCompleteEvent; import org.dashbuilder.renderer.chartjs.lib.event.AnimationCompleteHandler; import org.dashbuilder.renderer.chartjs.lib.event.HasAnimationCompleteHandlers; import org.dashbuilder.renderer.chartjs.lib.options.AnimationCallback; import org.dashbuilder.renderer.chartjs.lib.options.HasAnimation; import org.dashbuilder.renderer.chartjs.lib.options.IsResponsive; import org.dashbuilder.renderer.chartjs.lib.options.Type; import java.util.ArrayList; import java.util.List; public abstract class ChartWithAnimation extends Chart implements IsResponsive, HasAnimation,HasAnimationCompleteHandlers { protected List callbackList = new ArrayList(); public ChartWithAnimation(){ super(); registerNativeAnimationHandlers(); } @Override public void setResponsive(boolean responsive){ if(!responsive) options.clearProperty(RESPONSIVE); else options.setProperty(RESPONSIVE, true); } /** * Specify should chart be animated or not * Default value is true * @param enabled */ public void setAnimationEnabled(boolean enabled){ if(!enabled) //"animation" : false interpreted by chart.js as "true" options.clearProperty(ANIMATION); else options.setProperty(ANIMATION, enabled); } /** * Specify animation easing * Default value is {@link org.dashbuilder.renderer.chartjs.lib.options.Type#EASE_OUT_QUART} * @param type */ public void setAnimationType(Type type){ if(type == null) options.clearProperty(ANIMATION_EASING); else options.setProperty(ANIMATION_EASING, type.getValue()); } /** * Add animation callback to handle animation state changes * @param callback */ public void addAnimationCallback(AnimationCallback callback){ if(callback != null) callbackList.add(callback); } @Override public void setAnimationSteps(int steps) { if(steps <= 0) throw new IndexOutOfBoundsException("Number of animation steps should be positive. Found '"+steps+"'"); options.setProperty(ANIMATION_STEPS, steps); } @Override public void addAnimationCompleteHandler(AnimationCompleteHandler handler) { addHandler(handler, AnimationCompleteEvent.getType()); } protected void onAnimationProgress(double progress){ for(AnimationCallback callback : callbackList){ if(callback != null) callback.onProgress(progress); } } protected void onAnimationComplete(){ for(AnimationCallback callback : callbackList){ if(callback != null) callback.onAnimationComplete(); } } protected native void registerNativeAnimationHandlers()/*-{ options = this.@org.dashbuilder.renderer.chartjs.lib.Chart::constructOptions()(); self = this; options.onAnimationProgress = function(progress){ self.@org.dashbuilder.renderer.chartjs.lib.Chart::onAnimationProgress(D)(progress); return; } options.onAnimationComplete = function(){ self.@org.dashbuilder.renderer.chartjs.lib.Chart::onAnimationComplete()(); return; } }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/ChartWithScale.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.dom.client.Style; import org.dashbuilder.renderer.chartjs.lib.options.HasScale; public abstract class ChartWithScale extends ChartWithTooltip implements HasScale{ @Override public void showScale(boolean scale) { if(!scale) options.clearProperty(SHOWSCALE); else options.setProperty(SHOWSCALE, true); } @Override public void setScaleOverride(boolean override) { if(!override) options.clearProperty(SCALEOVERRIDE); else options.setProperty(SCALEOVERRIDE, override); } @Override public void setScaleSteps(int steps) { options.setProperty(SCALESTEPS, steps); } @Override public void setScaleStepWidth(int width) { options.setProperty(SCALESTEPWIDTH, width); } @Override public void setScaleStartValue(double startValue) { options.setProperty(SCALESTARTVALUE, startValue); } @Override public void setScaleLineColor(String color) { options.setProperty(SCALELINECOLOR, color); } @Override public void setScaleLineWidth(int pixelWidth) { options.setProperty(SCALELINEWIDTH, pixelWidth); } @Override public void setScaleShowLabels(boolean showLabels) { if(!showLabels) options.clearProperty(SCALESHOWLABELS); else options.setProperty(SCALESHOWLABELS, true); } @Override public void setScaleLabel(String template) { options.setProperty(SCALELABEL, template); } @Override public void setScaleIntegersOnly(boolean only) { if(!only) options.clearProperty(SCALEINTEGERSONLY); else options.setProperty(SCALEINTEGERSONLY, only); } @Override public void setScaleBeginAtZero(boolean beginAtZero) { options.setProperty(SCALEBEGINATZERO, beginAtZero); } @Override public void setScaleFontFamily(String fontFamily) { options.setProperty(SCALEFONTFAMILY, fontFamily); } @Override public void setScaleFontSize(int size) { options.setProperty(SCALEFONTSIZE, size); } @Override public void setScaleFontStyle(Style.FontStyle style) { options.setProperty(SCALEFONTSTYLE, style.getCssName()); } @Override public void setScaleFontColor(String color) { options.setProperty(SCALEFONTCOLOR, color); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/ChartWithTooltip.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; import org.dashbuilder.renderer.chartjs.lib.options.HasTooltip; /** * Adds tooltip configurations to Chart object */ public abstract class ChartWithTooltip extends Chart implements HasTooltip{ @Override public void setTooltipEvents(Event... events) { String[] eventsString = new String[events.length]; for(int i=0;i>() { @Override public void onSuccess(JsArray result) { drawDoughnut(result); } @Override public void onFailure(Throwable caught) { // TODO Auto-generated method stub } }); } public void setDataProvider(PieChartDataProvider provider){ this.provider = provider; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/LineChart.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.user.client.rpc.AsyncCallback; import org.dashbuilder.renderer.chartjs.lib.data.AreaChartData; import org.dashbuilder.renderer.chartjs.lib.data.AreaChartDataProvider; public class LineChart extends ChartWithScale { private AreaChartDataProvider provider = null; @Override public void draw() { reload(); } private native void drawLine(JavaScriptObject data)/*-{ canvas = this.@org.dashbuilder.renderer.chartjs.lib.LineChart::getNativeElement()(); nativeCanvas = this.@org.dashbuilder.renderer.chartjs.lib.LineChart::getNativeCanvas()(); if(nativeCanvas != null) { nativeCanvas.destroy(); } var options = this.@org.dashbuilder.renderer.chartjs.lib.LineChart::constructOptions()(); nativeCanvas = new $wnd.Chart(canvas.getContext("2d")).Line(data,options); this.@org.dashbuilder.renderer.chartjs.lib.LineChart::setNativeCanvas(Lcom/google/gwt/core/client/JavaScriptObject;)(nativeCanvas); }-*/; @Override public void update() { if(provider == null) throw new NullPointerException("Data provider is not specified before calling update()"); drawLine(provider.getData()); } @Override public void reload() { if(provider == null) throw new NullPointerException("Data provider is not specified before calling reload()"); //TODO: show some king of loading to user provider.reload(new AsyncCallback() { @Override public void onSuccess(AreaChartData result) { drawLine(result); } @Override public void onFailure(Throwable caught) { //TODO: show loading error to user } }); } public void setDataProvider(AreaChartDataProvider provider){ this.provider = provider; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/PieChart.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.rpc.AsyncCallback; import org.dashbuilder.renderer.chartjs.lib.data.PieChartDataProvider; import org.dashbuilder.renderer.chartjs.lib.data.Series; public class PieChart extends ChartWithScale { private PieChartDataProvider provider; @Override public void draw() { reload(); } private native void drawPie(JavaScriptObject data)/*-{ canvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeElement()(); nativeCanvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeCanvas()(); if(nativeCanvas != null) { nativeCanvas.destroy(); } options = this.@org.dashbuilder.renderer.chartjs.lib.Chart::constructOptions()(); nativeCanvas = new $wnd.Chart(canvas.getContext("2d")).Pie(data,options); this.@org.dashbuilder.renderer.chartjs.lib.Chart::setNativeCanvas(Lcom/google/gwt/core/client/JavaScriptObject;)(nativeCanvas); }-*/; @Override public void update() { if(provider == null) throw new NullPointerException("PieChartDataProvider not initialized before invoking update()"); drawPie(provider.getData()); } @Override public void reload() { if(provider == null) throw new NullPointerException("PieChartDataProvider not initialized before invoking update()"); //TODO: show loading provider.reload(new AsyncCallback>() { @Override public void onSuccess(JsArray result) { drawPie(provider.getData()); } @Override public void onFailure(Throwable caught) { // TODO Auto-generated method stub } }); } public void setDataProvider(PieChartDataProvider provider){ this.provider = provider; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/PolarAreaChart.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.rpc.AsyncCallback; import org.dashbuilder.renderer.chartjs.lib.data.PieChartDataProvider; import org.dashbuilder.renderer.chartjs.lib.data.Series; public class PolarAreaChart extends ChartWithScale { private PieChartDataProvider provider; @Override public void draw() { reload(); } private native void drawPolarArea(JavaScriptObject data)/*-{ canvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeElement()(); nativeCanvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeCanvas()(); if(nativeCanvas != null) { nativeCanvas.destroy(); } var options = this.@org.dashbuilder.renderer.chartjs.lib.Chart::constructOptions()(); nativeCanvas = new $wnd.Chart(canvas.getContext("2d")).PolarArea(data,options); this.@org.dashbuilder.renderer.chartjs.lib.Chart::setNativeCanvas(Lcom/google/gwt/core/client/JavaScriptObject;)(nativeCanvas); }-*/; @Override public void update() { if(provider == null) throw new NullPointerException("PieChartDataProvider is not initialized before invoking update()"); drawPolarArea(provider.getData()); } @Override public void reload() { if(provider == null) throw new NullPointerException("PieChartDataProvider is not initialized before invoking reload()"); //TODO: show loading to user provider.reload(new AsyncCallback>() { @Override public void onSuccess(JsArray result) { drawPolarArea(provider.getData()); } @Override public void onFailure(Throwable caught) { // TODO Auto-generated method stub } }); } public void setDataProvider(PieChartDataProvider provider){ this.provider = provider; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/RadarChart.java ================================================ package org.dashbuilder.renderer.chartjs.lib; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.rpc.AsyncCallback; import org.dashbuilder.renderer.chartjs.lib.data.AreaChartData; import org.dashbuilder.renderer.chartjs.lib.data.AreaChartDataProvider; public class RadarChart extends ChartWithScale { private AreaChartDataProvider provider; private boolean scaleShowLabels = false; @Override public void draw() { reload(); } public void setScaleShowLabels(boolean scaleShowLabels){ this.scaleShowLabels = scaleShowLabels; } private native void drawRadar(JavaScriptObject data)/*-{ canvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeElement()(); nativeCanvas = this.@org.dashbuilder.renderer.chartjs.lib.Chart::getNativeCanvas()(); if(nativeCanvas != null) { nativeCanvas.destroy(); } var options = this.@org.dashbuilder.renderer.chartjs.lib.Chart::constructOptions()(); if(options == null) options = {scaleShowLabels : true, pointLabelFontSize : 10}; nativeCanvas = new $wnd.Chart(canvas.getContext("2d")).Radar(data,options); this.@org.dashbuilder.renderer.chartjs.lib.Chart::setNativeCanvas(Lcom/google/gwt/core/client/JavaScriptObject;)(nativeCanvas); }-*/; @Override public void update() { if(provider == null) throw new NullPointerException("PieCharDataProvider was not initialized before invoking update()"); drawRadar(provider.getData()); } @Override public void reload() { if(provider == null) throw new NullPointerException("PieCharDataProvider was not initialized before invoking reload()"); //TODO: show loading.. provider.reload(new AsyncCallback() { @Override public void onSuccess(AreaChartData result) { drawRadar(result); } @Override public void onFailure(Throwable caught) { // TODO Auto-generated method stub } }); } public void setDataProvider(AreaChartDataProvider provider){ this.provider = provider; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/AreaChartData.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayString; public class AreaChartData extends JavaScriptObject{ protected AreaChartData(){ } public final void setLabels(String[] labels){ JsArrayString array = JsArrayString.createArray().cast(); for(String str : labels) array.push(str); setLabels(array); } private final native void setLabels(JsArrayString labels) /*-{ this.labels = labels; }-*/; public final native JsArray getSeries() /*-{ return this.datasets; }-*/; public final native void setSeries(JsArray series) /*-{ this.datasets = series; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/AreaChartDataProvider.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.user.client.rpc.AsyncCallback; public interface AreaChartDataProvider { public JavaScriptObject getData(); public void reload(AsyncCallback callback); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/AreaSeries.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArrayNumber; public class AreaSeries extends JavaScriptObject{ protected AreaSeries() { } public final native String getFillColor() /*-{ return this.fillColor; }-*/; public final native void setFillColor(String fillColor) /*-{ this.fillColor = fillColor; }-*/; public final native String getStrokeColor() /*-{ return this.strokeColor; }-*/; public final native void setStrokeColor(String strokeColor) /*-{ this.strokeColor = strokeColor; }-*/; public final native String getPointColor() /*-{ return this.pointColor; }-*/; public final native void setPointColor(String printColor) /*-{ this.pointColor = printColor; }-*/; public final native String getPointStrokeColor() /*-{ return this.pointStrokeColor; }-*/; public final native void setPointStrokeColor(String pointStrokeColor) /*-{ this.pointStrokeColor = pointStrokeColor; }-*/; public final native String[] getData() /*-{ return this.data; }-*/; public final native void setLabel(String label)/*-{ this.label = label; }-*/; public final native String getLabel()/*-{ return this.label; }-*/; public final void setData(double[] data){ JsArrayNumber array = JsArrayNumber.createArray().cast(); for(double str : data) array.push(str); setData(array); } private final native void setData(JsArrayNumber data) /*-{ this.data = data; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/ChartDataProvider.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.user.client.rpc.AsyncCallback; import java.util.List; public abstract class ChartDataProvider{ protected List data; public List getData(){ return data; } public void setData(List data){ this.data = data; } public abstract void update(AsyncCallback callback); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/Data.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; /** * Data storage used for Pie, Radar charts */ public class Data extends JavaScriptObject{ protected Data() { } public final native void setValue(double value)/*-{ this.value = value; }-*/; public final native double setValue()/*-{ return this.value; }-*/; public final native void setColor(String color)/*-{ this.color = color; }-*/; public final native String setColor()/*-{ return this.color; }-*/; public final native void setHighlighColor(String color)/*-{ this.highlightColor = color; }-*/; public final native String setHighlighColor()/*-{ return this.highlightColor; }-*/; public final native void setLabel(String label)/*-{ this.label = label; }-*/; public final native String setLabel()/*-{ return this.label; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/Dataset.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; /** * Set of data which used for constructing Line/Bar charts */ public class Dataset extends JavaScriptObject{ protected Dataset() { } public final native void setLabel(String label)/*-{ this.label = label; }-*/; public final native String getLabel()/*-{ return this.label; }-*/; public final native void setFillColor(String fillColor)/*-{ this.fillColor = fillColor; }-*/; public final native String getFillColor()/*-{ return this.fillColor; }-*/; public final native void setStrokeColor(String strokeColor)/*-{ this.strokeColor = strokeColor; }-*/; public final native String getStrokeColor()/*-{ return this.strokeColor; }-*/; public final native void setPointColor(String pointColor)/*-{ this.pointColor = pointColor; }-*/; public final native String getPointColor()/*-{ return this.pointColor; }-*/; public final native void setPointStrokeColor(String pointStrokeColor)/*-{ this.pointStrokeColor = pointStrokeColor; }-*/; public final native String getPointStrokeColor()/*-{ return this.pointStrokeColor; }-*/; public final native void setPointHighlightFill(String pointHighlightFill)/*-{ this.pointHighlightFill = pointHighlightFill; }-*/; public final native String getPointHighlightFill()/*-{ return this.pointHighlightFill; }-*/; public final native void setPointHighlightStroke(String pointHighlightStroke)/*-{ this.pointHighlightStroke = pointHighlightStroke; }-*/; public final native String getPointHighlightStroke()/*-{ return this.pointHighlightStroke; }-*/; public final native void setData(double[] data)/*-{ this.data = data; }-*/; public final native double[] getData()/*-{ return this.data; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/LineChartData.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; public class LineChartData extends JavaScriptObject{ protected LineChartData() { } public final native void setLabels(String[] label)/*-{ this.labels = labels; }-*/; public final native void addLabel(String label)/*-{ labels.push(label); }-*/; public final native String[] getLabels()/*-{ return this.labels; }-*/; public final native void setDataset(Dataset[] dataset)/*-{ this.datasets = dataset; }-*/; public final native Dataset[] getDataset()/*-{ return this.datasets; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/PieChartDataProvider.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JsArray; import com.google.gwt.user.client.rpc.AsyncCallback; public interface PieChartDataProvider { public JsArray getData(); public void reload(AsyncCallback> callback); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/RadarChartData.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; public class RadarChartData extends JavaScriptObject{ protected RadarChartData() { } public final native void setData(Data[] data)/*-{ this.data = data; }-*/; public final native void getData()/*-{ return this.data; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/Series.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; public class Series extends JavaScriptObject{ protected Series() { } public final native double getValue() /*-{ return this.value; }-*/; public final native void setValue(double value) /*-{ this.value = value; }-*/; public final native String getColor() /*-{ return this.color; }-*/; public final native void setColor(String color) /*-{ this.color = color; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/data/SeriesBuilder.java ================================================ package org.dashbuilder.renderer.chartjs.lib.data; import com.google.gwt.core.client.JavaScriptObject; public class SeriesBuilder { private AreaSeries series = null; private SeriesBuilder(){ series = JavaScriptObject.createObject().cast(); } public static SeriesBuilder create(){ return new SeriesBuilder(); } public SeriesBuilder withLabel(String label){ series.setLabel(label); return this; } public SeriesBuilder withFillColor(String fillColor){ series.setFillColor(fillColor); return this; } public SeriesBuilder withStoreColor(String strokeColor){ series.setStrokeColor(strokeColor); return this; } public SeriesBuilder withPointColor(String pointColor){ series.setPointColor(pointColor); return this; } public SeriesBuilder withPointStrokeColor(String pointStrokeColor){ series.setPointStrokeColor(pointStrokeColor); return this; } public SeriesBuilder withData(double[] data){ series.setData(data); return this; } public AreaSeries get(){ return series; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/event/AnimationCompleteEvent.java ================================================ package org.dashbuilder.renderer.chartjs.lib.event; import org.dashbuilder.renderer.chartjs.lib.Chart; import com.google.gwt.event.shared.GwtEvent; /** * Class represents event occurred when {@link Chart} animation has been finished */ public class AnimationCompleteEvent extends GwtEvent{ private static Type TYPE = new Type(); private Object sender; protected AnimationCompleteEvent(Object sender){ this.sender = sender; } public Object getSender(){ return sender; } @Override public com.google.gwt.event.shared.GwtEvent.Type getAssociatedType() { return TYPE; } public static Type getType(){ return TYPE; } @Override protected void dispatch(AnimationCompleteHandler handler) { handler.onAnimationComplete(this); } public static void fire(HasAnimationCompleteHandlers source, Object sender) { AnimationCompleteEvent event = new AnimationCompleteEvent(sender); source.fireEvent(event); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/event/AnimationCompleteHandler.java ================================================ package org.dashbuilder.renderer.chartjs.lib.event; import com.google.gwt.event.shared.EventHandler; /** * Handler interface for handling {@link AnimationCompleteEvent} */ public interface AnimationCompleteHandler extends EventHandler{ /** * Method will be invoked when animation is complete * @param event : object contains reference to the instance of chart */ public void onAnimationComplete(AnimationCompleteEvent event); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/event/DataSelectionEvent.java ================================================ package org.dashbuilder.renderer.chartjs.lib.event; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONValue; import org.dashbuilder.renderer.chartjs.lib.data.Series; import java.util.LinkedList; import java.util.List; public class DataSelectionEvent extends GwtEvent { private static Type TYPE = new Type(); private Object sender; private LinkedList series; protected DataSelectionEvent(Object sender){ this.sender = sender; } public Object getSender(){ return sender; } @Override public com.google.gwt.event.shared.GwtEvent.Type getAssociatedType() { return TYPE; } public static Type getType(){ return TYPE; } @Override protected void dispatch(DataSelectionHandler handler) { handler.onDataSelected(this); } public static void fire(HasDataSelectionEventHandlers source, Object sender, JavaScriptObject data) { DataSelectionEvent event = new DataSelectionEvent(sender); JSONObject array = new JSONObject(data); event.series = new LinkedList(); for(String key : array.keySet()){ JSONObject obj = array.get(key).isObject(); if(obj != null){ Series series1 = JavaScriptObject.createObject().cast(); series1.setValue(obj.get("value").isNumber().doubleValue()); series1.setColor(obj.get("fillColor").isString().stringValue()); event.series.add(series1); } } source.fireEvent(event); } public List getSeries(){ return series; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/event/DataSelectionHandler.java ================================================ package org.dashbuilder.renderer.chartjs.lib.event; import com.google.gwt.event.shared.EventHandler; /** * Handler interface for handling {@link org.dashbuilder.renderer.chartjs.lib.event.AnimationCompleteEvent} */ public interface DataSelectionHandler extends EventHandler{ /** * Method will be invoked when animation is complete * @param event : object contains reference to the instance of chart */ public void onDataSelected(DataSelectionEvent event); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/event/HasAnimationCompleteHandlers.java ================================================ package org.dashbuilder.renderer.chartjs.lib.event; import com.google.gwt.event.shared.HasHandlers; /** * Interface describe methods required for adding new handlers of {@link AnimationCompleteEvent} */ public interface HasAnimationCompleteHandlers extends HasHandlers{ /** * Add {@link AnimationCompleteEvent} handler to widget. * @param handler */ public void addAnimationCompleteHandler(AnimationCompleteHandler handler); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/event/HasDataSelectionEventHandlers.java ================================================ package org.dashbuilder.renderer.chartjs.lib.event; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.HasHandlers; /** * Interface describe methods required for adding new handlers of {@link org.dashbuilder.renderer.chartjs.lib.event.AnimationCompleteEvent} */ public interface HasDataSelectionEventHandlers extends HasHandlers{ /** * Add {@link org.dashbuilder.renderer.chartjs.lib.event.AnimationCompleteEvent} handler to widget. * @param handler */ public HandlerRegistration addDataSelectionHandler(DataSelectionHandler handler); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/AnimationCallback.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; /** * Callback used to handle animation state changes for charts */ public interface AnimationCallback { /** * Method will be invoked during animation in progress * @param progress - from 0 to 1 */ public void onProgress(double progress); /** * Method will be invoked when animation complete */ public void onAnimationComplete(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/ChartOption.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; import com.google.gwt.core.client.JavaScriptObject; /** * Simple container for chart options */ public class ChartOption extends JavaScriptObject{ protected ChartOption(){ super(); } public static ChartOption get(){ return JavaScriptObject.createObject().cast(); } public final native void setProperty(String key, Object value)/*-{ this[key] = value; }-*/; public final native void clearProperty(String key)/*-{ this[key] = null; }-*/; public final native void appendTo(JavaScriptObject parent)/*-{ for(var key in this) parent[key]=this[key]; }-*/; public final native void setArrayProperty(String key, Object[] value)/*-{ this[key] = value; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/HasAnimation.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; /** * Enum contains types of easing of chart animation */ public interface HasAnimation{ final String ANIMATION = "animation"; final String ANIMATION_STEPS = "animationSteps"; final String ANIMATION_EASING = "animationEasing"; /** * Specify should chart be animated or not * Default value is true * @param enabled */ public void setAnimationEnabled(boolean enabled); /** * Particularly specify quality of animation * Default value is 60 * @param steps */ public void setAnimationSteps(int steps); /** * Specify animation easing * Default value is {@link Type#EASE_OUT_QUART} * @param type */ public void setAnimationType(Type type); /** * Add animation callback to handle animation state changes * @param callback */ public void addAnimationCallback(AnimationCallback callback); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/HasScale.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; import com.google.gwt.dom.client.Style; public interface HasScale { final String SHOWSCALE = "showScale"; final String SCALEOVERRIDE = "scaleOverride"; final String SCALESTEPS = "scaleSteps"; final String SCALESTEPWIDTH = "scaleStepWidth"; final String SCALESTARTVALUE = "scaleStartValue"; final String SCALELINECOLOR = "scaleLineColor"; final String SCALELINEWIDTH = "scaleLineWidth"; final String SCALESHOWLABELS = "scaleShowLabels"; final String SCALELABEL = "scaleLabel"; final String SCALEINTEGERSONLY = "scaleIntegersOnly"; final String SCALEBEGINATZERO = "scaleBeginAtZero"; final String SCALEFONTFAMILY = "scaleFontFamily"; final String SCALEFONTSIZE = "scaleFontSize"; final String SCALEFONTSTYLE = "scaleFontStyle"; final String SCALEFONTCOLOR = "scaleFontColor"; /** * Default true */ public void showScale(boolean scale); /** * Default false */ public void setScaleOverride(boolean override); /** * Scale steps * Default null */ public void setScaleSteps(int steps); /** * Default null */ public void setScaleStepWidth(int width); /** * Double */ public void setScaleStartValue(double startValue); /** * */ public void setScaleLineColor(String color); /** * Default 1 */ public void setScaleLineWidth(int pixelWidth); /** * true */ public void setScaleShowLabels(boolean showLabels); /** * Default "<%=value%>" */ public void setScaleLabel(String template); /** * Default true */ public void setScaleIntegersOnly(boolean only); /** * Default false */ public void setScaleBeginAtZero(boolean beginAtZero); /** * Default "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" */ public void setScaleFontFamily(String fontFamily); /** * Default 12 */ public void setScaleFontSize(int size); /** * Default normal */ public void setScaleFontStyle(Style.FontStyle style); /** * Default #666 */ public void setScaleFontColor(String color); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/HasTooltip.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.Event; /** * Interface describes options available for configuring tooltips for Chart */ public interface HasTooltip { final String SHOWTOOLTIPS = "showTooltips"; final String TOOLTIPEVENTS = "tooltipEvents"; final String TOOLTIPFILLCOLOR = "tooltipFillColor"; final String TOOLTIPFONTFAMILY = "tooltipFontFamily"; final String TOOLTIPFONTSIZE = "tooltipFontSize"; final String TOOLTIPFONTSTYLE = "tooltipFontStyle"; final String TOOLTIPFONTCOLOR = "tooltipFontColor"; final String TOOLTIPTITLEFONTFAMILY = "tooltipTitleFontFamily"; final String TOOLTIPTITLEFONTSIZE = "tooltipTitleFontSize"; final String TOOLTIPTITLEFONTSTYLE = "tooltipTitleFontStyle"; final String TOOLTIPTITLEFONTCOLOR = "tooltipTitleFontColor"; final String TOOLTIPYPADDING = "tooltipYPadding"; final String TOOLTIPXPADDING = "tooltipXPadding"; final String TOOLTIPCARETSIZE = "tooltipCaretSize"; final String TOOLTIPCORNERRADIUS = "tooltipCornerRadius"; final String TOOLTIPXOFFSET = "tooltipXOffset"; final String TOOLTIPTEMPLATE = "tooltipTemplate"; final String MULTITOOLTIPTEMPLATE = "multiTooltipTemplate"; /** * Specify event on which tooltip should be shown * By default {@link com.google.gwt.user.client.Event#ONMOUSEMOVE}, * {@link com.google.gwt.user.client.Event#ONTOUCHSTART}, * {@link com.google.gwt.user.client.Event#ONTOUCHMOVE} * */ public void setTooltipEvents(Event...events); /** * Specify tooltip background color in String representation of CSS property (like red or #FFFFFF or rgb(0,0,0) etc) * * Default rgba(0,0,0,.8) * @param color */ public void setTooltipFillColor(String color); /** * Indicates should tooltips been shown or not * * Default value is true * @param show */ public void showTooltips(boolean show); /** * Specify font family which will be used for label * Default one "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" */ public void setTooltipFontFamily(String fontFamily); /** * Specify font-size of tooltip label * @param fontSize */ public void setTooltipFontSize(int fontSize); /** * Default is {@link com.google.gwt.dom.client.Style.FontStyle#NORMAL} * @param fontStyle */ public void setTooltipFontStyle(Style.FontStyle fontStyle); /** * Color of tooltip font * Default is #FFF * @param color */ public void setTooltipFontColor(String color); /** * Font-family for tooltip title * * Default one is "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" * @param fontFamily */ public void setTooltipTitleFontFamily(String fontFamily); /** * * * Default 14 * @param size */ public void setTooltipTitleFontSize(int size); /** * Default is {@link com.google.gwt.dom.client.Style.FontStyle#FONT_WEIGHT_BOLD} * @param style */ public void setTooltipTitleFontStyle(Style.FontStyle style); /** * * Default is #fff * @param color */ public void setTooltipTitleFontColor(String color); /** * Default is 6 * @param padding */ public void setTooltipYPadding(int padding); /** * Default is 6 * @param padding */ public void setTooltipXPadding(int padding); /** * * Default is 6 * @param radius */ public void setCornerRadius(int radius); /** * Default 8 * @param size */ public void setTooltipCaretSize(int size); /** * Default 10 * @param offset */ public void setTooltipXOffset(int offset); /** * Default "<%if (label){%><%=label%>: <%}%><%= value %>" * @param template */ public void setTooltipTemplate(String template); /** * Default "<%= value %>" * @param template */ public void setMultiTooltipTemplate(String template); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/IsResponsive.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; public interface IsResponsive { final String RESPONSIVE = "responsive"; final String MAINTAIN_ASPECT_RATIO = "maintainAspectRatio"; public void setResponsive(boolean responsive); public void setMaintainAspectRatio(boolean aspectRatio); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/LegendOption.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; import com.google.gwt.core.client.JavaScriptObject; public class LegendOption extends ChartOption{ protected LegendOption(){ super(); } public static LegendOption get(){ return JavaScriptObject.createObject().cast(); } /** * Template String of legend widget. * For example

    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
* @param template */ public final native void setLegendTemplate(String template)/*-{ this.legendTemplate = template; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/options/Type.java ================================================ package org.dashbuilder.renderer.chartjs.lib.options; public enum Type { LINEAR("linear"), EASE_IN_QUAD("easeInQuad"), EASE_OUT_QUAD("easeOutQuad"), EASE_IN_OUT_QUAD("easeInOutQuad"), EASE_IN_CUBIC("easeInCubic"), EASE_OUT_CUBIC("easeOutCubic"), EASE_IN_OUT_CUBIC("easeInOutCubic"), EASE_IN_QUART("easeInQuart"), EASE_OUT_QUART("easeOutQuart"), EASE_IN_OUT_QUART("easeInOutQuart"), EASE_IN_QUINT("easeInQuint"), EASE_OUT_QUINT("easeOutQuint"), EASE_IN_OUT_QUINT("easeInOutQuint"), EASE_IN_SINE("easeInSine"), EASE_OUT_SINE("easeOutSine"), EASE_IN_OUT_SINE("easeInOutSine"), EASE_IN_EXPO("easeInExpo"), EASE_OUT_EXPO("easeOutExpo"), EASE_IN_OUT_EXPO("easeInOutExpo"), EASE_IN_CIRC("easeInCirc"), EASE_OUT_CIRC("easeOutCirc"), EASE_IN_OUT_CIRC("easeInOutCirc"), EASE_IN_BACK("easeInBack"), EASE_OUT_BACK("easeOutBack"), EASE_IN_OUT_BACK("easeInOutBack"), EASE_IN_BOUNCE("easeInBounce"), EASE_OUT_BOUNCE("easeOutBounce"), EASE_IN_OUT_BOUNCE("easeInOutBounce"); private String value; private Type(String value){ this.value = value; } /** * @return - javascript name of easing function (used in native chart.js code) */ public String getValue(){ return value; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/resources/ChartStyle.java ================================================ package org.dashbuilder.renderer.chartjs.lib.resources; import com.google.gwt.resources.client.CssResource; public interface ChartStyle extends CssResource{ /** * Style for chart area (applied to div wrapper of canvas element) * @return */ String chart(); /** * Style of default series * @return */ String defaultSeries(); String series1(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/resources/Resources.java ================================================ package org.dashbuilder.renderer.chartjs.lib.resources; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.TextResource; /** * Class contains resources required for chart library */ public interface Resources extends ClientBundle{ /** * Contains text representation of native chart.js code */ @Source("js/chart.min.js") TextResource chartJsSource(); /** * Default style required for chart styling */ @Source("js/chart.css") ChartStyle chartStyle(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/lib/resources/js/chart.css ================================================ @CHARSET "UTF-8"; .chart { display: inline-block; } .chart .defaultSeries { } .chart .series1 { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/java/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.chartjs.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface ChartJsDisplayerConstants extends Messages { public static final ChartJsDisplayerConstants INSTANCE = GWT.create( ChartJsDisplayerConstants.class ); String common_Categories(); String common_Series(); String common_Values(); String common_Value(); String common_Locations(); String common_Rows(); String common_Columns(); String common_noData(); String chartjsDisplayer_resetAnchor(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/ChartJsRenderer.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categories common_Series=Series common_Values=Values common_Value=Value common_Locations=Locations common_Rows=Rows common_Columns=Columns common_noData=No data chartjsDisplayer_resetAnchor=reset ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants_de.properties ================================================ common_Categories=Kategorien common_Series=Serien common_Values=Werte common_Value=Wert common_Locations=Speicherorte common_Rows=Reihen common_Columns=Spalten common_noData=Keine Daten chartjsDisplayer_resetAnchor=zurücksetzen ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categorías common_Series=Serie common_Values=Valores common_Value=Valor common_Locations=Ubicaciones common_Rows=Filas common_Columns=Columnas common_noData=No hay datos chartjsDisplayer_resetAnchor=restablecer ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Catégories common_Series=Séries common_Values=Valeurs common_Value=Valeur common_Locations=Sites common_Rows=Lignes common_Columns=Colonnes common_noData=Aucune donnée chartjsDisplayer_resetAnchor=réinitialiser ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categorie common_Series=Serie common_Values=Valori common_Value=Valore common_Locations=Posizioni common_Rows=Righe common_Columns=Colonne common_noData=Nessun dato chartjsDisplayer_resetAnchor=reset ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=カテゴリ common_Series=シリーズ common_Values=値 common_Value=値 common_Locations=場所 common_Rows=行 common_Columns=カラム common_noData=データなし chartjsDisplayer_resetAnchor=リセット ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants_pt_BR.properties ================================================ common_Categories=Categorias common_Series=Séries common_Values=Valores common_Value=Valor common_Locations=Locais common_Rows=Linhas common_Columns=Colunas common_noData=Nenhum dado chartjsDisplayer_resetAnchor=reiniciar ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-chartjs/src/main/resources/org/dashbuilder/renderer/chartjs/resources/i18n/ChartJsDisplayerConstants_zh_CN.properties ================================================ common_Categories=类别 common_Series=序列 common_Values=值 common_Value=值 common_Locations=位置 common_Rows=行 common_Columns=列 common_noData=没有数据 chartjsDisplayer_resetAnchor=重置 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-renderers 7.75.0-SNAPSHOT dashbuilder-renderer-default jar Dashbuilder Default Renderer Dashbuilder Default Renderer org.jboss.errai errai-common org.jboss.errai errai-ioc org.jboss.errai errai-ui org.jboss.errai errai-cdi-server com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 org.gwtbootstrap3 gwtbootstrap3-extras org.uberfire uberfire-client-all org.uberfire uberfire-api org.uberfire uberfire-client-api org.dashbuilder dashbuilder-common-client org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-dataset-shared org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-client org.uberfire uberfire-widgets-commons org.uberfire uberfire-widgets-table org.uberfire uberfire-testing-utils test org.kie.soup kie-soup-dataset-api test-jar test org.dashbuilder dashbuilder-dataset-client test-jar test org.dashbuilder dashbuilder-displayer-client test-jar test com.google.gwt.gwtmockito gwtmockito test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/DefaultRenderer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.AbstractRendererLibrary; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.renderer.client.external.ExternalComponentDisplayer; import org.dashbuilder.renderer.client.metric.MetricDisplayer; import org.dashbuilder.renderer.client.selector.SelectorDisplayer; import org.dashbuilder.renderer.client.selector.SelectorDropDownDisplayer; import org.dashbuilder.renderer.client.selector.SelectorLabelSetDisplayer; import org.dashbuilder.renderer.client.selector.SelectorSliderDisplayer; import org.dashbuilder.renderer.client.table.TableDisplayer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import static org.dashbuilder.displayer.DisplayerType.*; import static org.dashbuilder.displayer.DisplayerSubType.*; /** * Default renderer */ @ApplicationScoped public class DefaultRenderer extends AbstractRendererLibrary { public static final String UUID = "default"; @Inject protected SyncBeanManager beanManager; @PostConstruct private void init() { publishJsFunctions(); } @Override public String getUUID() { return UUID; } @Override public String getName() { return "GWT Core"; } @Override public boolean isDefault(DisplayerType type) { return TABLE.equals(type) || SELECTOR.equals(type) || METRIC.equals(type) || EXTERNAL_COMPONENT.equals(type); } @Override public List getSupportedTypes() { return Arrays.asList( TABLE, SELECTOR, METRIC, EXTERNAL_COMPONENT); } @Override public List getSupportedSubtypes(DisplayerType displayerType) { switch (displayerType) { case METRIC: return Arrays.asList(METRIC_CARD, METRIC_CARD2, METRIC_QUOTA, METRIC_PLAIN_TEXT); case SELECTOR: return Arrays.asList(SELECTOR_DROPDOWN, SELECTOR_LABELS, SELECTOR_SLIDER); default: return Collections.emptyList(); } } @Override public Displayer lookupDisplayer(DisplayerSettings displayerSettings) { DisplayerType type = displayerSettings.getType(); DisplayerSubType subtype = displayerSettings.getSubtype(); if (TABLE.equals(type)) { return beanManager.lookupBean(TableDisplayer.class).newInstance(); } if (SELECTOR.equals(type)) { if (SELECTOR_DROPDOWN.equals(subtype)) { return beanManager.lookupBean(SelectorDropDownDisplayer.class).newInstance(); } if (SELECTOR_LABELS.equals(subtype)) { return beanManager.lookupBean(SelectorLabelSetDisplayer.class).newInstance(); } if (SELECTOR_SLIDER.equals(subtype)) { return beanManager.lookupBean(SelectorSliderDisplayer.class).newInstance(); } // Keep backward compatibility with 0.6 and prior versions return beanManager.lookupBean(SelectorDisplayer.class).newInstance(); } if (METRIC.equals(type)) { MetricDisplayer displayer = beanManager.lookupBean(MetricDisplayer.class).newInstance(); _metricDisplayerMap.put(displayer.getView().getUniqueId(), displayer); return displayer; } if (EXTERNAL_COMPONENT.equals(type)) { return beanManager.lookupBean(ExternalComponentDisplayer.class).newInstance(); } return null; } private native void publishJsFunctions() /*-{ $wnd.metricDisplayerDoFilter = $entry(@org.dashbuilder.renderer.client.DefaultRenderer::metricDisplayerDoFilter(Ljava/lang/String;)); }-*/; protected static Map _metricDisplayerMap = new HashMap<>(); public static void metricDisplayerDoFilter(String displayerId) { MetricDisplayer displayer = _metricDisplayerMap.get(displayerId); if (displayer != null) { displayer.updateFilter(); } } public static void closeDisplayer(String displayerId) { _metricDisplayerMap.remove(displayerId); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/external/ExternalComponentDisplayer.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.external; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.DomGlobal; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.common.client.widgets.FilterLabel; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.AbstractErraiDisplayer; import org.dashbuilder.displayer.client.widgets.ExternalComponentPresenter; import org.dashbuilder.displayer.external.ExternalColumn; import org.dashbuilder.displayer.external.ExternalColumnSettings; import org.dashbuilder.displayer.external.ExternalComponentMessage; import org.dashbuilder.displayer.external.ExternalComponentMessageHelper; import org.dashbuilder.displayer.external.ExternalDataSet; import org.dashbuilder.displayer.external.ExternalFilterRequest; @Dependent public class ExternalComponentDisplayer extends AbstractErraiDisplayer { public interface View extends AbstractErraiDisplayer.View { void setSize(int chartWidth, int chartHeight); void setMargin(int chartMarginTop, int chartMarginRight, int chartMarginBottom, int chartMarginLeft); void setFilterLabelSet(FilterLabelSet widget); } @Inject View view; @Inject ExternalComponentPresenter externalComponentPresenter; @Inject FilterLabelSet filterLabelSet; @Inject ExternalComponentMessageHelper messageHelper; private String componentId; @Override public View getView() { return view; } @PostConstruct public void init() { view.init(this); view.setFilterLabelSet(filterLabelSet); this.filterLabelSet.setOnClearAllCommand(this::onFilterClearAll); externalComponentPresenter.setFilterConsumer(this::receiveFilterRequest); } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints().setGroupAllowed(true) .setGroupRequired(false) .setExtraColumnsAllowed(true) .setGroupsTitle("Groups") .setColumnsTitle("Columns"); return new DisplayerConstraints(lookupConstraints).supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.EXTERNAL_COMPONENT_ID) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeGroupDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP); } @Override protected void createVisualization() { ExternalComponentMessage init = initMessage(); externalComponentPresenter.sendMessage(init); updateVisualization(); } @Override protected void updateVisualization() { String currentComponentId = displayerSettings.getComponentId(); if (currentComponentId != null && !currentComponentId.equals(componentId)) { componentId = currentComponentId; String partitionId = displayerSettings.getComponentPartition(); if (partitionId != null) { externalComponentPresenter.withComponent(componentId, partitionId); } else { externalComponentPresenter.withComponent(componentId); } } ExternalComponentMessage message = dataSetMessage(); externalComponentPresenter.sendMessage(message); view.setSize(displayerSettings.getChartWidth(), displayerSettings.getChartHeight()); view.setMargin(displayerSettings.getChartMarginTop(), displayerSettings.getChartMarginRight(), displayerSettings.getChartMarginBottom(), displayerSettings.getChartMarginLeft()); updateFilterStatus(); } private ExternalComponentMessage dataSetMessage() { Map componentProperties = new HashMap<>(displayerSettings.getComponentProperties()); ExternalDataSet ds = ExternalDataSet.of(buildColumns(), buildData(dataSet)); return messageHelper.newDataSetMessage(ds, componentProperties); } private ExternalComponentMessage initMessage() { Map componentProperties = new HashMap<>(displayerSettings.getComponentProperties()); return messageHelper.newInitMessage(componentProperties); } private ExternalColumn[] buildColumns() { return dataSet.getColumns() .stream() .map(this::buildExternalColumn) .toArray(ExternalColumn[]::new); } public ExternalComponentPresenter getExternalComponentPresenter() { return externalComponentPresenter; } public String[][] buildData(DataSet ds) { List columns = ds.getColumns(); int rows = columns.get(0).getValues().size(); int cols = columns.size(); String[][] result = new String[rows][]; for (int i = 0; i < rows; i++) { String[] line = new String[cols]; for (int j = 0; j < cols; j++) { line[j] = getEvaluatedValue(ds, i, j); } result[i] = line; } return result; } @Override protected void afterClose() { super.afterClose(); externalComponentPresenter.destroy(); } protected String columnValueToString(Object mightBeNull) { return mightBeNull == null ? "" : mightBeNull.toString(); } protected ExternalColumn buildExternalColumn(DataColumn cl) { ColumnSettings clSettings = displayerSettings.getColumnSettings(cl); ExternalColumnSettings settings = ExternalColumnSettings.of(clSettings.getColumnId(), clSettings.getColumnName(), clSettings.getValueExpression(), clSettings.getEmptyTemplate(), clSettings.getValuePattern()); return ExternalColumn.of(cl.getId(), cl.getColumnType().name(), settings); } protected void updateFilterStatus() { filterLabelSet.clear(); Set columnFilters = filterColumns(); if (displayerSettings.isFilterEnabled() && !columnFilters.isEmpty()) { for (String columnId : columnFilters) { List selectedValues = filterIntervals(columnId); DataColumn column = dataSet.getColumnById(columnId); for (Interval interval : selectedValues) { String formattedValue = formatInterval(interval, column); FilterLabel filterLabel = filterLabelSet.addLabel(formattedValue); filterLabel.setOnRemoveCommand(() -> onFilterLabelRemoved(columnId, interval.getIndex())); } } } } protected void onFilterLabelRemoved(String columnId, int row) { super.filterUpdate(columnId, row); if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } protected void onFilterClearAll() { super.filterReset(); if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } private void receiveFilterRequest(ExternalFilterRequest filterRequest) { if (displayerSettings.isFilterEnabled()) { if (filterRequest.isReset()) { super.filterReset(); } else { DataColumn column = dataSet.getColumnByIndex(filterRequest.getColumn()); super.filterUpdate(column.getId(), filterRequest.getRow()); } updateFilterStatus(); } } private String getEvaluatedValue(DataSet ds, int i, int j) { String value = columnValueToString(ds.getValueAt(i, j)); try { String columnId = ds.getColumnByIndex(j).getId(); ColumnSettings settings = displayerSettings.getColumnSettings(columnId); String expression = settings.getValueExpression(); if (!StringUtils.isBlank(expression)) { return getEvaluator().evalExpression(value, expression); } } catch (Exception e) { DomGlobal.console.log("Error evaluating value at " + i + "," + j); } return value; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/external/ExternalComponentDisplayerView.html ================================================
================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/external/ExternalComponentDisplayerView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.external; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.CSSProperties.HeightUnionType; import elemental2.dom.CSSProperties.MarginUnionType; import elemental2.dom.CSSProperties.WidthUnionType; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import jsinterop.base.Js; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.displayer.client.AbstractErraiDisplayerView; import org.jboss.errai.common.client.dom.elemental2.Elemental2DomUtil; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class ExternalComponentDisplayerView extends AbstractErraiDisplayerView implements ExternalComponentDisplayer.View { @Inject @DataField HTMLDivElement externalComponentDisplayerRoot; @Inject Elemental2DomUtil domUtil; private HTMLElement externalComponentView; @Override public void init(ExternalComponentDisplayer presenter) { super.setPresenter(presenter); externalComponentView = Js.cast(presenter.getExternalComponentPresenter().getView().asWidget().getElement()); externalComponentDisplayerRoot.appendChild(externalComponentView); super.setVisualization(Js.cast(externalComponentDisplayerRoot)); } @Override public org.jboss.errai.common.client.dom.HTMLElement getElement() { return Js.cast(externalComponentDisplayerRoot); } @Override public void setSize(int chartWidth, int chartHeight) { externalComponentDisplayerRoot.style.width = WidthUnionType.of(asPixel(chartWidth)); externalComponentDisplayerRoot.style.height = HeightUnionType.of(asPixel(chartHeight)); } @Override public void setMargin(int top, int right, int bottom, int left) { externalComponentDisplayerRoot.style.margin = MarginUnionType.of(String.join(" ", asPixel(top), asPixel(right), asPixel(bottom), asPixel(left))); } private String asPixel(int value) { return value + "px"; } @Override public void setFilterLabelSet(FilterLabelSet widget) { org.jboss.errai.common.client.dom.HTMLElement element = widget.getElement(); element.getStyle().setProperty("position", "absolute"); element.getStyle().setProperty("z-index", "20"); externalComponentDisplayerRoot.insertBefore(Js.cast(element), externalComponentView); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/metric/MetricDisplayer.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.metric; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.StringTemplateBuilder; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.AbstractGwtDisplayer; import org.dashbuilder.displayer.client.resources.i18n.DisplayerConstants; import org.dashbuilder.displayer.client.widgets.sourcecode.HasHtmlTemplate; import org.dashbuilder.displayer.client.widgets.sourcecode.HasJsTemplate; @Dependent public class MetricDisplayer extends AbstractGwtDisplayer implements HasHtmlTemplate, HasJsTemplate { public interface View extends AbstractGwtDisplayer.View { String getUniqueId(); void setHtml(String html); void eval(String js); String getNoDataString(); String getColumnsTitle(); } public static final List TEMPLATE_KEYS = Arrays.asList("value.raw", "value", "title", "width", "height", "marginTop", "marginBottom", "marginRight", "marginLeft", "bgColor", "isFilterEnabled", "isFilterOn", "isEmpty", "doFilter"); public static final String DEFAULT_HTML_TEMPLATE = "
\n" + "

${title}

\n" + "

${value}

\n" + "
"; public static final String DEFAULT_JS_TEMPLATE = "if (${isFilterEnabled}) { \n" + " var filterOn = false;\n" + " ${this}.style.cursor=\"pointer\";\n" + "\n" + " ${this}.onmouseover = function() {\n" + " if (!filterOn) ${this}.style.backgroundColor = \"lightblue\";\n" + " };\n" + " ${this}.onmouseout = function() {\n" + " if (!filterOn) ${this}.style.backgroundColor = \"${bgColor}\";\n" + " };\n" + " ${this}.onclick = function() {\n" + " filterOn = !filterOn;\n" + " ${this}.style.backgroundColor = filterOn ? \"lightblue\" : \"${bgColor}\";\n" + " ${doFilter};\n" + " };\n" + "}"; protected View view; protected boolean filterOn = false; protected StringTemplateBuilder codeBuilder = new StringTemplateBuilder(); @Inject public MetricDisplayer(View view) { this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupAllowed(false) .setMaxColumns(1) .setMinColumns(1) .setFunctionRequired(true) .setExtraColumnsAllowed(false) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.METER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.HTML_GROUP); } @Override protected void createVisualization() { updateVisualization(); } @Override protected void updateVisualization() { String template = getHtmlTemplate(); String html = parseHtmlTemplate(template); view.setHtml(html); // Invoke the onDraw JS callback if defined String onDrawJs = getJsTemplate(); if (onDrawJs != null) { onDrawJs = parseJsTemplate(onDrawJs); view.eval(onDrawJs); } } public String parseHtmlTemplate(String str) { parseTemplate(str); // Replace the extra keys with a reference to a displayer-bounded identifier for (String key : codeBuilder.keys()) { if (!TEMPLATE_KEYS.contains(key)) { String id = getExtraKeyId(key); codeBuilder.replace(key, id); } } return codeBuilder.build(); } public String parseJsTemplate(String str) { parseTemplate(str); // Replace the extra keys with a reference to its DOM element for (String key : codeBuilder.keys()) { if (!TEMPLATE_KEYS.contains(key)) { String id = getExtraKeyId(key); codeBuilder.replace(key, "document.getElementById(\"" + id + "\")"); } } return codeBuilder.build(); } protected void parseTemplate(String template) { boolean isEmpty = dataSet.getRowCount() == 0; Double valueRaw = isEmpty ? 0 : (Double) dataSet.getValueAt(0, 0); String valueStr = isEmpty ? view.getNoDataString() : super.formatValue(0, 0); String title = displayerSettings.isTitleVisible() ? displayerSettings.getTitle() : ""; String bgcolor = displayerSettings.getChartBackgroundColor(); bgcolor = !StringUtils.isBlank(bgcolor) ? bgcolor : "white"; try { Integer.parseInt(bgcolor, 16); bgcolor = "#" + bgcolor; } catch (NumberFormatException e) { // No hash prefix needed } // Replace the core keys by their corresponding displayer settings. codeBuilder.setTemplate(template); codeBuilder.replace("value.raw", Double.toString(valueRaw)) .replace("value", valueStr != null ? valueStr : "") .replace("title", title) .replace("width", Integer.toString(displayerSettings.getChartWidth())) .replace("height", Integer.toString(displayerSettings.getChartHeight())) .replace("marginTop", Integer.toString(displayerSettings.getChartMarginTop())) .replace("marginBottom", Integer.toString(displayerSettings.getChartMarginBottom())) .replace("marginRight", Integer.toString(displayerSettings.getChartMarginRight())) .replace("marginLeft", Integer.toString(displayerSettings.getChartMarginLeft())) .replace("value.start", Long.toString(displayerSettings.getMeterStart())) .replace("value.warning", Long.toString(displayerSettings.getMeterWarning())) .replace("value.critical", Long.toString(displayerSettings.getMeterCritical())) .replace("value.end", Long.toString(displayerSettings.getMeterEnd())) .replace("bgColor", bgcolor) .replace("isFilterEnabled", Boolean.toString(isFilterEnabled())) .replace("isFilterOn", Boolean.toString(isFilterOn())) .replace("isEmpty", Boolean.toString(isEmpty)) .replace("doFilter", "window.metricDisplayerDoFilter('" + view.getUniqueId() + "')"); } public String getExtraKeyId(String key) { return view.getUniqueId() + "_" + key; } public boolean isFilterOn() { return filterOn; } public void setFilterOn(boolean on) { filterOn = on; } public boolean isFilterEnabled() { return displayerSettings.isFilterEnabled() && fetchFilter() != null; } public void updateFilter() { if (isFilterEnabled()) { if (filterOn) { filterReset(); } else { if (displayerSettings.isFilterEnabled()) { filterApply(); } } } } public DataSetFilter fetchFilter() { if (displayerSettings.getDataSetLookup() == null) { return null; } List filterOps = displayerSettings.getDataSetLookup().getOperationList(DataSetFilter.class); if (filterOps == null || filterOps.isEmpty()) { return null; } DataSetFilter filter = new DataSetFilter(); for (DataSetFilter filterOp : filterOps) { filter.getColumnFilterList().addAll(filterOp.getColumnFilterList()); } return filter; } public void filterApply() { DataSetFilter filter = fetchFilter(); if (displayerSettings.isFilterEnabled() && filter != null) { filterOn = true; super.filterApply(filter); } } @Override public void filterReset() { DataSetFilter filter = fetchFilter(); if (filterOn && filter != null) { filterOn = false; super.filterReset(); } } @Override public String getHtmlTemplate() { String template = displayerSettings.getHtmlTemplate(); if (StringUtils.isBlank(template)) { return DEFAULT_HTML_TEMPLATE; } return template; } @Override public Map getHtmlVariableMap() { return getCommonVariableMap(); } @Override public String getJsTemplate() { String template = displayerSettings.getJsTemplate(); if (StringUtils.isBlank(template)) { return DEFAULT_JS_TEMPLATE; } return template; } @Override public Map getJsVariableMap() { Map varMap = new HashMap<>(); // Append the user defined variables String template = getHtmlTemplate(); codeBuilder.setTemplate(template); for (String key : codeBuilder.keys()) { if (!TEMPLATE_KEYS.contains(key)) { String var = codeBuilder.asVar(key); varMap.put(var, DisplayerConstants.INSTANCE.userDefinedVariableDescription()); } } varMap.putAll(getCommonVariableMap()); varMap.put(asVar("doFilter"), DisplayerConstants.INSTANCE.doFilterVariableDescription()); return varMap; } protected Map getCommonVariableMap() { Map varMap = new HashMap<>(); varMap.put(asVar("value.raw"), DisplayerConstants.INSTANCE.valueRawVariableDescription()); varMap.put(asVar("value.start"), DisplayerConstants.INSTANCE.valueStartVariableDescription()); varMap.put(asVar("value.warning"), DisplayerConstants.INSTANCE.valueWarningVariableDescription()); varMap.put(asVar("value.critical"), DisplayerConstants.INSTANCE.valueCriticalVariableDescription()); varMap.put(asVar("value.end"), DisplayerConstants.INSTANCE.valueEndVariableDescription()); varMap.put(asVar("value"), DisplayerConstants.INSTANCE.valueVariableDescription()); varMap.put(asVar("title"), DisplayerConstants.INSTANCE.titleVariableDescription()); varMap.put(asVar("width"), DisplayerConstants.INSTANCE.widthVariableDescription()); varMap.put(asVar("height"), DisplayerConstants.INSTANCE.heightVariableDescription()); varMap.put(asVar("marginTop"), DisplayerConstants.INSTANCE.marginTopVariableDescription()); varMap.put(asVar("marginBottom"), DisplayerConstants.INSTANCE.marginBottomVariableDescription()); varMap.put(asVar("marginRight"), DisplayerConstants.INSTANCE.marginRightVariableDescription()); varMap.put(asVar("marginLeft"), DisplayerConstants.INSTANCE.marginLeftVariableDescription()); varMap.put(asVar("bgColor"), DisplayerConstants.INSTANCE.bgColorVariableDescription()); varMap.put(asVar("isFilterEnabled"), DisplayerConstants.INSTANCE.isFilterEnabledVariableDescription()); varMap.put(asVar("isFilterOn"), DisplayerConstants.INSTANCE.isFilterOnVariableDescription()); varMap.put(asVar("isEmpty"), DisplayerConstants.INSTANCE.isEmptyVariableDescription()); return varMap; } protected String asVar(String key) { return codeBuilder.asVar(key); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/metric/MetricView.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.metric; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.ScriptInjector; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTMLPanel; import org.dashbuilder.displayer.client.AbstractGwtDisplayerView; import org.dashbuilder.renderer.client.DefaultRenderer; import org.dashbuilder.renderer.client.resources.i18n.MetricConstants; @Dependent public class MetricView extends AbstractGwtDisplayerView implements MetricDisplayer.View { FlowPanel container = new FlowPanel(); HTMLPanel htmlPanel = null; String uniqueId = Document.get().createUniqueId(); @Override public void init(MetricDisplayer presenter) { container.getElement().setAttribute("id", uniqueId); super.setPresenter(presenter); super.setVisualization(container); } @Override public String getUniqueId() { return uniqueId; } @Override public void clear() { super.clear(); htmlPanel = null; container.clear(); DefaultRenderer.closeDisplayer(uniqueId); } @Override public void setHtml(String html) { htmlPanel = new HTMLPanel(html); container.clear(); container.add(htmlPanel); } @Override public String getNoDataString() { return MetricConstants.INSTANCE.metricDisplayer_noDataAvailable(); } @Override public void eval(String js) { Scheduler.get().scheduleFixedDelay(() -> { Element el = Document.get().getElementById(uniqueId); if (el != null) { ScriptInjector.fromString(js).setWindow(ScriptInjector.TOP_WINDOW).setRemoveTag(true).inject(); return false; } return true; }, 100); } @Override public String getColumnsTitle() { return MetricConstants.INSTANCE.metricDisplayer_columnsTitle(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/resources/i18n/CommonConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface CommonConstants extends Messages { public static final CommonConstants INSTANCE = GWT.create(CommonConstants.class); public String error(); public String error_settings_unset(); public String error_handler_unset(); public String error_dataset_notfound(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/resources/i18n/MetricConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface MetricConstants extends Messages { public static final MetricConstants INSTANCE = GWT.create( MetricConstants.class ); String metricDisplayer_noDataAvailable(); String metricDisplayer_columnsTitle(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface SelectorConstants extends Messages { SelectorConstants INSTANCE = GWT.create( SelectorConstants.class ); String selectorDisplayer_noDataAvailable(); String selectorDisplayer_groupsTitle(); String selectorDisplayer_columnsTitle(); String selectorDisplayer_select(); String selectorDisplayer_reset(); String selectorDisplayer_clearAll(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/resources/i18n/SliderConstants.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface SliderConstants extends Messages { SliderConstants INSTANCE = GWT.create(SliderConstants.class); String sliderTooltip(String from, String to); String sliderColumnName(); String textColumnsNotSupported(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/resources/i18n/TableConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface TableConstants extends Messages { TableConstants INSTANCE = GWT.create(TableConstants.class); String tableDisplayer_noDataAvailable(); String tableDisplayer_groupsTitle(); String tableDisplayer_columnsTitle(); String tableDisplayer_export_to_csv(); String tableDisplayer_export_to_xls(); String tableDisplayer_reset(); String tableDisplayer_export_no_data(); String tableDisplayer_export_too_many_rows(int rowNum, int limit); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/AbstractSelectorItemPresenter.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import org.uberfire.mvp.Command; public abstract class AbstractSelectorItemPresenter implements SelectorItemPresenter { protected Command onSelectCommand; protected Command onResetCommand; protected int id; protected boolean selected = false; public void init(int id, String value, String descr) { this.id = id; getView().setValue(value); getView().setDescription(descr); this.reset(); } public int getId() { return id; } public boolean isSelected() { return selected; } public void setOnSelectCommand(Command onSelectCommand) { this.onSelectCommand = onSelectCommand; } public void setOnResetCommand(Command onResetCommand) { this.onResetCommand = onResetCommand; } public void select() { selected = true; getView().select(); } public void reset() { selected = false; getView().reset(); } // View notifications public void onItemClick() { if (selected) { selected = false; getView().reset(); if (onResetCommand != null) { onResetCommand.execute(); } } else { selected = true; getView().select(); if (onSelectCommand != null) { onSelectCommand.execute(); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.AbstractGwtDisplayer; import org.dashbuilder.displayer.client.Displayer; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class SelectorDisplayer extends AbstractGwtDisplayer { public interface View extends AbstractGwtDisplayer.View { void showSelectHint(String column); void showResetHint(String column); void clearItems(); void addItem(String id, String value, boolean selected); String getSelectedId(); int getItemCount(); void setItemTitle(int id, String title); void setFilterEnabled(boolean enabled); String getGroupsTitle(); String getColumnsTitle(); } protected View view; protected boolean filterOn = false; public SelectorDisplayer() { this(new SelectorDisplayerView()); } @Inject public SelectorDisplayer(View view) { this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(-1) .setMinColumns(1) .setExtraColumnsAllowed(true) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute( DisplayerAttributeDef.TYPE ) .supportsAttribute( DisplayerAttributeGroupDef.COLUMNS_GROUP ) .supportsAttribute( DisplayerAttributeGroupDef.FILTER_GROUP ) .supportsAttribute( DisplayerAttributeGroupDef.REFRESH_GROUP ) .supportsAttribute( DisplayerAttributeGroupDef.GENERAL_GROUP ); } @Override protected void createVisualization() { view.setFilterEnabled(displayerSettings.isFilterEnabled()); updateVisualization(); } @Override protected void updateVisualization() { view.clearItems(); DataColumn firstColumn = dataSet.getColumnByIndex(0); String firstColumnId = firstColumn.getId(); ColumnSettings columnSettings = displayerSettings.getColumnSettings(firstColumn); String firstColumnName = columnSettings.getColumnName(); List currentFilter = super.filterIndexes(firstColumnId); // Add a selector hint according to the filter status if (currentFilter.isEmpty()) { view.showSelectHint(firstColumnName); } else { view.showResetHint(firstColumnName); } // Generate the list entries from the current data set for (int i = 0; i < dataSet.getRowCount(); i++) { Object obj = dataSet.getValueAt(i, 0); if (obj == null) { continue; } String value = super.formatValue(i, 0); boolean selected = currentFilter != null && currentFilter.contains(i); view.addItem(Integer.toString(i), value, selected); // Generate an option tooltip (only if extra data set columns are defined) int ncolumns = dataSet.getColumns().size(); if (ncolumns > 1) { StringBuilder out = new StringBuilder(); for (int j = 1; j < ncolumns; j++) { DataColumn extraColumn = dataSet.getColumnByIndex(j); columnSettings = displayerSettings.getColumnSettings(extraColumn); String extraColumnName = columnSettings.getColumnName(); Object extraValue = dataSet.getValueAt(i, j); if (extraValue != null) { out.append(j > 1 ? " " : ""); String formattedValue = super.formatValue(i, j); out.append(extraColumnName).append("=").append(formattedValue); } } view.setItemTitle(view.getItemCount()-1, out.toString()); } } } // View notifications public void onItemSelected() { // Reset the current filter (if any) DataColumn firstColumn = dataSet.getColumnByIndex(0); String firstColumnId = firstColumn.getId(); List currentFilter = filterIndexes(firstColumnId); if (currentFilter != null && !currentFilter.isEmpty()) { filterReset(); } ColumnSettings columnSettings = displayerSettings.getColumnSettings(firstColumn); String firstColumnName = columnSettings.getColumnName(); String selected = view.getSelectedId(); if (selected != null) { // Filter by the selected value (if any) filterUpdate(firstColumnId, Integer.parseInt(selected)); view.showResetHint(firstColumnName); } else { view.showSelectHint(firstColumnName); } } // KEEP IN SYNC THE CURRENT SELECTION WITH ANY EXTERNAL FILTER @Override public void onFilterEnabled(Displayer displayer, DataSetGroup groupOp) { String firstColumnId = dataSet.getColumnByIndex(0).getId(); List currentFilter = super.filterIndexes(firstColumnId); // If selector is active then ignore external filters. if (currentFilter.isEmpty()) { if (firstColumnId.equals(groupOp.getColumnGroup().getColumnId())) { columnSelectionMap.put(groupOp.getColumnGroup().getColumnId(), groupOp.getSelectedIntervalList()); } super.onFilterEnabled(displayer, groupOp); } } @Override public void onFilterReset(Displayer displayer, List groupOps) { String firstColumnId = dataSet.getColumnByIndex(0).getId(); List currentFilter = super.filterIndexes(firstColumnId); // If selector is active then ignore external filters. if (currentFilter.isEmpty()) { for (DataSetGroup groupOp : groupOps) { if (firstColumnId.equals(groupOp.getColumnGroup().getColumnId())) { columnSelectionMap.remove(groupOp.getColumnGroup().getColumnId()); } } super.onFilterReset(displayer, groupOps); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.OptionElement; import com.google.gwt.dom.client.SelectElement; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import org.dashbuilder.displayer.client.AbstractGwtDisplayerView; import org.dashbuilder.renderer.client.resources.i18n.SelectorConstants; import org.gwtbootstrap3.client.ui.ListBox; public class SelectorDisplayerView extends AbstractGwtDisplayerView implements SelectorDisplayer.View { protected ListBox listBox = new ListBox(); protected boolean hintEnabled = false; @Override public void init(SelectorDisplayer presenter) { super.setPresenter(presenter); super.setVisualization(listBox); } @Override public void showSelectHint(String column) { showHint("- " + SelectorConstants.INSTANCE.selectorDisplayer_select() + " " + column + " -"); } @Override public void showResetHint(String column) { showHint("- " + SelectorConstants.INSTANCE.selectorDisplayer_reset() + " " + column + " -"); } protected void showHint(String hint) { if (hintEnabled) { SelectElement selectElement = SelectElement.as(listBox.getElement()); NodeList options = selectElement.getOptions(); options.getItem(0).setText(hint); } else { listBox.addItem(hint); hintEnabled = true; } } @Override public void clearItems() { listBox.clear(); hintEnabled = false; } @Override public void addItem(String id, String value, boolean selected) { listBox.addItem(value, id); if (selected) { listBox.setSelectedIndex(listBox.getItemCount()-1); } } @Override public String getSelectedId() { if (hintEnabled && listBox.getSelectedIndex() == 0) { return null; } return listBox.getSelectedValue(); } @Override public int getItemCount() { return listBox.getItemCount() - (hintEnabled ? 1 : 0); } @Override public void setItemTitle(int index, String title) { SelectElement selectElement = SelectElement.as(listBox.getElement()); NodeList options = selectElement.getOptions(); OptionElement optionElement = options.getItem(index + (hintEnabled ? 1: 0)); if (optionElement != null) { optionElement.setTitle(title); } } @Override public void setFilterEnabled(boolean enabled) { if (enabled) { listBox.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { getPresenter().onItemSelected(); } }); } } @Override public String getGroupsTitle() { return SelectorConstants.INSTANCE.selectorDisplayer_groupsTitle(); } @Override public String getColumnsTitle() { return SelectorConstants.INSTANCE.selectorDisplayer_columnsTitle(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownDisplayer.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.GroupStrategy; import org.dashbuilder.dataset.sort.DataSetSort; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.AbstractErraiDisplayer; import org.jboss.errai.ioc.client.container.SyncBeanManager; @Dependent public class SelectorDropDownDisplayer extends AbstractErraiDisplayer { public interface View extends AbstractErraiDisplayer.View { void showTitle(String title); void margins(int top, int bottom, int left, int right); void setWidth(int width); void showSelectHint(String column, boolean multiple); void showResetHint(String column, boolean multiple); void showCurrentSelection(String text, String hint); void clearItems(); void addItem(SelectorDropDownItem item); String getGroupsTitle(); String getColumnsTitle(); } protected View view; protected boolean filterOn = false; protected boolean multipleSelections = false; protected SyncBeanManager beanManager; protected Set itemCollection = new HashSet<>(); @Inject public SelectorDropDownDisplayer(View view, SyncBeanManager beanManager) { this.beanManager = beanManager; this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public void close() { super.close(); clearItems(); } protected void clearItems() { view.clearItems(); for (SelectorDropDownItem item : itemCollection) { beanManager.destroyBean(item); } itemCollection.clear(); } protected void resetItems() { for (SelectorDropDownItem item : itemCollection) { item.reset(); } } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(-1) .setMinColumns(1) .setExtraColumnsAllowed(true) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeDef.TITLE) .supportsAttribute(DisplayerAttributeDef.TITLE_VISIBLE) .supportsAttribute(DisplayerAttributeGroupDef.SELECTOR_GROUP) .excludeAttribute(DisplayerAttributeGroupDef.SELECTOR_SHOW_INPUTS) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP); } @Override protected void beforeDataSetLookup() { // Make sure the drop down entries are sorted DataSetGroup group = dataSetHandler.getCurrentDataSetLookup().getLastGroupOp(); if (dataSetHandler.getCurrentDataSetLookup().getOperationList(DataSetSort.class).isEmpty() && group != null) { ColumnGroup column = group.getColumnGroup(); if (!GroupStrategy.FIXED.equals(column.getStrategy())) { dataSetHandler.sort(column.getSourceId(), SortOrder.ASCENDING); } } } @Override protected void createVisualization() { if (displayerSettings.isTitleVisible()) { view.showTitle(displayerSettings.getTitle()); } if (displayerSettings.getSelectorWidth() > 0) { view.setWidth(displayerSettings.getSelectorWidth()); } view.margins(displayerSettings.getChartMarginTop(), displayerSettings.getChartMarginBottom(), displayerSettings.getChartMarginLeft(), displayerSettings.getChartMarginRight()); multipleSelections = displayerSettings.isSelectorMultiple(); updateVisualization(); } @Override protected void updateVisualization() { DataColumn firstColumn = dataSet.getColumnByIndex(0); ColumnSettings columnSettings = displayerSettings.getColumnSettings(firstColumn); String firstColumnName = columnSettings.getColumnName(); List currentFilter = super.filterIndexes(firstColumn.getId()); clearItems(); // Generate the list entries from the current data set for (int i = 0; i < dataSet.getRowCount(); i++) { Object obj = dataSet.getValueAt(i, 0); if (obj == null) { continue; } String value = super.formatValue(i, 0); StringBuilder title = new StringBuilder(); int ncolumns = dataSet.getColumns().size(); if (ncolumns > 1) { for (int j = 1; j < ncolumns; j++) { DataColumn extraColumn = dataSet.getColumnByIndex(j); columnSettings = displayerSettings.getColumnSettings(extraColumn); String extraColumnName = columnSettings.getColumnName(); Object extraValue = dataSet.getValueAt(i, j); if (extraValue != null) { title.append(j > 1 ? " " : ""); String formattedValue = super.formatValue(i, j); title.append(extraColumnName).append("=").append(formattedValue); } } } final SelectorDropDownItem item = beanManager.lookupBean(SelectorDropDownItem.class).newInstance(); item.init(i, value, title.toString()); item.setSelectionIconVisible(multipleSelections); item.setOnSelectCommand(() -> onItemSelected(item)); item.setOnResetCommand(() -> onItemReset(item)); if (currentFilter.contains(i)) { item.select(); } else { item.reset(); } view.addItem(item); itemCollection.add(item); } // Add a selector hint according to the filter status if (currentFilter.isEmpty()) { view.showSelectHint(firstColumnName, multipleSelections); } else { view.showResetHint(firstColumnName, multipleSelections); } } public String getFirstColumnId() { DataColumn firstColumn = dataSet.getColumnByIndex(0); return firstColumn.getId(); } public String getFirstColumnName() { DataColumn firstColumn = dataSet.getColumnByIndex(0); ColumnSettings columnSettings = displayerSettings.getColumnSettings(firstColumn); return columnSettings.getColumnName(); } protected void onItemSelected(SelectorDropDownItem item) { if (displayerSettings.isFilterEnabled()) { String firstColumnId = getFirstColumnId(); String firstColumnName = getFirstColumnName(); // Reset current selection (if any) in single selection mode if (!multipleSelections) { List currentFilter = filterIndexes(firstColumnId); if (currentFilter != null && !currentFilter.isEmpty()) { resetItems(); super.filterReset(); item.select(); } } // Filter by the selected entry filterUpdate(firstColumnId, item.getId()); List currentFilter = super.filterIndexes(firstColumnId); showSelectedItems(currentFilter); view.showResetHint(firstColumnName, multipleSelections); } } protected void onItemReset(SelectorDropDownItem item) { if (displayerSettings.isFilterEnabled()) { String firstColumnId = getFirstColumnId(); String firstColumnName = getFirstColumnName(); filterUpdate(firstColumnId, item.getId()); List currentFilter = super.filterIndexes(firstColumnId); if (currentFilter.isEmpty()) { view.showSelectHint(firstColumnName, multipleSelections); } else { showSelectedItems(currentFilter); } } } protected void showSelectedItems(List currentFilter) { List itemList = new ArrayList<>(); for (Integer idx : currentFilter) { String value = super.formatValue(idx, 0); itemList.add(value); } int width = displayerSettings.getSelectorWidth(); String hint = formatItemList(itemList); String text = width > 0 ? formatItemList(itemList, width) : hint; view.showCurrentSelection(text, hint); } public String formatItemList(List itemList) { StringBuffer out = new StringBuffer(); for (String item : itemList) { if (out.length() > 0) { out.append(", "); } out.append(item); } return out.toString() + " "; } public String formatItemList(List itemList, int maxWidth) { StringBuffer out = new StringBuffer(); int charLength = 9; int availableChars = maxWidth / charLength; for (String item : itemList) { if (availableChars < 0) { out.append(" ..."); return out.toString(); } if (out.length() > 0) { availableChars -= 2; if (availableChars <= 0) { out.append(" ..."); return out.toString(); } else { out.append(", "); } } if (item.length() > availableChars) { out.append(item.substring(0, availableChars)).append("..."); return out.toString(); } else { availableChars -= item.length(); out.append(item); } } return out.toString() + " "; } void onResetSelections() { filterReset(); updateVisualization(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownDisplayerView.css ================================================ .selector-ddown-container { margin: 5px; } .selector-ddown-button { text-align: left; overflow: hidden; } .selector-ddown-text { float: left; overflow: hidden; } .selector-ddown-reset-anchor { margin-right: 10px; cursor: pointer; float: right; } .selector-ddown-caret { float: right; margin-top: 5px; margin-left: 10px; } .selector-ddown-menu { max-height: 252px; overflow-y: auto; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownDisplayerView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownDisplayerView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import javax.inject.Inject; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.ClickEvent; import org.dashbuilder.displayer.client.AbstractErraiDisplayerView; import org.dashbuilder.renderer.client.resources.i18n.SelectorConstants; import org.jboss.errai.common.client.dom.Anchor; import org.jboss.errai.common.client.dom.Button; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.common.client.dom.UnorderedList; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class SelectorDropDownDisplayerView extends AbstractErraiDisplayerView implements SelectorDropDownDisplayer.View { @Inject @DataField Div containerDiv; @Inject @DataField Span titleSpan; @Inject @DataField Div dropDownDiv; @Inject @DataField Button dropDownButton; @Inject @DataField Div dropDownText; @Inject @DataField UnorderedList resetMenu; @Inject @DataField UnorderedList dropDownMenu; @Inject @DataField Anchor resetAnchor; @Override public void init(SelectorDropDownDisplayer presenter) { super.setPresenter(presenter); super.setVisualization((Element) containerDiv); } @Override public void showTitle(String title) { titleSpan.setTextContent(title); } @Override public void margins(int top, int bottom, int left, int right) { containerDiv.getStyle().setProperty("margin-top", top + "px"); containerDiv.getStyle().setProperty("margin-bottom", bottom + "px"); containerDiv.getStyle().setProperty("margin-left", left + "px"); containerDiv.getStyle().setProperty("margin-right", right + "px"); } @Override public void setWidth(int width) { if (width > 0) { dropDownButton.getStyle().setProperty("width", width + "px"); dropDownMenu.getStyle().setProperty("width", width + "px"); resetMenu.getStyle().setProperty("width", width + "px"); dropDownText.getStyle().setProperty("max-width", (width - 30) + "px"); } else { dropDownButton.getStyle().removeProperty("width"); dropDownMenu.getStyle().removeProperty("width"); resetMenu.getStyle().removeProperty("width"); dropDownText.getStyle().removeProperty("max-width"); } } @Override public void showSelectHint(String column, boolean multiple) { String hint = "- " + SelectorConstants.INSTANCE.selectorDisplayer_select() + " " + column + " - "; dropDownText.setTextContent(hint); resetMenu.getStyle().setProperty("display", "none"); } @Override public void showResetHint(String column, boolean multiple) { String resetAction = multiple ? SelectorConstants.INSTANCE.selectorDisplayer_clearAll() : SelectorConstants.INSTANCE.selectorDisplayer_reset(); resetAnchor.setTextContent(resetAction); resetMenu.getStyle().removeProperty("display"); int n = dropDownMenu.getChildNodes().getLength() * 25; resetMenu.getStyle().setProperty("margin-top", (n > 250 ? 250 : n) + "px"); } @Override public void showCurrentSelection(String text, String hint) { dropDownText.setTextContent(text); dropDownButton.setTitle(hint); } @Override public void clearItems() { DOMUtil.removeAllChildren(dropDownMenu); } @Override public void addItem(SelectorDropDownItem item) { dropDownMenu.appendChild(item.getView().getElement()); } @Override public String getGroupsTitle() { return SelectorConstants.INSTANCE.selectorDisplayer_groupsTitle(); } @Override public String getColumnsTitle() { return SelectorConstants.INSTANCE.selectorDisplayer_columnsTitle(); } @EventHandler("resetAnchor") private void onResetClicked(ClickEvent event) { presenter.onResetSelections(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownItem.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class SelectorDropDownItem extends AbstractSelectorItemPresenter { public interface View extends SelectorItemView { void setSelectionIconVisible(boolean visible); } protected View view; @Inject public SelectorDropDownItem(View view) { this.view = view; this.view.init(this); } @Override public View getView() { return view; } public void setSelectionIconVisible(boolean selectionIconVisible) { view.setSelectionIconVisible(selectionIconVisible); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownItemView.css ================================================ .selector-dditem { cursor: pointer; } .selector-dditem-icon { margin-left: 5px; cursor: pointer; float: right; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownItemView.html ================================================
  • ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorDropDownItemView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import org.jboss.errai.common.client.dom.Anchor; import org.jboss.errai.common.client.dom.ListItem; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class SelectorDropDownItemView implements SelectorDropDownItem.View, IsElement { @Inject @DataField ListItem item; @Inject @DataField Anchor itemAnchor; @Inject @DataField Span itemText; @Inject @DataField Span itemIcon; SelectorDropDownItem presenter; boolean iconVisible = true; @Override public void init(SelectorDropDownItem presenter) { this.presenter = presenter; } @Override public void setValue(String value) { itemText.setTextContent(value); } @Override public void setDescription(String description) { item.setTitle(description); } @Override public void select() { item.setClassName("selector-dditem selected"); if (iconVisible) { itemIcon.getStyle().removeProperty("display"); } } @Override public void reset() { item.setClassName("selector-dditem"); itemIcon.getStyle().setProperty("display", "none"); } @Override public void setSelectionIconVisible(boolean visible) { iconVisible = visible; if (!iconVisible) { itemIcon.getStyle().setProperty("display", "none"); } } @EventHandler("itemAnchor") public void onItemClick(ClickEvent event) { presenter.onItemClick(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorItemPresenter.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import org.uberfire.mvp.Command; public interface SelectorItemPresenter { void init(int id, String value, String descr); int getId(); boolean isSelected(); void setOnSelectCommand(Command onSelectCommand); void setOnResetCommand(Command onResetCommand); void select(); void reset(); SelectorItemView getView(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorItemView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import org.uberfire.client.mvp.UberElement; public interface SelectorItemView

    extends UberElement

    { void setValue(String value); void setDescription(String description); void select(); void reset(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorLabelItem.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import javax.enterprise.context.Dependent; import javax.inject.Inject; @Dependent public class SelectorLabelItem extends AbstractSelectorItemPresenter { public interface View extends SelectorItemView { void setWidth(int percentage); } protected View view; @Inject public SelectorLabelItem(View view) { this.view = view; this.view.init(this); } @Override public View getView() { return view; } public void setWidth(int percentage) { if (percentage > 0 && percentage <= 100) { view.setWidth(percentage); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorLabelItemView.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorLabelItemView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import org.jboss.errai.common.client.dom.Button; import org.jboss.errai.common.client.dom.CSSStyleDeclaration; import org.jboss.errai.ui.client.local.api.IsElement; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class SelectorLabelItemView implements SelectorLabelItem.View, IsElement { @Inject @DataField Button item; SelectorLabelItem presenter; @Override public void init(SelectorLabelItem presenter) { this.presenter = presenter; } @Override public void setValue(String value) { item.setTextContent(value); // setTitle to make the whole value visible on mouse over when selector width is restricted and value is trimmed item.setTitle(value); } @Override public void setDescription(String description) { item.setTitle(description); } @Override public void setWidth(int percentage) { CSSStyleDeclaration style = item.getStyle(); style.setProperty("width", percentage + "%"); // Labels too long to fit into the button width will be trimmed and ended with "..." // Based on https://www.w3schools.com/cssref/css3_pr_text-overflow.asp style.setProperty("white-space","nowrap"); style.setProperty("overflow","hidden"); style.setProperty("text-overflow","ellipsis"); } @Override public void select() { item.setClassName("btn btn-primary"); } @Override public void reset() { item.setClassName("btn btn-default"); } @EventHandler("item") public void onItemClick(ClickEvent event) { presenter.onItemClick(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorLabelSetDisplayer.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.GroupStrategy; import org.dashbuilder.dataset.sort.DataSetSort; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.AbstractErraiDisplayer; import org.jboss.errai.ioc.client.container.SyncBeanManager; @Dependent public class SelectorLabelSetDisplayer extends AbstractErraiDisplayer { public interface View extends AbstractErraiDisplayer.View { void showTitle(String title); void setWidth(int width); void margins(int top, int bottom, int left, int right); void clearItems(); void addItem(SelectorLabelItem item); String getGroupsTitle(); String getColumnsTitle(); void noData(); } protected View view; protected boolean filterOn = false; protected boolean multipleSelections = false; protected SyncBeanManager beanManager; protected Set itemCollection = new HashSet<>(); @Inject public SelectorLabelSetDisplayer(View view, SyncBeanManager beanManager) { this.beanManager = beanManager; this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public void close() { super.close(); clearItems(); } protected void clearItems() { view.clearItems(); for (SelectorLabelItem item : itemCollection) { beanManager.destroyBean(item); } itemCollection.clear(); } protected void resetItems() { for (SelectorLabelItem item : itemCollection) { item.reset(); } } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(-1) .setMinColumns(1) .setExtraColumnsAllowed(true) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeDef.TITLE) .supportsAttribute(DisplayerAttributeDef.TITLE_VISIBLE) .supportsAttribute(DisplayerAttributeGroupDef.SELECTOR_GROUP) .excludeAttribute(DisplayerAttributeDef.SELECTOR_SHOW_INPUTS) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP); } @Override protected void beforeDataSetLookup() { // Make sure the drop down entries are sorted DataSetGroup group = dataSetHandler.getCurrentDataSetLookup().getLastGroupOp(); if (dataSetHandler.getCurrentDataSetLookup().getOperationList(DataSetSort.class).isEmpty() && group != null) { ColumnGroup column = group.getColumnGroup(); if (!GroupStrategy.FIXED.equals(column.getStrategy())) { dataSetHandler.sort(column.getSourceId(), SortOrder.ASCENDING); } } } @Override protected void createVisualization() { if (displayerSettings.isTitleVisible()) { view.showTitle(displayerSettings.getTitle()); } view.margins(displayerSettings.getChartMarginTop(), displayerSettings.getChartMarginBottom(), displayerSettings.getChartMarginLeft(), displayerSettings.getChartMarginRight()); multipleSelections = displayerSettings.isSelectorMultiple(); updateVisualization(); } @Override protected void updateVisualization() { clearItems(); if (dataSet.getRowCount() == 0) { view.noData(); } else { // Generate the list entries from the current data set for (int i = 0; i < dataSet.getRowCount(); i++) { Object obj = dataSet.getValueAt(i, 0); if (obj == null) { continue; } String value = super.formatValue(i, 0); StringBuilder title = new StringBuilder(); int ncolumns = dataSet.getColumns().size(); if (ncolumns > 1) { for (int j = 1; j < ncolumns; j++) { DataColumn extraColumn = dataSet.getColumnByIndex(j); ColumnSettings columnSettings = displayerSettings.getColumnSettings(extraColumn); String extraColumnName = columnSettings.getColumnName(); Object extraValue = dataSet.getValueAt(i, j); if (extraValue != null) { title.append(j > 1 ? " " : ""); String formattedValue = super.formatValue(i, j); title.append(extraColumnName).append("=").append(formattedValue); } } } final SelectorLabelItem item = beanManager.lookupBean(SelectorLabelItem.class).newInstance(); item.init(i, value, title.toString()); item.setOnSelectCommand(() -> onItemSelected(item)); item.setOnResetCommand(() -> onItemReset(item)); view.addItem(item); itemCollection.add(item); } // Set both the global and each item width if (displayerSettings.getSelectorWidth() > 0) { view.setWidth(displayerSettings.getSelectorWidth() + 100); int itemWidth = 85 / itemCollection.size(); for (SelectorLabelItem labelItem : itemCollection) { labelItem.setWidth(itemWidth); } } } } public String getFirstColumnId() { DataColumn firstColumn = dataSet.getColumnByIndex(0); return firstColumn.getId(); } void onItemSelected(SelectorLabelItem item) { if (displayerSettings.isFilterEnabled()) { String firstColumnId = getFirstColumnId(); // Reset current selection (if any) in single selection mode if (!multipleSelections) { List currentFilter = filterIndexes(firstColumnId); if (currentFilter != null && !currentFilter.isEmpty()) { resetItems(); super.filterReset(); item.select(); } } // Filter by the selected entry filterUpdate(firstColumnId, item.getId()); } } void onItemReset(SelectorLabelItem item) { if (displayerSettings.isFilterEnabled()) { String firstColumnId = getFirstColumnId(); filterUpdate(firstColumnId, item.getId()); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorLabelSetDisplayerView.html ================================================

    ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorLabelSetDisplayerView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import javax.inject.Inject; import com.google.gwt.dom.client.Element; import org.dashbuilder.displayer.client.AbstractErraiDisplayerView; import org.dashbuilder.renderer.client.resources.i18n.SelectorConstants; import org.jboss.errai.common.client.dom.DOMUtil; import org.jboss.errai.common.client.dom.Div; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.common.client.dom.Span; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated public class SelectorLabelSetDisplayerView extends AbstractErraiDisplayerView implements SelectorLabelSetDisplayer.View { @Inject @DataField Div containerDiv; @Inject @DataField Span titleSpan; @Inject @DataField Span noDataSpan; @Inject @DataField Div labelSetDiv; @Override public void init(SelectorLabelSetDisplayer presenter) { super.setPresenter(presenter); super.setVisualization((Element) containerDiv); } @Override public void showTitle(String title) { titleSpan.setTextContent(title); } @Override public void setWidth(int width) { containerDiv.getStyle().setProperty("width", width + "px"); } @Override public void margins(int top, int bottom, int left, int right) { containerDiv.getStyle().setProperty("margin-top", top + "px"); containerDiv.getStyle().setProperty("margin-bottom", bottom + "px"); containerDiv.getStyle().setProperty("margin-left", left + "px"); containerDiv.getStyle().setProperty("margin-right", right + "px"); } @Override public void clearItems() { DOMUtil.removeAllChildren(labelSetDiv); noDataSpan.setTextContent(""); } @Override public void addItem(SelectorLabelItem item) { HTMLElement element = item.getView().getElement(); element.getStyle().setProperty("margin", "3px"); labelSetDiv.appendChild(element); } @Override public void noData() { noDataSpan.setTextContent(SelectorConstants.INSTANCE.selectorDisplayer_noDataAvailable()); } @Override public String getGroupsTitle() { return SelectorConstants.INSTANCE.selectorDisplayer_groupsTitle(); } @Override public String getColumnsTitle() { return SelectorConstants.INSTANCE.selectorDisplayer_columnsTitle(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorSliderDisplayer.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import java.util.Date; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.dataset.impl.DataColumnImpl; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.AbstractGwtDisplayer; import org.dashbuilder.displayer.client.widgets.filter.DateParameterEditor; import org.dashbuilder.displayer.client.widgets.filter.NumberParameterEditor; @Dependent public class SelectorSliderDisplayer extends AbstractGwtDisplayer { public interface View extends AbstractGwtDisplayer.View { void showTitle(String title); void setWidth(int width); String getColumnsTitle(); void setSliderEnabled(boolean enabled); void showSlider(double min, double max, double step, double minSelected, double maxSelected); void showInputs(IsWidget minValueEditor, IsWidget maxValueEditor); void margins(int top, int bottom, int left, int right); String formatRange(String from, String to); void textColumnsNotSupported(); void noData(); } protected View view; protected DataColumn dataColumnMin; protected DataColumn dataColumnMax; protected double rangeMin = -1; protected double rangeMax = -1; protected double selectedMin = -1; protected double selectedMax = -1; protected DateParameterEditor minDateEditor; protected DateParameterEditor maxDateEditor; protected NumberParameterEditor minNumberEditor; protected NumberParameterEditor maxNumberEditor; @Inject public SelectorSliderDisplayer(View view, DateParameterEditor minDateEditor, DateParameterEditor maxDateEditor, NumberParameterEditor minNumberEditor, NumberParameterEditor maxNumberEditor) { this.view = view; this.view.init(this); this.minDateEditor = minDateEditor; this.maxDateEditor = maxDateEditor; this.minNumberEditor = minNumberEditor; this.maxNumberEditor = maxNumberEditor;; this.minDateEditor.setOnChangeCommand(this::onMinDateInputChange); this.minDateEditor.setOnFocusCommand(this::onMinDateInputFocus); this.minDateEditor.setOnBlurCommand(this::onMinDateInputBlur); this.maxDateEditor.setOnChangeCommand(this::onMaxDateInputChange); this.maxDateEditor.setOnFocusCommand(this::onMaxDateInputFocus); this.maxDateEditor.setOnBlurCommand(this::onMaxDateInputBlur); this.minNumberEditor.setOnChangeCommand(this::onMinNumberInputChange); this.maxNumberEditor.setOnChangeCommand(this::onMaxNumberInputChange); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { // A single a number or date column is required as the filter column used by the slider DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupAllowed(false) .setMaxColumns(2) .setMinColumns(1) .setFunctionRequired(false) .setExtraColumnsAllowed(false) .setColumnsTitle(view.getColumnsTitle()); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeDef.TITLE) .supportsAttribute(DisplayerAttributeDef.TITLE_VISIBLE) .supportsAttribute(DisplayerAttributeGroupDef.SELECTOR_GROUP) .excludeAttribute(DisplayerAttributeGroupDef.SELECTOR_MULTIPLE) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP); } @Override protected void beforeDataSetLookup() { DataSetGroup group = dataSetHandler.getCurrentDataSetLookup().getLastGroupOp(); if (group != null && (group.getAggregationFunctions().isEmpty() || group.getColumnGroup() != null || group.getGroupFunctions().size() < 2)) { group.setColumnGroup(null); GroupFunction minFunction = group.getGroupFunctions().get(0); minFunction.setFunction(AggregateFunctionType.MIN); GroupFunction maxFunction = minFunction.cloneInstance(); maxFunction.setFunction(AggregateFunctionType.MAX); group.addGroupFunction(maxFunction); } } @Override protected void createVisualization() { if (displayerSettings.isTitleVisible()) { view.showTitle(displayerSettings.getTitle()); } if (displayerSettings.getSelectorWidth() > 0) { view.setWidth(displayerSettings.getSelectorWidth()); } view.margins(displayerSettings.getChartMarginTop(), displayerSettings.getChartMarginBottom(), displayerSettings.getChartMarginLeft(), displayerSettings.getChartMarginRight()); updateVisualization(); } @Override protected void updateVisualization() { DataColumn minColumn = dataSet.getColumnByIndex(0); DataColumn maxColumn = dataSet.getColumnByIndex(1); Object minValue = minColumn.getValues().isEmpty() ? null : minColumn.getValues().get(0); Object maxValue = maxColumn.getValues().isEmpty() ? null : maxColumn.getValues().get(0); String minColumnId = minColumn.getId(); String maxColumnId = maxColumn.getId(); ColumnType columnType = minColumn.getColumnType(); dataColumnMin = new DataColumnImpl(minColumnId, columnType); dataColumnMax = new DataColumnImpl(maxColumnId, columnType); int inputsWidth = displayerSettings.getSelectorWidth(); inputsWidth = inputsWidth > 0 ? (inputsWidth/2) - 10 : -1; inputsWidth = inputsWidth > 100 ? 100 : inputsWidth; if (minValue == null || maxValue == null) { view.noData(); } else if (ColumnType.DATE.equals(columnType)) { rangeMin = ((Date) minValue).getTime(); rangeMax = ((Date) maxValue).getTime() + 1; selectedMin = selectedMin == -1 ? rangeMin : selectedMin; selectedMax = selectedMax == -1 ? rangeMax : selectedMax; view.showSlider(rangeMin, rangeMax, 1, selectedMin, selectedMax); if (displayerSettings.isSelectorInputsEnabled()) { minDateEditor.setValue((Date) minValue); maxDateEditor.setValue((Date) maxValue); minDateEditor.setWidth(inputsWidth); maxDateEditor.setWidth(inputsWidth); view.showInputs(minDateEditor, maxDateEditor); } } else if (ColumnType.NUMBER.equals(columnType)) { // Round to integer rangeMin = ((Number) minValue).intValue(); rangeMax = ((Number) maxValue).intValue() + 1; selectedMin = selectedMin == -1 ? rangeMin : selectedMin; selectedMax = selectedMax == -1 ? rangeMax : selectedMax; view.showSlider(rangeMin, rangeMax, 1, selectedMin, selectedMax); if (displayerSettings.isSelectorInputsEnabled()) { minNumberEditor.setValue((Number) minValue); maxNumberEditor.setValue((Number) maxValue); minNumberEditor.setWidth(inputsWidth); maxNumberEditor.setWidth(inputsWidth); view.showInputs(minNumberEditor, maxNumberEditor); } } else { view.textColumnsNotSupported(); } } public Object getSelectedMin() { if (selectedMin == -1) { return new Date((long) rangeMin); } if (ColumnType.DATE.equals(dataColumnMin.getColumnType())) { return new Date((long) selectedMin); } else if (ColumnType.NUMBER.equals(dataColumnMin.getColumnType())) { return (long) selectedMin; } else { return null; } } public Object getSelectedMax() { if (selectedMax == -1) { return new Date((long) rangeMax); } if (ColumnType.DATE.equals(dataColumnMax.getColumnType())) { return new Date((long) selectedMax); } else if (ColumnType.NUMBER.equals(dataColumnMax.getColumnType())) { return (long) selectedMax; } else { return null; } } // View callbacks void onSliderChange(double min, double max) { if (selectedMin != min || selectedMax != max) { selectedMin = min; selectedMax = max; DataSetFilter filter = new DataSetFilter(); CoreFunctionFilter columnFilter = new CoreFunctionFilter(); columnFilter.setColumnId(dataColumnMin.getId()); columnFilter.setType(CoreFunctionType.BETWEEN); filter.addFilterColumn(columnFilter); if (ColumnType.DATE.equals(dataColumnMin.getColumnType())) { Date dateFrom = new Date((long) min); Date dateTo = new Date((long) max); columnFilter.setParameters(dateFrom, dateTo); minDateEditor.setValue(dateFrom); maxDateEditor.setValue(dateTo); super.filterUpdate(filter); } else if (ColumnType.NUMBER.equals(dataColumnMin.getColumnType())) { columnFilter.setParameters(min, max); minNumberEditor.setValue(min); maxNumberEditor.setValue(max); super.filterUpdate(filter); } } } void onMinDateInputChange() { long min = minDateEditor.getValue().getTime(); double max = selectedMax != -1 ? selectedMax : rangeMax; this.onSliderChange(min, max); view.showSlider(rangeMin, rangeMax, 1, min, max); view.setSliderEnabled(true); } void onMinDateInputFocus() { view.setSliderEnabled(false); } void onMinDateInputBlur() { view.setSliderEnabled(true); } void onMaxDateInputChange() { double min = selectedMin != -1 ? selectedMin : rangeMin; long max = maxDateEditor.getValue().getTime(); this.onSliderChange(min, max); view.showSlider(rangeMin, rangeMax, 1, min, max); view.setSliderEnabled(true); } void onMaxDateInputFocus() { view.setSliderEnabled(false); } void onMaxDateInputBlur() { view.setSliderEnabled(true); } void onMinNumberInputChange() { double min = minNumberEditor.getValue().doubleValue(); double max = selectedMax != -1 ? selectedMax : rangeMax; this.onSliderChange(min, max); view.showSlider(rangeMin, rangeMax, 1, min, max); } void onMaxNumberInputChange() { double min = selectedMin != -1 ? selectedMin : rangeMin; double max = maxNumberEditor.getValue().doubleValue(); this.onSliderChange(min, max); view.showSlider(rangeMin, rangeMax, 1, min, max); } String formatRange(double min, double max) { String fromStr = this.formatValue(min, dataColumnMin); String toStr = this.formatValue(max, dataColumnMax); return view.formatRange(fromStr, toStr); } String formatValue(double val, DataColumn dataColumn) { if (ColumnType.DATE.equals(dataColumn.getColumnType())) { Date date = new Date((long) val); return super.formatValue(date, dataColumn); } else if (ColumnType.NUMBER.equals(dataColumn.getColumnType())) { return super.formatValue(val, dataColumn); } else { return Double.toString(val); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/selector/SelectorSliderDisplayerView.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.StyleInjector; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.displayer.client.AbstractGwtDisplayerView; import org.dashbuilder.renderer.client.resources.i18n.SelectorConstants; import org.dashbuilder.renderer.client.resources.i18n.SliderConstants; import org.gwtbootstrap3.client.ui.Label; import org.gwtbootstrap3.extras.slider.client.ui.Range; import org.gwtbootstrap3.extras.slider.client.ui.RangeSlider; import org.gwtbootstrap3.extras.slider.client.ui.base.constants.HandleType; import org.gwtbootstrap3.extras.slider.client.ui.base.constants.TooltipType; public class SelectorSliderDisplayerView extends AbstractGwtDisplayerView implements SelectorSliderDisplayer.View { FlowPanel container = new FlowPanel(); HTML header = new HTML(); FlowPanel body = new FlowPanel(); RangeSlider slider = new RangeSlider(); HorizontalPanel inputs = new HorizontalPanel(); FlowPanel error = new FlowPanel(); @Override public void init(SelectorSliderDisplayer presenter) { super.setPresenter(presenter); super.setVisualization(container); // Enlarge the tooltip max width StyleInjector.inject(".slider .tooltip-inner { max-width: 900px; }"); header.setVisible(false); slider.setHandle(HandleType.ROUND); slider.setFormatter(r -> presenter.formatRange(r.getMinValue(), r.getMaxValue())); slider.addSlideStopHandler(e -> presenter.onSliderChange(e.getValue().getMinValue(), e.getValue().getMaxValue())); slider.getElement().getStyle().setWidth(100, Style.Unit.PCT); inputs.getElement().getStyle().setWidth(100, Style.Unit.PCT); body.add(slider); body.getElement().getStyle().setMarginLeft(10, Style.Unit.PX); container.add(header); container.add(body); container.add(inputs); container.add(error); } @Override public String getColumnsTitle() { return SliderConstants.INSTANCE.sliderColumnName(); } @Override public void showTitle(String title) { error.setVisible(false); header.setVisible(true); header.setText(title); } @Override public void setWidth(int width) { slider.getElement().getStyle().setWidth(width, Style.Unit.PX); inputs.getElement().getStyle().setWidth(width, Style.Unit.PX); } @Override public void margins(int top, int bottom, int left, int right) { container.getElement().getStyle().setMarginTop(top, Style.Unit.PX); container.getElement().getStyle().setMarginBottom(bottom, Style.Unit.PX); container.getElement().getStyle().setMarginLeft(left, Style.Unit.PX); container.getElement().getStyle().setMarginRight(right, Style.Unit.PX); } @Override public void setSliderEnabled(boolean enabled) { slider.setEnabled(enabled); slider.setTooltip(enabled ? TooltipType.SHOW : TooltipType.HIDE); } @Override public void showSlider(double min, double max, double step, double minSelected, double maxSelected) { slider.setMin(min); slider.setMax(max); slider.setValue(new Range(minSelected, maxSelected)); slider.setStep(step); header.setVisible(true); body.setVisible(true); error.setVisible(false); } @Override public void showInputs(IsWidget minValueEditor, IsWidget maxValueEditor) { minValueEditor.asWidget().getElement().getStyle().setMarginTop(5, Style.Unit.PX); maxValueEditor.asWidget().getElement().getStyle().setMarginTop(5, Style.Unit.PX); minValueEditor.asWidget().getElement().getStyle().setMarginBottom(5, Style.Unit.PX); maxValueEditor.asWidget().getElement().getStyle().setMarginBottom(5, Style.Unit.PX); maxValueEditor.asWidget().getElement().getStyle().setFloat(Style.Float.RIGHT); inputs.clear(); inputs.add(minValueEditor); inputs.add(maxValueEditor); header.setVisible(true); inputs.setVisible(true); error.setVisible(false); } @Override public String formatRange(String from, String to) { return SliderConstants.INSTANCE.sliderTooltip(from, to); } @Override public void textColumnsNotSupported() { header.setVisible(false); error(SliderConstants.INSTANCE.textColumnsNotSupported()); } @Override public void noData() { error(SelectorConstants.INSTANCE.selectorDisplayer_noDataAvailable()); } protected void error(String msg) { body.setVisible(false); inputs.setVisible(false); error.setVisible(true); error.clear(); error.add(new Label(msg)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/table/TableDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.table; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.common.client.widgets.FilterLabel; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.AbstractGwtDisplayer; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.export.ExportCallback; import org.dashbuilder.displayer.client.export.ExportFormat; import org.uberfire.client.callbacks.Callback; import org.uberfire.mvp.Command; @Dependent public class TableDisplayer extends AbstractGwtDisplayer { public interface View extends AbstractGwtDisplayer.View { String getGroupsTitle(); String getColumnsTitle(); void showTitle(String title); void createTable(int pageSize, FilterLabelSet widget); void redrawTable(); void setWidth(int width); void fullWidth(); void setSortEnabled(boolean enabled); void setTotalRows(int rows, boolean isExact); void setPagerEnabled(boolean enabled); void setColumnPickerEnabled(boolean enabled); void setExportToCsvEnabled(boolean enabled); void setExportToXlsEnabled(boolean enabled); void addColumn(ColumnType columnType, String columnId, String columnName, int index, boolean selectEnabled, boolean sortEnabled); void gotoFirstPage(); int getLastOffset(); int getPageSize(); void exportNoData(); void exportTooManyRows(int rowNum, int limit); void exportFileUrl(String url); } protected View view; protected int totalRows = 0; protected String lastOrderedColumn = null; protected SortOrder lastSortOrder = null; protected List onCellSelectedCommands = new ArrayList<>(); protected String selectedCellColumn = null; protected Integer selectedCellRow = null; protected int exportRowNumMax = 100000; protected FilterLabelSet filterLabelSet; @Inject public TableDisplayer(View view, FilterLabelSet filterLabelSet) { this.view = view; this.view.init(this); this.filterLabelSet = filterLabelSet; this.filterLabelSet.setOnClearAllCommand(this::onFilterClearAll); } @Override public View getView() { return view; } public FilterLabelSet getFilterLabelSet() { return filterLabelSet; } public int getTotalRows() { return totalRows; } public String getLastOrderedColumn() { return lastOrderedColumn; } public SortOrder getLastSortOrder() { return lastSortOrder; } public String getSelectedCellColumn() { return selectedCellColumn; } public Integer getSelectedCellRow() { return selectedCellRow; } public int getExportRowNumMax() { return exportRowNumMax; } public void setExportRowNumMax(int exportRowNumMax) { this.exportRowNumMax = exportRowNumMax; } public void addOnCellSelectedCommand(Command onCellSelectedCommand) { this.onCellSelectedCommands.add(onCellSelectedCommand); } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupAllowed(true) .setGroupRequired(false) .setExtraColumnsAllowed(true) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()); return new DisplayerConstraints(lookupConstraints) .supportsAttribute( DisplayerAttributeDef.TYPE ) .supportsAttribute( DisplayerAttributeDef.RENDERER ) .supportsAttribute( DisplayerAttributeGroupDef.COLUMNS_GROUP ) .supportsAttribute( DisplayerAttributeGroupDef.FILTER_GROUP ) .supportsAttribute( DisplayerAttributeGroupDef.REFRESH_GROUP ) .supportsAttribute( DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute( DisplayerAttributeGroupDef.CHART_RESIZABLE ) .supportsAttribute( DisplayerAttributeGroupDef.EXPORT_GROUP) .supportsAttribute( DisplayerAttributeGroupDef.TABLE_GROUP ); } @Override protected void beforeDataSetLookup() { // Get the sort settings if (lastOrderedColumn == null) { String defaultSortColumn = displayerSettings.getTableDefaultSortColumnId(); if (!StringUtils.isBlank(defaultSortColumn)) { lastOrderedColumn = defaultSortColumn; lastSortOrder = displayerSettings.getTableDefaultSortOrder(); } } // Apply the sort order specified (if any) if (lastOrderedColumn != null) { sortApply(lastOrderedColumn, lastSortOrder); } // Lookup only the target rows dataSetHandler.limitDataSetRows(view.getLastOffset(), getPageSize()); } protected int getPageSize() { return view.getPageSize() == 0 ? displayerSettings.getTablePageSize() : view.getPageSize(); } @Override protected void afterDataSetLookup(DataSet dataSet) { totalRows = dataSet.getRowCountNonTrimmed(); view.setTotalRows(totalRows, isTotalRowsExact(dataSet, totalRows)); } @Override protected void createVisualization() { if (displayerSettings.isTitleVisible()) { view.showTitle(displayerSettings.getTitle()); } List dataColumns = dataSet.getColumns(); int width = displayerSettings.getTableWidth(); view.createTable(displayerSettings.getTablePageSize(), filterLabelSet); view.setWidth(width == 0 ? dataColumns.size() * 100 + 40 : width); view.setSortEnabled(displayerSettings.isTableSortEnabled()); view.setTotalRows(totalRows, isTotalRowsExact(dataSet, totalRows)); view.setPagerEnabled(isPagerEnabled(dataSet, totalRows)); view.setColumnPickerEnabled(displayerSettings.isTableColumnPickerEnabled()); view.setExportToCsvEnabled(displayerSettings.isCSVExportAllowed()); view.setExportToXlsEnabled(displayerSettings.isExcelExportAllowed()); if(displayerSettings.isResizable()) { view.fullWidth(); } for ( int i = 0; i < dataColumns.size(); i++ ) { DataColumn dataColumn = dataColumns.get(i); ColumnSettings columnSettings = displayerSettings.getColumnSettings(dataColumn); String columnName = columnSettings.getColumnName(); switch (dataColumn.getColumnType()) { case LABEL: { // Only label columns cells are selectable view.addColumn(dataColumn.getColumnType(), dataColumn.getId(), columnName, i, displayerSettings.isFilterEnabled(), true); break; } default: { view.addColumn(dataColumn.getColumnType(), dataColumn.getId(), columnName, i, false, true); break; } } } view.gotoFirstPage(); } protected boolean isTotalRowsExact(DataSet dataSet, int totalRows) { return isRemoteProvider(dataSet) ? totalRows < getPageSize() : true; } protected boolean isPagerEnabled(DataSet dataSet, int totalRows) { return isRemoteProvider(dataSet) ? totalRows == getPageSize() : getPageSize() < dataSet.getRowCountNonTrimmed(); } protected boolean isRemoteProvider(DataSet dataSet) { final DataSetDef def = dataSet.getDefinition(); return def == null || def.getProvider() == null ? false : def.getProvider().getName().equals("REMOTE"); } @Override protected void updateVisualization() { view.setTotalRows(totalRows, isTotalRowsExact(dataSet, totalRows)); view.setPagerEnabled(isPagerEnabled(dataSet, totalRows)); view.gotoFirstPage(); view.redrawTable(); updateFilterStatus(); } protected void updateFilterStatus() { filterLabelSet.clear(); Set columnFilters = filterColumns(); if (displayerSettings.isFilterEnabled() && !columnFilters.isEmpty()) { for (String columnId : columnFilters) { List selectedValues = filterIntervals(columnId); DataColumn column = dataSet.getColumnById(columnId); for (Interval interval : selectedValues) { String formattedValue = formatInterval(interval, column); FilterLabel filterLabel = filterLabelSet.addLabel(formattedValue); filterLabel.setOnRemoveCommand(() -> onFilterLabelRemoved(columnId, interval.getIndex())); } } } } public void sortBy(String column, SortOrder order) { if (displayerSettings.isTableSortEnabled()) { lastOrderedColumn = column; lastSortOrder = order; super.redraw(); } } public void selectCell(String columnId, int rowIndex) { if (displayerSettings.isFilterEnabled()) { selectedCellColumn = columnId; selectedCellRow = rowIndex; for(Command cmd : onCellSelectedCommands){ cmd.execute(); } if (displayerSettings.isFilterSelfApplyEnabled()) { view.gotoFirstPage(); } super.filterUpdate(columnId, rowIndex); updateFilterStatus(); } } @Override public void filterReset(String columnId) { super.filterReset(columnId); if (selectedCellColumn != null && selectedCellColumn.equals(columnId)) { selectedCellColumn = null; selectedCellRow = null; } } @Override public void filterReset() { selectedCellColumn = null; selectedCellRow = null; filterLabelSet.clear(); super.filterReset(); } public void lookupCurrentPage(final Callback callback) { try { beforeDataSetLookup(); dataSetHandler.lookupDataSet(new DataSetReadyCallback() { public void callback(DataSet ds) { try { dataSet = ds; afterDataSetLookup(dataSet); callback.callback(dataSet.getRowCount()); } catch (Exception e) { showError(new ClientRuntimeError(e)); } } public void notFound() { view.errorDataSetNotFound(displayerSettings.getDataSetLookup().getDataSetUUID()); } public boolean onError(ClientRuntimeError error) { showError(error); return false; } }); } catch (Exception e) { showError(new ClientRuntimeError(e)); } } public void export(ExportFormat format) { super.export(format, exportRowNumMax, new ExportCallback() { @Override public void noData() { view.exportNoData(); } @Override public void tooManyRows(int rowNum) { view.exportTooManyRows(rowNum, exportRowNumMax); } @Override public void exportFileUrl(String url) { view.exportFileUrl(url); } @Override public void error(ClientRuntimeError error) { view.error(error); } }); } // Filter label set component notifications void onFilterLabelRemoved(String columnId, int row) { super.filterUpdate(columnId, row); // Update the displayer view in order to reflect the current selection // (only if not has already been redrawn in the previous filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } void onFilterClearAll() { filterReset(); // Update the displayer view in order to reflect the current selection // (only if not has already been redrawn in the previous filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } // Reset the current navigation status on filter requests from external displayers @Override public void onFilterEnabled(Displayer displayer, DataSetGroup groupOp) { view.gotoFirstPage(); super.onFilterEnabled(displayer, groupOp); } @Override public void onFilterEnabled(Displayer displayer, DataSetFilter filter) { view.gotoFirstPage(); super.onFilterEnabled(displayer, filter); } @Override public void onFilterReset(Displayer displayer, List groupOps) { view.gotoFirstPage(); super.onFilterReset(displayer, groupOps); } @Override public void onFilterReset(Displayer displayer, DataSetFilter filter) { view.gotoFirstPage(); super.onFilterReset(displayer, filter); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/java/org/dashbuilder/renderer/client/table/TableDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.table; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.IntStream; import com.google.gwt.cell.client.TextCell; import com.google.gwt.cell.client.ValueUpdater; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Style; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.cellview.client.ColumnSortEvent; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.view.client.AsyncDataProvider; import com.google.gwt.view.client.HasData; import com.google.gwt.view.client.Range; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.client.AbstractGwtDisplayerView; import org.dashbuilder.displayer.client.export.ExportFormat; import org.dashbuilder.renderer.client.resources.i18n.TableConstants; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.constants.IconType; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.uberfire.ext.widgets.common.client.tables.PagedTable; import static com.google.gwt.dom.client.BrowserEvents.CLICK; import static com.google.gwt.dom.client.BrowserEvents.MOUSEOVER; public class TableDisplayerView extends AbstractGwtDisplayerView implements TableDisplayer.View { protected HTML titleHtml = new HTML(); protected TableProvider tableProvider = new TableProvider(); protected VerticalPanel rootPanel = new VerticalPanel(); protected PagedTable table; protected Button exportToCsvButton; protected Button exportToXlsButton; @Override public void init(TableDisplayer presenter) { super.setPresenter(presenter); super.setVisualization(rootPanel); rootPanel.add(titleHtml); } @Override public void showTitle(String title) { titleHtml.setText(title); } @Override public String getGroupsTitle() { return TableConstants.INSTANCE.tableDisplayer_groupsTitle(); } @Override public String getColumnsTitle() { return TableConstants.INSTANCE.tableDisplayer_columnsTitle(); } @Override public void createTable(int pageSize, FilterLabelSet filterLabelSet) { table = new PagedTable<>(pageSize); table.pageSizesSelector.setVisible(false); table.setEmptyTableCaption(TableConstants.INSTANCE.tableDisplayer_noDataAvailable()); table.pageSizesSelector.setForceDropup(true); table.pageSizesSelector.setDropupAuto(false); tableProvider.addDataDisplay(table); tableProvider.lastPageSize = pageSize; HTMLElement element = filterLabelSet.getElement(); element.getStyle().setProperty("margin-bottom", "5px"); table.getLeftToolbar().add(ElementWrapperWidget.getWidget(filterLabelSet.getElement())); exportToCsvButton = new Button("", IconType.FILE_TEXT, e -> getPresenter().export(ExportFormat.CSV)); exportToXlsButton = new Button("", IconType.FILE_EXCEL_O, e -> getPresenter().export(ExportFormat.XLS)); exportToCsvButton.setTitle(TableConstants.INSTANCE.tableDisplayer_export_to_csv()); exportToXlsButton.setTitle(TableConstants.INSTANCE.tableDisplayer_export_to_xls()); setupToolbar(); rootPanel.add(table); } protected void setupToolbar() { HasWidgets rightToolbar = table.getRightToolbar(); if (rightToolbar instanceof HorizontalPanel) { ((HorizontalPanel) rightToolbar).insert(exportToCsvButton, 0); ((HorizontalPanel) rightToolbar).insert(exportToXlsButton, 1); } else { rightToolbar.add(exportToCsvButton); rightToolbar.add(exportToXlsButton); } } @Override public void redrawTable() { table.redraw(); } @Override public void setWidth(int width) { table.setWidth(width + "px"); } @Override public void fullWidth() { table.setWidth("100%"); rootPanel.setWidth("100%"); } @Override public void setSortEnabled(boolean enabled) { table.addColumnSortHandler(new ColumnSortEvent.AsyncHandler(table) { public void onColumnSort(ColumnSortEvent event) { String column = ((DataColumnCell) event.getColumn().getCell()).columnId; SortOrder order = event.isSortAscending() ? SortOrder.ASCENDING : SortOrder.DESCENDING; getPresenter().sortBy(column, order); } }); } @Override public void setTotalRows(int rows, boolean isExact) { if(table != null) { table.setRowCount(rows, isExact); } } @Override public void setPagerEnabled(boolean enabled) { table.pager.setVisible(enabled); } @Override public void setColumnPickerEnabled(boolean enabled) { table.setColumnPickerButtonVisible(enabled); } @Override public void setExportToCsvEnabled(boolean enabled) { exportToCsvButton.setVisible(enabled); } @Override public void setExportToXlsEnabled(boolean enabled) { exportToXlsButton.setVisible(enabled); } @Override public void addColumn(ColumnType columnType, String columnId, String columnName, int index, boolean selectEnabled, boolean sortEnabled) { Column column = createColumn(columnType, columnId, selectEnabled, index); if (column != null) { column.setSortable(sortEnabled); table.addColumn(column, columnName); } } @Override public void gotoFirstPage() { tableProvider.gotoFirstPage(); } @Override public int getLastOffset() { return tableProvider.lastOffset; } @Override public int getPageSize() { return tableProvider.lastPageSize; } @Override public void exportNoData() { Window.alert(TableConstants.INSTANCE.tableDisplayer_export_no_data()); } @Override public void exportTooManyRows(int rowNum, int limit) { Window.alert(TableConstants.INSTANCE.tableDisplayer_export_too_many_rows(rowNum, limit)); } @Override public void exportFileUrl(String url) { Window.open(url, "downloading", "resizable=no,scrollbars=yes,status=no"); } // Table internals protected Column createColumn(ColumnType type, String columnId, final boolean selectable, final int columnNumber) { switch (type) { case LABEL: return new Column(new DataColumnCell(columnId, selectable)) { public String getValue(Integer row) { return getPresenter().formatValue(row, columnNumber); } }; case NUMBER: case DATE: case TEXT: return new Column(new DataColumnCell(columnId, selectable)) { public String getValue(Integer row) { return getPresenter().formatValue(row, columnNumber); } }; } return null; } protected class DataColumnCell extends TextCell { private String columnId; private boolean selectable = false; DataColumnCell(String columnId, boolean selectable) { this.columnId = columnId; this.selectable = selectable; } @Override public Set getConsumedEvents() { Set consumedEvents = new HashSet(); if (selectable) { consumedEvents.add(CLICK); consumedEvents.add(MOUSEOVER); } return consumedEvents; } @Override public void onBrowserEvent(Context context, Element parent, String value, NativeEvent event, ValueUpdater valueUpdater) { if (selectable) { String eventType = event.getType(); switch (eventType) { case MOUSEOVER: parent.getStyle().setCursor(Style.Cursor.POINTER); break; case CLICK: int rowIndexInPage = context.getIndex() - table.getPageStart(); getPresenter().selectCell(columnId, rowIndexInPage); break; } } } } /** * The table data provider */ protected class TableProvider extends AsyncDataProvider { protected int lastOffset = 0; protected int lastPageSize = 0; protected List getCurrentPageRows(HasData display) { final int start = display.getVisibleRange().getStart(); int pageSize = display.getVisibleRange().getLength(); int items = Integer.min(pageSize, table.getRowCount() > start ? table.getRowCount() - start : table.getRowCount()); return IntStream.range(0, items).boxed().collect(Collectors.toList()); } /** * Both filter & sort invoke this method from redraw() */ public void gotoFirstPage() { // Avoid fetching the data set again lastOffset = 0; lastPageSize = table.getVisibleRange().getLength(); // This calls internally to onRangeChanged() when the page changes table.pager.setPage(0); int start = table.getVisibleRange().getStart(); final List rows = getCurrentPageRows(table); updateRowData(start, rows); } /** * Invoked from createWidget just after the data set has been fetched. */ public void addDataDisplay(HasData display) { // Avoid fetching the data set again lastOffset = 0; lastPageSize = table.getVisibleRange().getLength(); // This calls internally to onRangeChanged() super.addDataDisplay(display); } /** * This is invoked internally by the PagedTable on navigation actions. */ protected void onRangeChanged(final HasData display) { final Range range = display.getVisibleRange(); if (lastOffset == range.getStart() && range.getLength() <= lastPageSize) { lastPageSize = range.getLength(); if(table.getRowCount() > range.getLength()) { setPagerEnabled(true); } updateRowData(lastOffset, getCurrentPageRows(display)); } else { lastOffset = range.getStart(); lastPageSize = range.getLength(); getPresenter().lookupCurrentPage(rowsFetched -> { final List rows = getCurrentPageRows(display); updateRowData(lastOffset, rows); }); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/DefaultRenderer.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # error=ERROR: error_settings_unset=DisplayerSettings property not set. error_handler_unset=DataSetHandler property not set. error_dataset_notfound=Data set not found. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants_de.properties ================================================ error=FEHLER\: error_settings_unset=DisplayerSettings-Eigenschaft nicht eingestellt. error_handler_unset=DataSetHandler-Eigenschaft nicht eingestellt. error_dataset_notfound=Datensatz nicht gefunden. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants_es.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # error=ERROR: error_settings_unset=Propiedad DisplayerSettings no establecida. error_handler_unset=Propiedad DataSetHandler no establecida. error_dataset_notfound=No se encuentra el conjunto de datos. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants_fr.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # error=ERREUR : error_settings_unset=La propriété DisplayerSettings n''est pas définie. error_handler_unset=La propriété DataSetHandler n''est pas définie. error_dataset_notfound=Ensemble de données introuvable. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants_it.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # error=ERRORE: error_settings_unset=Proprietà DisplayerSettings non impostata. error_handler_unset=Proprietà DataSetHandler non impostata. error_dataset_notfound=Set di dati non trovato. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants_ja.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # error=エラー: error_settings_unset=DisplayerSettings プロパティーが設定されていません。 error_handler_unset=DataSetHandler プロパティーが設定されていません。 error_dataset_notfound=データセットが見つかりません。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants_pt_BR.properties ================================================ error=ERRO\: error_settings_unset=Propriedade do DisplayerSettings não foi definida. error_handler_unset=Propriedade do DataSetHandler não foi definida. error_dataset_notfound=Data set não foi encontrado. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/CommonConstants_zh_CN.properties ================================================ error=错误: error_settings_unset=没有设置 DisplayerSettings 属性。 error_handler_unset=没有设置 DataSetHandler 属性。 error_dataset_notfound=未找到数据集。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # metricDisplayer_noDataAvailable=No data metricDisplayer_columnsTitle=Metric ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants_de.properties ================================================ metricDisplayer_columnsTitle=Metrik ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # metricDisplayer_noDataAvailable=No hay datos metricDisplayer_columnsTitle=Métrica ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # metricDisplayer_noDataAvailable=Aucune donnée metricDisplayer_columnsTitle=Métrique ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # metricDisplayer_noDataAvailable=Nessun dato metricDisplayer_columnsTitle=Metrica ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # metricDisplayer_noDataAvailable=データなし metricDisplayer_columnsTitle=メトリック ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants_pt_BR.properties ================================================ metricDisplayer_columnsTitle=Métrica ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/MetricConstants_zh_CN.properties ================================================ metricDisplayer_columnsTitle=度量 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # selectorDisplayer_noDataAvailable=No data selectorDisplayer_groupsTitle=Entries selectorDisplayer_columnsTitle=Tooltip selectorDisplayer_select=Select selectorDisplayer_reset=Clear selectorDisplayer_clearAll=Clear All ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants_de.properties ================================================ selectorDisplayer_select=Auswählen ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # selectorDisplayer_noDataAvailable=No hay datos selectorDisplayer_groupsTitle=Entradas selectorDisplayer_columnsTitle=Información sobre herramientas selectorDisplayer_select=Seleccionar selectorDisplayer_reset=Borrar selectorDisplayer_clearAll=Borrar todo ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # selectorDisplayer_noDataAvailable=Aucune donnée selectorDisplayer_groupsTitle=Entrées selectorDisplayer_columnsTitle=Info-bulle selectorDisplayer_select=Sélectionner selectorDisplayer_reset=Effacer selectorDisplayer_clearAll=Effacer tout ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # selectorDisplayer_noDataAvailable=Nessun dato selectorDisplayer_groupsTitle=Voci selectorDisplayer_columnsTitle=Tooltip selectorDisplayer_select=Seleziona selectorDisplayer_reset=Cancella selectorDisplayer_clearAll=Cancella tutto ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # selectorDisplayer_noDataAvailable=データなし selectorDisplayer_groupsTitle=エントリー selectorDisplayer_columnsTitle=値 selectorDisplayer_select=選択 selectorDisplayer_reset=消去 selectorDisplayer_clearAll=すべて消去 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants_pt_BR.properties ================================================ selectorDisplayer_select=Selecionar ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SelectorConstants_zh_CN.properties ================================================ selectorDisplayer_select=选择 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SliderConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # sliderColumnName=Column sliderTooltip={0} to {1} textColumnsNotSupported=Text columns not supported (only date and numeric are) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SliderConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # sliderColumnName=Columna sliderTooltip={0} a {1} textColumnsNotSupported=Columnas de texto no admitidas (solo se admiten las de fecha y número) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SliderConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # sliderColumnName=Colonne sliderTooltip={0} à {1} textColumnsNotSupported=Colonnes de texte non prises en charge (seules les colonnes de date et numériques le sont) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SliderConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # sliderColumnName=Colonna sliderTooltip={0} a {1} textColumnsNotSupported=Colonne di testo non supportate (solo date e numeriche) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/SliderConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # sliderColumnName=カラム sliderTooltip={0} を {1} へ textColumnsNotSupported=テキスト列はサポートされません(日付と数値のみサポート) ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # tableDisplayer_noDataAvailable=No data tableDisplayer_groupsTitle=Group By tableDisplayer_columnsTitle=Columns tableDisplayer_reset=reset tableDisplayer_export_to_csv=Export to CSV tableDisplayer_export_to_xls=Export to Excel tableDisplayer_export_no_data=No data to export. The table is empty. tableDisplayer_export_too_many_rows=The table rows={0} exceed the maximum allowed={1} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants_de.properties ================================================ tableDisplayer_columnsTitle=Spalten tableDisplayer_reset=zurücksetzen ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # tableDisplayer_noDataAvailable=No hay datos tableDisplayer_groupsTitle=Agrupar por tableDisplayer_columnsTitle=Columnas tableDisplayer_reset=restablecer tableDisplayer_export_to_csv=Exportar a CSV tableDisplayer_export_to_xls=Exportar a Excel tableDisplayer_export_no_data=No hay datos para exportar. La tabla está vacía. tableDisplayer_export_too_many_rows=Las filas de la tabla={0} supera la cantidad máxima permitida={1} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # tableDisplayer_noDataAvailable=Aucune donnée tableDisplayer_groupsTitle=Grouper par tableDisplayer_columnsTitle=Colonnes tableDisplayer_reset=réinitialiser tableDisplayer_export_to_csv=Exporter au format CSV tableDisplayer_export_to_xls=Exporter vers Excel tableDisplayer_export_no_data=Aucune donnée à exporter. La table est vide. tableDisplayer_export_too_many_rows=Les lignes de la table={0} dépassent le maximum autorisé={1} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # tableDisplayer_noDataAvailable=Nessun dato tableDisplayer_groupsTitle=Raggruppa per tableDisplayer_columnsTitle=Colonne tableDisplayer_reset=reset tableDisplayer_export_to_csv=Esporta in CSV tableDisplayer_export_to_xls=Esporta in Excel tableDisplayer_export_no_data=Nessun dato da esportare. La tabella è vuota. tableDisplayer_export_too_many_rows=Le righe della tabella={0} superano il limite massimo consentito={1} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # tableDisplayer_noDataAvailable=データなし tableDisplayer_groupsTitle=グループ化 tableDisplayer_columnsTitle=カラム tableDisplayer_reset=リセット tableDisplayer_export_to_csv=CSVにエクスポート tableDisplayer_export_to_xls=Excelにエクスポート tableDisplayer_export_no_data=エクスポートするデータがありませんテーブルは空です。 tableDisplayer_export_too_many_rows=テーブル列 {0} は、最大数 {1} を超えています。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants_pt_BR.properties ================================================ tableDisplayer_columnsTitle=Colunas tableDisplayer_reset=reiniciar ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/main/resources/org/dashbuilder/renderer/client/resources/i18n/TableConstants_zh_CN.properties ================================================ tableDisplayer_columnsTitle=列 tableDisplayer_reset=重置 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/external/ExternalComponentDisplayerTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.external; import java.text.ParseException; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.ExpenseReportsData; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.AbstractDisplayer; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class ExternalComponentDisplayerTest extends AbstractDisplayerTest { @Test public void testBuildData() throws ParseException { DataSet dataSet = ExpenseReportsData.INSTANCE.toDataSet(); DisplayerSettings settings = mock(DisplayerSettings.class); ColumnSettings clSettings = mock(ColumnSettings.class); ExternalComponentDisplayer displayer = new ExternalComponentDisplayer(); when(settings.getColumnSettings(anyString())).thenReturn(clSettings); displayer.setDisplayerSettings(settings); displayer.setEvaluator(new AbstractDisplayer.ExpressionEval() { @Override public String evalExpression(String value, String expression) { return value; } }); String[][] buildData = displayer.buildData(dataSet); for (int i = 0; i < buildData.length; i++) { for (int j = 0; j < buildData[i].length; j++) { assertEquals(buildData[i][j], dataSet.getValueAt(i, j).toString()); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/metric/MetricDisplayerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.metric; import org.dashbuilder.common.client.StringUtils; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.DisplayerListener; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.dashbuilder.dataset.ExpenseReportsData.*; @RunWith(MockitoJUnitRunner.Silent.class) public class MetricDisplayerTest extends AbstractDisplayerTest { public static final String HTML_TEMPLATE = "
    \n" + " ${title}\n" + " ${value}\n" + "
    "; public static final String JS_TEMPLATE = "if (${isFilterEnabled}) { \n" + " var filterOn = ${isFilterOn};\n" + " ${this}.style.cursor=\"pointer\";\n" + " ${this}.onclick = function() {\n" + " filterOn = !filterOn;\n" + " ${this}.style.backgroundColor = filterOn ? \"lightblue\" : \"${bgColor}\";\n" + " ${doFilter};\n" + " };\n" + "}"; @Mock MetricDisplayer.View view; @Mock DisplayerListener listener; public MetricDisplayer createMetricDisplayer(DisplayerSettings settings) { MetricDisplayer displayer = initDisplayer(new MetricDisplayer(view), settings); displayer.addListener(listener); return displayer; } @Before public void setUp() { when(view.getUniqueId()).thenReturn("test"); } @Test public void testDraw() { DisplayerSettings engExpenses = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .filter(COLUMN_DEPARTMENT, FilterFactory.equalsTo("Engineering")) .column(COLUMN_AMOUNT, AggregateFunctionType.SUM) .title("Title").titleVisible(true) .width(300).height(200) .margins(10, 20, 30, 40) .backgroundColor("FDE8D4") .filterOff(true) .htmlTemplate(HTML_TEMPLATE) .jsTemplate("alert('${value.raw}');") .buildSettings(); MetricDisplayer presenter = createMetricDisplayer(engExpenses); presenter.draw(); verify(view).setHtml("
    \n" + " Title\n" + " 7,650.16\n" + "
    "); verify(view).eval("alert('7650.16');"); } @Test public void testDefaultTemplates() { DisplayerSettings engExpenses = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .buildSettings(); MetricDisplayer presenter = createMetricDisplayer(engExpenses); String html = presenter.getHtmlTemplate(); String js = presenter.getJsTemplate(); assertFalse(StringUtils.isBlank(html)); assertFalse(StringUtils.isBlank(js)); assertFalse(html.equals(js)); } @Test public void testNoData() { DisplayerSettings empty = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .column(COLUMN_AMOUNT) .title("Title").titleVisible(true) .width(300).height(200) .margins(10, 20, 30, 40) .backgroundColor("FDE8D4") .htmlTemplate(HTML_TEMPLATE) .buildSettings(); when(view.getNoDataString()).thenReturn("0,0"); MetricDisplayer presenter = createMetricDisplayer(empty); MetricDisplayer.View view = presenter.getView(); presenter.draw(); verify(view, atLeastOnce()).getNoDataString(); verify(view).setHtml("
    \n" + " Title\n" + " 0,0\n" + "
    "); } @Test public void testNoFilter() { DisplayerSettings empty = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .column(COLUMN_AMOUNT) .filterOn(false, true, true) .buildSettings(); MetricDisplayer presenter = createMetricDisplayer(empty); MetricDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); reset(listener); presenter.filterApply(); verify(listener, never()).onFilterEnabled(eq(presenter), any(DataSetFilter.class)); } @Test public void testSwitchOnFilter() { DisplayerSettings empty = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .column(COLUMN_AMOUNT) .filterOn(false, true, true) .buildSettings(); MetricDisplayer presenter = createMetricDisplayer(empty); MetricDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); reset(listener); presenter.updateFilter(); verify(listener).onFilterEnabled(eq(presenter), any(DataSetFilter.class)); } @Test public void testSwitchOffFilter() { DisplayerSettings empty = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .column(COLUMN_AMOUNT) .filterOn(false, true, true) .buildSettings(); MetricDisplayer presenter = createMetricDisplayer(empty); MetricDisplayer.View view = presenter.getView(); presenter.draw(); presenter.filterApply(); reset(view); reset(listener); presenter.filterReset(); verify(listener).onFilterReset(eq(presenter), any(DataSetFilter.class)); } @Test public void testFilterOn() { DisplayerSettings empty = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .column(COLUMN_AMOUNT) .filterOn(false, true, true) .jsTemplate(JS_TEMPLATE) .buildSettings(); MetricDisplayer presenter = createMetricDisplayer(empty); presenter.setFilterOn(true); presenter.draw(); assertEquals(presenter.isFilterOn(), true); verify(view).eval("if (true) { \n" + " var filterOn = true;\n" + " document.getElementById(\"test_this\").style.cursor=\"pointer\";\n" + " document.getElementById(\"test_this\").onclick = function() {\n" + " filterOn = !filterOn;\n" + " document.getElementById(\"test_this\").style.backgroundColor = filterOn ? \"lightblue\" : \"white\";\n" + " window.metricDisplayerDoFilter('test');\n" + " };\n" + "}"); } @Test public void testFilterOff() { DisplayerSettings empty = DisplayerSettingsFactory.newMetricSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .column(COLUMN_AMOUNT) .filterOn(false, true, true) .jsTemplate(JS_TEMPLATE) .buildSettings(); MetricDisplayer presenter = createMetricDisplayer(empty); presenter.setFilterOn(false); presenter.draw(); assertEquals(presenter.isFilterOn(), false); verify(view).eval("if (true) { \n" + " var filterOn = false;\n" + " document.getElementById(\"test_this\").style.cursor=\"pointer\";\n" + " document.getElementById(\"test_this\").onclick = function() {\n" + " filterOn = !filterOn;\n" + " document.getElementById(\"test_this\").style.backgroundColor = filterOn ? \"lightblue\" : \"white\";\n" + " window.metricDisplayerDoFilter('test');\n" + " };\n" + "}"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/selector/SelectorCoordinatorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import java.util.Date; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.client.AbstractDisplayer; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerCoordinator; import org.dashbuilder.displayer.client.DisplayerListener; import org.dashbuilder.displayer.client.widgets.filter.DateParameterEditor; import org.dashbuilder.displayer.client.widgets.filter.NumberParameterEditor; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class SelectorCoordinatorTest extends AbstractDisplayerTest { DisplayerSettings yearLabels = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .filterOn(false, true, false) .subtype(DisplayerSubType.SELECTOR_LABELS) .buildSettings(); DisplayerSettings dateSlider = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .column(COLUMN_DATE) .filterOn(false, true, true) .subtype(DisplayerSubType.SELECTOR_SLIDER) .buildSettings(); DisplayerSettings numberSlider = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .column(COLUMN_AMOUNT) .filterOn(false, true, false) .subtype(DisplayerSubType.SELECTOR_SLIDER) .buildSettings(); DisplayerSettings dropDownDept = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .filterOn(false, true, true) .subtype(DisplayerSubType.SELECTOR_DROPDOWN) .multiple(true) .buildSettings(); DisplayerSettings dropDownCity = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_CITY) .column(COLUMN_CITY) .filterOn(false, true, true) .subtype(DisplayerSubType.SELECTOR_DROPDOWN) .multiple(true) .buildSettings(); DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .column(COLUMN_DEPARTMENT) .column(COLUMN_CITY) .column(COLUMN_EMPLOYEE) .column(COLUMN_AMOUNT) .column(COLUMN_DATE) .filterOn(true, false, true) .buildSettings(); DisplayerCoordinator displayerCoordinator; AbstractDisplayer allRowsDisplayer; SelectorLabelSetDisplayer yearLabelDisplayer; SelectorSliderDisplayer dateSliderDisplayer; SelectorSliderDisplayer numberSliderDisplayer; SelectorDropDownDisplayer deptDropDownDisplayer; SelectorDropDownDisplayer cityDropDownDisplayer; @Mock SelectorLabelSetDisplayer.View labelSetView; @Mock SelectorSliderDisplayer.View sliderView; @Mock SyncBeanManager beanManager; @Mock DateParameterEditor dateEditor; @Mock NumberParameterEditor numberEditor; @Mock DisplayerListener listener; @Mock SelectorLabelItem labelItem; @Mock SyncBeanDef labelItemBean; @Mock SyncBeanDef dropDownItemBean; @Mock SelectorDropDownItem dropDownItem; public SelectorLabelSetDisplayer createLabelSetDisplayer(DisplayerSettings settings) { return initDisplayer(new SelectorLabelSetDisplayer(labelSetView, beanManager), settings); } public SelectorSliderDisplayer createSliderDisplayer(DisplayerSettings settings) { return initDisplayer(new SelectorSliderDisplayer(sliderView, dateEditor, dateEditor, numberEditor, numberEditor), settings); } public SelectorDropDownDisplayer createDropDownDisplayer(DisplayerSettings settings) { return initDisplayer(new SelectorDropDownDisplayer(mock(SelectorDropDownDisplayerView.class), beanManager), settings); } @Before public void init() throws Exception { super.init(); when(beanManager.lookupBean(SelectorLabelItem.class)).thenReturn(labelItemBean); when(labelItemBean.newInstance()).thenReturn(labelItem); when(beanManager.lookupBean(SelectorDropDownItem.class)).thenReturn(dropDownItemBean); when(dropDownItemBean.newInstance()).thenReturn(dropDownItem); allRowsDisplayer = createNewDisplayer(allRows); dateSliderDisplayer = createSliderDisplayer(dateSlider); numberSliderDisplayer = createSliderDisplayer(numberSlider); yearLabelDisplayer = createLabelSetDisplayer(yearLabels); cityDropDownDisplayer = createDropDownDisplayer(dropDownCity); deptDropDownDisplayer = createDropDownDisplayer(dropDownDept); displayerCoordinator = new DisplayerCoordinator(rendererManager); displayerCoordinator.addDisplayers(allRowsDisplayer, dateSliderDisplayer, numberSliderDisplayer, yearLabelDisplayer, cityDropDownDisplayer, deptDropDownDisplayer); displayerCoordinator.addListener(listener); } @Test public void testDrawAll() { displayerCoordinator.drawAll(); verify(listener, times(6)).onDraw(any(Displayer.class)); } @Test public void testFilterPropagations() { displayerCoordinator.drawAll(); // Select the first year label (2009) reset(listener); when(labelItem.getId()).thenReturn(0); yearLabelDisplayer.onItemSelected(labelItem); // Check the allRowsDisplayer receives the filter request DataSet dataSet = allRowsDisplayer.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 13); verify(listener).onDataLookup(allRowsDisplayer); verify(listener).onRedraw(allRowsDisplayer); } @Test public void testTwoDateFilters() { displayerCoordinator.drawAll(); // Select the first year label (2012) when(labelItem.getId()).thenReturn(0); yearLabelDisplayer.onItemSelected(labelItem); reset(listener); // Select 2012 year on slider when(labelItem.getId()).thenReturn(0); Date min = new Date(112, 0, 1); Date max = new Date(112, 11, 31); dateSliderDisplayer.onSliderChange(min.getTime(), max.getTime()); // Check the allRowsDisplayer receives all the filter requests DataSet dataSet = allRowsDisplayer.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 13); verify(listener).onDataLookup(allRowsDisplayer); verify(listener).onRedraw(allRowsDisplayer); } @Test public void testSliderDateKeepsSelection() { displayerCoordinator.drawAll(); Date min = (Date) dateSliderDisplayer.getSelectedMin(); Date max = (Date) dateSliderDisplayer.getSelectedMax(); // Select the first year label (2012) when(labelItem.getId()).thenReturn(0); yearLabelDisplayer.onItemSelected(labelItem); Date min2012 = (Date) dateSliderDisplayer.getSelectedMin(); Date max2012 = (Date) dateSliderDisplayer.getSelectedMax(); verify(sliderView).showSlider(min2012.getTime(), max2012.getTime(), 1, min2012.getTime(), max2012.getTime()); // Shorten the slider Date newMin = new Date(112, 3, 3); dateSliderDisplayer.onSliderChange(newMin.getTime(), max.getTime()); assertEquals(dateSliderDisplayer.getSelectedMin(), newMin); assertEquals(dateSliderDisplayer.getSelectedMax(), max); // Reset the label filter and check the slider keeps its latest selection reset(sliderView); yearLabelDisplayer.filterReset(); assertEquals(dateSliderDisplayer.getSelectedMin(), newMin); assertEquals(dateSliderDisplayer.getSelectedMax(), max); verify(sliderView).showSlider(min.getTime(), max.getTime(), 1, newMin.getTime(), max.getTime()); } @Test public void testMinMaxNumberSliderEquals() { displayerCoordinator.drawAll(); // Filter by a range numberSliderDisplayer.onSliderChange(11, 100); DataSet dataSet = allRowsDisplayer.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 3); // Select the same min/max amount reset(listener); numberSliderDisplayer.onSliderChange(100, 100); // Check the allRowsDisplayer receives all the filter requests and no data is found dataSet = allRowsDisplayer.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getRowCount(), 1); verify(listener).onDataLookup(allRowsDisplayer); verify(listener).onRedraw(allRowsDisplayer); } @Test public void testSelectedDropDownItems() { displayerCoordinator.drawAll(); // Select the first item on both drop down selectors when(dropDownItem.getId()).thenReturn(0); cityDropDownDisplayer.onItemSelected(dropDownItem); reset(dropDownItem); deptDropDownDisplayer.onItemSelected(dropDownItem); verify(dropDownItem).select(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/selector/SelectorDisplayerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.DisplayerListener; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.mockito.Mockito.*; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.Silent.class) public class SelectorDisplayerTest extends AbstractDisplayerTest { public SelectorDisplayer createSelectorDisplayer(DisplayerSettings settings) { return initDisplayer(new SelectorDisplayer(mock(SelectorDisplayer.View.class)), settings); } @Test public void testDraw() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, false) .buildSettings(); SelectorDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDisplayer.View view = presenter.getView(); presenter.draw(); verify(view).setFilterEnabled(true); verify(view).clearItems(); verify(view).showSelectHint(COLUMN_DEPARTMENT); verify(view, times(5)).addItem(anyString(), anyString(), eq(false)); verify(view, never()).showResetHint(anyString()); } @Test public void testNoData() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDisplayer.View view = presenter.getView(); presenter.draw(); verify(view).clearItems(); verify(view).showSelectHint(COLUMN_DEPARTMENT); verify(view, never()).addItem(anyString(), anyString(), anyBoolean()); } @Test public void testNullNotShown() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DEPARTMENT)); expensesDataSet.setValueAt(0, column, null); // ... and make sure it's not shown SelectorDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDisplayer.View view = presenter.getView(); presenter.draw(); verify(view, never()).addItem(anyString(), eq((String) null), anyBoolean()); verify(view, times(5)).addItem(anyString(), anyString(), eq(false)); } @Test public void testSelectDisabled() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOff(true) .buildSettings(); SelectorDisplayer presenter = createSelectorDisplayer(departmentList); DisplayerListener listener = mock(DisplayerListener.class); SelectorDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); when(view.getSelectedId()).thenReturn("1"); presenter.addListener(listener); presenter.onItemSelected(); // Check filter notifications verify(listener, never()).onFilterEnabled(eq(presenter), any(DataSetGroup.class)); verify(listener, never()).onRedraw(presenter); // Ensure data does not change verify(view).showResetHint(COLUMN_DEPARTMENT); verify(view, never()).clearItems(); verify(view, never()).showSelectHint(COLUMN_DEPARTMENT); verify(view, never()).addItem(anyString(), anyString(), anyBoolean()); } @Test public void testSelectItem() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .buildSettings(); SelectorDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); // Select an item reset(view); when(view.getSelectedId()).thenReturn("1"); presenter.addListener(listener); presenter.onItemSelected(); // Ensure data does not change verify(view, never()).clearItems(); verify(view, never()).addItem(anyString(), anyString(), anyBoolean()); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(view).showResetHint(COLUMN_DEPARTMENT); verify(view, never()).showSelectHint(COLUMN_DEPARTMENT); verify(listener).onFilterEnabled(eq(presenter), argument.capture()); verify(listener, never()).onRedraw(presenter); DataSetGroup dataSetGroup = argument.getValue(); Interval selectedInterval = dataSetGroup.getSelectedIntervalList().get(0); assertEquals(selectedInterval.getName(), "Services"); } @Test public void testDrillDown() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(true, true, true) .buildSettings(); SelectorDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); reset(view); when(view.getSelectedId()).thenReturn("1"); presenter.addListener(listener); presenter.onItemSelected(); // Check filter notifications verify(listener).onFilterEnabled(eq(presenter), any(DataSetGroup.class)); verify(listener).onRedraw(presenter); // Check selector refreshes verify(view).clearItems(); verify(view, atLeastOnce()).showResetHint(COLUMN_DEPARTMENT); verify(view, never()).showSelectHint(COLUMN_DEPARTMENT); verify(view, times(1)).addItem(anyString(), anyString(), eq(false)); } @Test public void testNullEntries() { // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DEPARTMENT)); expensesDataSet.setValueAt(0, column, null); // Create a selector displayer DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .buildSettings(); SelectorDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.addListener(listener); presenter.draw(); // Verify that null entries are not shown verify(view, times(5)).addItem(anyString(), anyString(), eq(false)); verify(view, never()).addItem(anyString(), eq((String) null), anyBoolean()); // Select an item reset(listener); when(view.getSelectedId()).thenReturn("1"); presenter.onItemSelected(); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(listener).onFilterEnabled(eq(presenter), argument.capture()); DataSetGroup dataSetGroup = argument.getValue(); Interval selectedInterval = dataSetGroup.getSelectedIntervalList().get(0); assertEquals(selectedInterval.getName(), "Engineering"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/selector/SelectorDropDownDisplayerTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import java.util.Arrays; import java.util.List; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.DisplayerListener; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class SelectorDropDownDisplayerTest extends AbstractDisplayerTest { @Mock SyncBeanManager beanManager; @Mock SyncBeanDef dropDownItemBean; @Mock SelectorDropDownItem dropDownItem; public SelectorDropDownDisplayer createSelectorDisplayer(DisplayerSettings settings) { return initDisplayer(new SelectorDropDownDisplayer(mock(SelectorDropDownDisplayer.View.class), beanManager), settings); } @Before public void setUp() { when(beanManager.lookupBean(SelectorDropDownItem.class)).thenReturn(dropDownItemBean); when(dropDownItemBean.newInstance()).thenReturn(dropDownItem); } @Test public void testDraw() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, false) .multiple(false) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDropDownDisplayer.View view = presenter.getView(); presenter.draw(); verify(view).clearItems(); verify(view).showSelectHint(COLUMN_DEPARTMENT, false); verify(view, times(5)).addItem(any()); verify(view, never()).showResetHint(anyString(), anyBoolean()); // Verify the entries are sorted by default DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "Engineering"); assertEquals(dataSet.getValueAt(4, 0), "Support"); } @Test public void testNoData() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .multiple(false) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDropDownDisplayer.View view = presenter.getView(); presenter.draw(); verify(view).clearItems(); verify(view).showSelectHint(COLUMN_DEPARTMENT, false); verify(view, never()).addItem(any()); } @Test public void testNullNotShown() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DEPARTMENT)); expensesDataSet.setValueAt(0, column, null); // ... and make sure it's not shown SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDropDownDisplayer.View view = presenter.getView(); presenter.draw(); verify(view, times(5)).addItem(any()); verify(view, never()).addItem(null); } @Test public void testSelectDisabled() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOff(true) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); DisplayerListener listener = mock(DisplayerListener.class); SelectorDropDownDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); presenter.addListener(listener); presenter.onItemSelected(dropDownItem); // Check filter notifications verify(listener, never()).onFilterEnabled(eq(presenter), any(DataSetGroup.class)); verify(listener, never()).onRedraw(presenter); // Ensure data does not change verify(view, never()).showResetHint(COLUMN_DEPARTMENT, true); verify(view, never()).clearItems(); verify(view, never()).showSelectHint(COLUMN_DEPARTMENT, true); verify(view, never()).addItem(any()); } @Test public void testSelectItem() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .multiple(false) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDropDownDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); // Select an item reset(view); when(dropDownItem.getId()).thenReturn(1); presenter.addListener(listener); presenter.onItemSelected(dropDownItem); // Ensure data does not change verify(view, never()).clearItems(); verify(view, never()).addItem(any()); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(view).showResetHint(COLUMN_DEPARTMENT, false); verify(view, never()).showSelectHint(COLUMN_DEPARTMENT, false); verify(listener).onFilterEnabled(eq(presenter), argument.capture()); verify(listener, never()).onRedraw(presenter); DataSetGroup dataSetGroup = argument.getValue(); List selectedIntervals = dataSetGroup.getSelectedIntervalList(); assertEquals(selectedIntervals.size(), 1); Interval selectedInterval = selectedIntervals.get(0); assertEquals(selectedInterval.getName(), "Management"); } @Test public void testMultipleSelect() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .multiple(true) .width(100) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDropDownDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); // Select an item presenter.addListener(listener); when(dropDownItem.getId()).thenReturn(1); presenter.onItemSelected(dropDownItem); // Select another item reset(view); reset(listener); when(dropDownItem.getId()).thenReturn(2); presenter.onItemSelected(dropDownItem); // Ensure data does not change verify(view, never()).clearItems(); verify(view, never()).addItem(any()); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(view).showResetHint(COLUMN_DEPARTMENT, true); verify(view, never()).showSelectHint(COLUMN_DEPARTMENT, true); verify(view).showCurrentSelection("Management ...", "Management, Sales "); verify(listener).onFilterEnabled(eq(presenter), argument.capture()); verify(listener, never()).onRedraw(presenter); DataSetGroup dataSetGroup = argument.getValue(); List selectedIntervals = dataSetGroup.getSelectedIntervalList(); assertEquals(selectedIntervals.size(), 2); Interval selectedInterval1 = selectedIntervals.get(0); Interval selectedInterval2 = selectedIntervals.get(1); assertEquals(selectedInterval1.getName(), "Management"); assertEquals(selectedInterval2.getName(), "Sales"); } @Test public void testFormatItemList() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .multiple(true) .width(90) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); String result = presenter.formatItemList(Arrays.asList("Sales", "Management", "IT"), 200); assertEquals(result, "Sales, Management, IT "); result = presenter.formatItemList(Arrays.asList("Sales", "Management", "IT")); assertEquals(result, "Sales, Management, IT "); result = presenter.formatItemList(Arrays.asList("Sales", "Management", "IT"), 150); assertEquals(result, "Sales, Managemen..."); result = presenter.formatItemList(Arrays.asList("Sales", "Management", "IT"), 130); assertEquals(result, "Sales, Managem..."); result = presenter.formatItemList(Arrays.asList("Sales", "Management", "IT"), 60); assertEquals(result, "Sales ..."); result = presenter.formatItemList(Arrays.asList("Sales", "Management", "IT"), 10); assertEquals(result, "S..."); } @Test public void testDrillDown() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(true, true, true) .multiple(false) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDropDownDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); reset(view); when(dropDownItem.getId()).thenReturn(1); presenter.addListener(listener); presenter.onItemSelected(dropDownItem); // Check filter notifications verify(listener).onFilterEnabled(eq(presenter), any(DataSetGroup.class)); verify(listener).onRedraw(presenter); // Check selector refreshes verify(view).clearItems(); verify(view, atLeastOnce()).showResetHint(COLUMN_DEPARTMENT, false); verify(view, never()).showSelectHint(COLUMN_DEPARTMENT, false); verify(view, times(1)).addItem(any()); } @Test public void testNullEntries() { // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DEPARTMENT)); expensesDataSet.setValueAt(0, column, null); // Create a selector displayer DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(departmentList); SelectorDropDownDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.addListener(listener); presenter.draw(); // Verify that null entries are not shown verify(view, times(5)).addItem(any()); verify(view, never()).addItem(null); // Select an item reset(listener); when(dropDownItem.getId()).thenReturn(1); presenter.onItemSelected(dropDownItem); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(listener).onFilterEnabled(eq(presenter), argument.capture()); DataSetGroup dataSetGroup = argument.getValue(); Interval selectedInterval = dataSetGroup.getSelectedIntervalList().get(0); assertEquals(selectedInterval.getName(), "Engineering"); } @Test public void testSortFixedMonthDefault() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.MONTH, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "1"); assertEquals(dataSet.getValueAt(11, 0), "12"); } @Test public void testSortFixedFirstMonth() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.MONTH, true).firstMonth(Month.FEBRUARY) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "2"); assertEquals(dataSet.getValueAt(11, 0), "1"); } @Test public void testSortFixedDayOfWeekDefault() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.DAY_OF_WEEK, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "2"); assertEquals(dataSet.getValueAt(6, 0), "1"); } @Test public void testSortFixedFirstDayOfWeek() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.DAY_OF_WEEK, true).firstDay(DayOfWeek.SUNDAY) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "1"); assertEquals(dataSet.getValueAt(6, 0), "7"); } @Test public void testSortFixedHour() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.HOUR, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "0"); assertEquals(dataSet.getValueAt(23, 0), "23"); } @Test public void testSortFixedMinute() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.MINUTE, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "0"); assertEquals(dataSet.getValueAt(59, 0), "59"); } @Test public void testSortFixedSecond() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.SECOND, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorDropDownDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "0"); assertEquals(dataSet.getValueAt(59, 0), "59"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/selector/SelectorLabelSetDisplayerTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import java.util.List; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.DisplayerListener; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class SelectorLabelSetDisplayerTest extends AbstractDisplayerTest { @Mock SyncBeanManager beanManager; @Mock SyncBeanDef labelItemBean; @Mock SelectorLabelItem labelItem; public SelectorLabelSetDisplayer createSelectorDisplayer(DisplayerSettings settings) { return initDisplayer(new SelectorLabelSetDisplayer(mock(SelectorLabelSetDisplayer.View.class), beanManager), settings); } @Before public void setUp() { when(beanManager.lookupBean(SelectorLabelItem.class)).thenReturn(labelItemBean); when(labelItemBean.newInstance()).thenReturn(labelItem); } @Test public void testDraw() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, false) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); SelectorLabelSetDisplayer.View view = presenter.getView(); presenter.draw(); verify(view).clearItems(); verify(view, times(5)).addItem(any()); // Verify the entries are sorted by default DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "Engineering"); assertEquals(dataSet.getValueAt(4, 0), "Support"); } @Test public void testNoData() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); SelectorLabelSetDisplayer.View view = presenter.getView(); presenter.draw(); verify(view).clearItems(); verify(view, never()).addItem(any()); } @Test public void testNullNotShown() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DEPARTMENT)); expensesDataSet.setValueAt(0, column, null); // ... and make sure it's not shown SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); SelectorLabelSetDisplayer.View view = presenter.getView(); presenter.draw(); verify(view, times(5)).addItem(any()); verify(view, never()).addItem(null); } @Test public void testSelectDisabled() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOff(true) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); DisplayerListener listener = mock(DisplayerListener.class); SelectorLabelSetDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); presenter.addListener(listener); presenter.onItemSelected(labelItem); // Check filter notifications verify(listener, never()).onFilterEnabled(eq(presenter), any(DataSetGroup.class)); verify(listener, never()).onRedraw(presenter); // Ensure data does not change verify(view, never()).clearItems(); verify(view, never()).addItem(any()); } @Test public void testSelectItem() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); SelectorLabelSetDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); // Select an item reset(view); when(labelItem.getId()).thenReturn(1); presenter.addListener(listener); presenter.onItemSelected(labelItem); // Ensure data does not change verify(view, never()).clearItems(); verify(view, never()).addItem(any()); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(listener).onFilterEnabled(eq(presenter), argument.capture()); verify(listener, never()).onRedraw(presenter); DataSetGroup dataSetGroup = argument.getValue(); List selectedIntervals = dataSetGroup.getSelectedIntervalList(); assertEquals(selectedIntervals.size(), 1); Interval selectedInterval = selectedIntervals.get(0); assertEquals(selectedInterval.getName(), "Management"); } @Test public void testMultipleSelect() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .multiple(true) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); SelectorLabelSetDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); // Select an item reset(view); presenter.addListener(listener); when(labelItem.getId()).thenReturn(1); presenter.onItemSelected(labelItem); when(labelItem.getId()).thenReturn(2); presenter.onItemSelected(labelItem); // Ensure data does not change verify(view, never()).clearItems(); verify(view, never()).addItem(any()); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(listener, times(2)).onFilterEnabled(eq(presenter), argument.capture()); verify(listener, never()).onRedraw(presenter); DataSetGroup dataSetGroup = argument.getValue(); List selectedIntervals = dataSetGroup.getSelectedIntervalList(); assertEquals(selectedIntervals.size(), 2); Interval selectedInterval1 = selectedIntervals.get(0); Interval selectedInterval2 = selectedIntervals.get(1); assertEquals(selectedInterval1.getName(), "Management"); assertEquals(selectedInterval2.getName(), "Sales"); } @Test public void testDrillDown() { DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(true, true, true) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); SelectorLabelSetDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); reset(view); when(labelItem.getId()).thenReturn(1); presenter.addListener(listener); presenter.onItemSelected(labelItem); // Check filter notifications verify(listener).onFilterEnabled(eq(presenter), any(DataSetGroup.class)); verify(listener).onRedraw(presenter); // Check selector refreshes verify(view).clearItems(); verify(view, times(1)).addItem(any()); } @Test public void testNullEntries() { // Insert a null entry into the dataset DataSet expensesDataSet = clientDataSetManager.getDataSet(EXPENSES); int column = expensesDataSet.getColumnIndex(expensesDataSet.getColumnById(COLUMN_DEPARTMENT)); expensesDataSet.setValueAt(0, column, null); // Create a selector displayer DisplayerSettings departmentList = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DEPARTMENT) .column(COLUMN_DEPARTMENT) .column(COLUMN_ID, AggregateFunctionType.COUNT) .filterOn(false, true, true) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(departmentList); SelectorLabelSetDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.addListener(listener); presenter.draw(); // Verify that null entries are not shown verify(view, times(5)).addItem(any()); verify(view, never()).addItem(null); // Select an item reset(listener); when(labelItem.getId()).thenReturn(1); presenter.onItemSelected(labelItem); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetGroup.class); verify(listener).onFilterEnabled(eq(presenter), argument.capture()); DataSetGroup dataSetGroup = argument.getValue(); Interval selectedInterval = dataSetGroup.getSelectedIntervalList().get(0); assertEquals(selectedInterval.getName(), "Engineering"); } @Test public void testSortFixedMonthDefault() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.MONTH, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "1"); assertEquals(dataSet.getValueAt(11, 0), "12"); } @Test public void testSortFixedFirstMonth() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.MONTH, true).firstMonth(Month.FEBRUARY) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "2"); assertEquals(dataSet.getValueAt(11, 0), "1"); } @Test public void testSortFixedDayOfWeekDefault() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.DAY_OF_WEEK, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "2"); assertEquals(dataSet.getValueAt(6, 0), "1"); } @Test public void testSortFixedFirstDayOfWeek() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.DAY_OF_WEEK, true).firstDay(DayOfWeek.SUNDAY) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "1"); assertEquals(dataSet.getValueAt(6, 0), "7"); } @Test public void testSortFixedHour() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.HOUR, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "0"); assertEquals(dataSet.getValueAt(23, 0), "23"); } @Test public void testSortFixedMinute() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.MINUTE, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "0"); assertEquals(dataSet.getValueAt(59, 0), "59"); } @Test public void testSortFixedSecond() { DisplayerSettings displayerSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .group(COLUMN_DATE).fixed(DateIntervalType.SECOND, true) .column(COLUMN_DATE) .column(COLUMN_ID, AggregateFunctionType.COUNT) .buildSettings(); SelectorLabelSetDisplayer presenter = createSelectorDisplayer(displayerSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); assertEquals(dataSet.getValueAt(0, 0), "0"); assertEquals(dataSet.getValueAt(59, 0), "59"); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/selector/SelectorSliderDisplayerTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.selector; import java.util.Date; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.engine.ClientDateFormatter; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.DisplayerListener; import org.dashbuilder.displayer.client.widgets.filter.DateParameterEditor; import org.dashbuilder.displayer.client.widgets.filter.NumberParameterEditor; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class SelectorSliderDisplayerTest extends AbstractDisplayerTest { @Mock ClientDateFormatter clientDateFormatter; @Mock DateParameterEditor minDateInputEditor; @Mock DateParameterEditor maxDateInputEditor; @Mock NumberParameterEditor minNumberInputEditor; @Mock NumberParameterEditor maxNumberInputEditor; DisplayerSettings dateSelectorSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .column(COLUMN_DATE) .width(200) .filterOn(false, true, false) .buildSettings(); DisplayerSettings numberSelectorSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .column(COLUMN_AMOUNT) .width(200) .filterOn(false, true, false) .buildSettings(); public SelectorSliderDisplayer createSelectorDisplayer(DisplayerSettings settings) { return initDisplayer(new SelectorSliderDisplayer(mock(SelectorSliderDisplayer.View.class), minDateInputEditor, maxDateInputEditor, minNumberInputEditor, maxNumberInputEditor), settings); } @Test public void testDateSelector() { SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); SelectorSliderDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.addListener(listener); presenter.draw(); verify(view).showSlider(anyDouble(), anyDouble(), anyDouble(), anyDouble(), anyDouble()); verify(view).margins(anyInt(), anyInt(), anyInt(), anyInt()); verify(view).setWidth(anyInt()); // Ensure no filter is executed if the range does not change presenter.onSliderChange(1, 6); reset(listener); presenter.onSliderChange(1, 6); verify(listener, never()).onFilterUpdate(eq(presenter), any(DataSetFilter.class), any(DataSetFilter.class)); } @Test public void testNumberSelector() { SelectorSliderDisplayer presenter = createSelectorDisplayer(numberSelectorSettings); SelectorSliderDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.addListener(listener); presenter.draw(); verify(view).showSlider(1, 1101, 1, 1, 1101); verify(view).margins(anyInt(), anyInt(), anyInt(), anyInt()); verify(view).setWidth(anyInt()); // Ensure no filter is executed if the range does not change presenter.onSliderChange(1, 6); reset(listener); presenter.onSliderChange(1, 6); verify(listener, never()).onFilterUpdate(eq(presenter), any(DataSetFilter.class), any(DataSetFilter.class)); } @Test public void testNoData() { DisplayerSettings dateSelectorSettings = DisplayerSettingsFactory.newSelectorSettings() .dataset(EXPENSES) .filter(COLUMN_DATE, FilterFactory.isNull()) .column(COLUMN_DATE) .buildSettings(); SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); SelectorSliderDisplayer.View view = presenter.getView(); presenter.draw(); verify(view).noData(); verify(view, never()).showSlider(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); } @Test public void testSelectDisabled() { dateSelectorSettings.setFilterEnabled(false); SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); DisplayerListener listener = mock(DisplayerListener.class); SelectorSliderDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); presenter.addListener(listener); presenter.onSliderChange(0, 1); // Check filter notifications verify(listener, never()).onFilterEnabled(eq(presenter), any(DataSetFilter.class)); verify(listener, never()).onRedraw(presenter); // Ensure data does not change verify(view, never()).showSlider(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); } @Test public void testDateRangeSelection() { SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); SelectorSliderDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); // Select a range reset(view); presenter.addListener(listener); presenter.onSliderChange(1328050800000d, 1333231200000d); // Ensure data does not change verify(view, never()).showSlider(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetFilter.class); verify(listener).onFilterUpdate(eq(presenter), any(), argument.capture()); verify(listener, never()).onRedraw(presenter); DataSetFilter dataSetFilter = argument.getValue(); CoreFunctionFilter columnFilter = (CoreFunctionFilter) dataSetFilter.getColumnFilterList().get(0); assertEquals(columnFilter.getColumnId(), COLUMN_DATE); assertEquals(columnFilter.getType(), CoreFunctionType.BETWEEN); assertEquals(columnFilter.getParameters().size(), 2); assertEquals(columnFilter.getParameters().get(0), new Date(1328050800000L)); assertEquals(columnFilter.getParameters().get(1), new Date(1333231200000L)); // Select another range reset(listener); presenter.onSliderChange(1328050800000d, 1335823200000d); verify(listener).onFilterUpdate(eq(presenter), any(), argument.capture()); dataSetFilter = argument.getValue(); columnFilter = (CoreFunctionFilter) dataSetFilter.getColumnFilterList().get(0); assertEquals(columnFilter.getParameters().get(0), new Date(1328050800000L)); assertEquals(columnFilter.getParameters().get(1), new Date(1335823200000L)); } @Test public void testNumberRangeSelection() { SelectorSliderDisplayer presenter = createSelectorDisplayer(numberSelectorSettings); SelectorSliderDisplayer.View view = presenter.getView(); DisplayerListener listener = mock(DisplayerListener.class); presenter.draw(); // Select a range reset(view); presenter.addListener(listener); presenter.onSliderChange(1, 101); // Ensure data does not change verify(view, never()).showSlider(anyInt(), anyInt(), anyInt(), anyInt(), anyInt()); // Verify the item selected is correct ArgumentCaptor argument = ArgumentCaptor.forClass(DataSetFilter.class); verify(listener).onFilterUpdate(eq(presenter), any(), argument.capture()); verify(listener, never()).onRedraw(presenter); DataSetFilter dataSetFilter = argument.getValue(); CoreFunctionFilter columnFilter = (CoreFunctionFilter) dataSetFilter.getColumnFilterList().get(0); assertEquals(columnFilter.getColumnId(), COLUMN_AMOUNT); assertEquals(columnFilter.getType(), CoreFunctionType.BETWEEN); assertEquals(columnFilter.getParameters().size(), 2); assertEquals(columnFilter.getParameters().get(0), 1d); assertEquals(columnFilter.getParameters().get(1), 101d); // Select another range reset(listener); presenter.onSliderChange(51, 101); verify(listener).onFilterUpdate(eq(presenter), any(), argument.capture()); dataSetFilter = argument.getValue(); columnFilter = (CoreFunctionFilter) dataSetFilter.getColumnFilterList().get(0); assertEquals(columnFilter.getParameters().get(0), 51d); assertEquals(columnFilter.getParameters().get(1), 101d); } @Test public void testIgnoreNullDates() { expensesDataSet.setValueAt(0, 4, null); expensesDataSet.setValueAt(49, 4, null); SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); Object min = dataSet.getValueAt(0, 0); Object max = dataSet.getValueAt(0, 1); assertEquals(min, expensesDataSet.getValueAt(48, 4)); assertEquals(max, expensesDataSet.getValueAt(1, 4)); } @Test public void testIgnoreNullNumbers() { expensesDataSet.setValueAt(0, 5, null); SelectorSliderDisplayer presenter = createSelectorDisplayer(numberSelectorSettings); presenter.draw(); DataSet dataSet = presenter.getDataSetHandler().getLastDataSet(); Object min = dataSet.getValueAt(0, 0); Object max = dataSet.getValueAt(0, 1); assertEquals(min, 1.1d); assertEquals(max, 1100.1d); } @Test public void testDateAllNullNoData() { for (int i = 0; i < 50; i++) { expensesDataSet.setValueAt(i, 4, null); } SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); presenter.draw(); verify(presenter.getView()).noData(); } @Test public void testNumberAllNullNoData() { for (int i = 0; i < 50; i++) { expensesDataSet.setValueAt(i, 5, null); } SelectorSliderDisplayer presenter = createSelectorDisplayer(numberSelectorSettings); presenter.draw(); verify(presenter.getView()).noData(); } @Test public void testOnMinDateEditorChanged() { SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); SelectorSliderDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); presenter.onMinDateInputFocus(); verify(view).setSliderEnabled(false); reset(view); when(minDateInputEditor.getValue()).thenReturn(new Date()); presenter.onMinDateInputChange(); verify(view).showSlider(anyDouble(), anyDouble(), anyDouble(), anyDouble(), anyDouble()); verify(view).setSliderEnabled(true); } @Test public void testOnMaxDateEditorChanged() { SelectorSliderDisplayer presenter = createSelectorDisplayer(dateSelectorSettings); SelectorSliderDisplayer.View view = presenter.getView(); presenter.draw(); reset(view); presenter.onMaxDateInputFocus(); verify(view).setSliderEnabled(false); reset(view); when(maxDateInputEditor.getValue()).thenReturn(new Date()); presenter.onMaxDateInputChange(); verify(view).showSlider(anyDouble(), anyDouble(), anyDouble(), anyDouble(), anyDouble()); verify(view).setSliderEnabled(true); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/table/TableDisplayerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.table; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.common.client.widgets.FilterLabel; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.DisplayerListener; import org.dashbuilder.displayer.client.formatter.ValueFormatter; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.mvp.Command; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.COUNT; import static org.dashbuilder.dataset.group.AggregateFunctionType.MIN; import static org.dashbuilder.dataset.sort.SortOrder.ASCENDING; import static org.dashbuilder.dataset.sort.SortOrder.DESCENDING; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class TableDisplayerTest extends AbstractDisplayerTest { public TableDisplayer createTableDisplayer(DisplayerSettings settings) { return initDisplayer(new TableDisplayer(mock(TableDisplayer.View.class), mock(FilterLabelSet.class)), settings); } @Mock DisplayerListener displayerListener; @Mock Command selectCommand; @Mock FilterLabel filterLabel; public void resetFilterLabelSet(FilterLabelSet filterLabelSet) { reset(filterLabelSet); doAnswer(invocationOnMock -> filterLabel).when(filterLabelSet).addLabel(anyString()); } @Test public void testTableDraw() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tableOrderDefault(COLUMN_DEPARTMENT, SortOrder.DESCENDING) .tableOrderEnabled(true) .tablePageSize(10) .tableWidth(1000) .filterOn(true, true, true) .allowCsvExport(true) .allowExcelExport(false) .buildSettings(); TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View tableView = table.getView(); FilterLabelSet filterLabelSet = table.getFilterLabelSet(); table.draw(); verify(tableView).setWidth(1000); verify(tableView).setSortEnabled(true); verify(tableView, times(2)).setTotalRows(50, true); verify(tableView).createTable(10, filterLabelSet); verify(tableView).addColumn(ColumnType.NUMBER, COLUMN_ID, COLUMN_ID, 0, false, true); verify(tableView).addColumn(ColumnType.LABEL, COLUMN_CITY, COLUMN_CITY, 1, true, true); verify(tableView).addColumn(ColumnType.LABEL, COLUMN_DEPARTMENT, COLUMN_DEPARTMENT, 2, true, true); verify(tableView).addColumn(ColumnType.LABEL, COLUMN_EMPLOYEE, COLUMN_EMPLOYEE, 3, true, true); verify(tableView).addColumn(ColumnType.DATE, COLUMN_DATE, COLUMN_DATE, 4, false, true); verify(tableView).addColumn(ColumnType.NUMBER, COLUMN_AMOUNT, COLUMN_AMOUNT, 5, false, true); verify(tableView).setExportToCsvEnabled(true); verify(tableView).setExportToXlsEnabled(false); verify(tableView).gotoFirstPage(); } @Test public void testEmptyTableDraw() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .tablePageSize(10) .buildSettings(); TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View tableView = table.getView(); FilterLabelSet filterLabelSet = table.getFilterLabelSet(); table.draw(); verify(tableView).createTable(10, filterLabelSet); verify(tableView, times(2)).setTotalRows(0, true); verify(tableView).setPagerEnabled(false); verify(tableView, never()).setPagerEnabled(true); reset(tableView); table.redraw(); verify(tableView, never()).setPagerEnabled(true); } @Test public void testTableSort() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .tableOrderDefault(COLUMN_ID, SortOrder.DESCENDING) .buildSettings(); // Sorted by ID descending by default TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View tableView = table.getView(); table.draw(); assertEquals(table.getDataSetHandler().getLastDataSet().getValueAt(0, 0), 50d); // Sort disabled (no effect) allRows.setTableSortEnabled(false); table = createTableDisplayer(allRows); tableView = table.getView(); table.draw(); reset(tableView); table.sortBy(COLUMN_ID, SortOrder.DESCENDING); verify(tableView, never()).redrawTable(); assertEquals(table.getDataSetHandler().getLastDataSet().getValueAt(0, 0), 50d); // Sort enabled allRows.setTableSortEnabled(true); table = createTableDisplayer(allRows); tableView = table.getView(); table.draw(); reset(tableView); table.sortBy(COLUMN_ID, SortOrder.ASCENDING); verify(tableView).redrawTable(); assertEquals(table.getDataSetHandler().getLastDataSet().getValueAt(0, 0), 1d); } @Test public void testSelectCellDisabled() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .tableOrderDefault(COLUMN_ID, SortOrder.DESCENDING) .filterOff(false) .buildSettings(); TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View view = table.getView(); FilterLabelSet filterLabelSet = table.getFilterLabelSet(); table.addListener(displayerListener); table.addOnCellSelectedCommand(selectCommand); table.draw(); reset(view); reset(displayerListener); resetFilterLabelSet(filterLabelSet); table.selectCell(COLUMN_DEPARTMENT, 3); verify(selectCommand, never()).execute(); verify(view, never()).gotoFirstPage(); verify(filterLabelSet, never()).addLabel(anyString()); verify(displayerListener, never()).onRedraw(table); assertNull(table.getSelectedCellColumn()); assertNull(table.getSelectedCellRow()); } @Test public void testSelectCellNoDrillDown() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .tableOrderDefault(COLUMN_ID, SortOrder.DESCENDING) .filterOn(false, true, true) .buildSettings(); TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View view = table.getView(); FilterLabelSet filterLabelSet = table.getFilterLabelSet(); table.addListener(displayerListener); table.addOnCellSelectedCommand(selectCommand); table.draw(); reset(view); reset(displayerListener); resetFilterLabelSet(filterLabelSet); table.selectCell(COLUMN_DEPARTMENT, 3); verify(selectCommand).execute(); verify(view, never()).gotoFirstPage(); verify(filterLabelSet).addLabel(anyString()); verify(displayerListener, never()).onRedraw(table); assertEquals(table.getSelectedCellColumn(), COLUMN_DEPARTMENT); assertEquals(table.getSelectedCellRow(), new Integer(3)); } @Test public void testSelectCellDrillDown() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .tableOrderDefault(COLUMN_ID, SortOrder.DESCENDING) .filterOn(true, true, true) .buildSettings(); TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View view = table.getView(); FilterLabelSet filterLabelSet = table.getFilterLabelSet(); table.addListener(displayerListener); table.addOnCellSelectedCommand(selectCommand); table.draw(); reset(view); reset(displayerListener); resetFilterLabelSet(filterLabelSet); table.selectCell(COLUMN_DEPARTMENT, 3); verify(view, atLeastOnce()).gotoFirstPage(); verify(view).redrawTable(); verify(filterLabelSet, atLeastOnce()).addLabel(anyString()); verify(view, times(2)).setTotalRows(11, true); verify(displayerListener).onRedraw(table); verify(selectCommand).execute(); assertEquals(table.getSelectedCellColumn(), COLUMN_DEPARTMENT); assertEquals(table.getSelectedCellRow(), new Integer(3)); } @Test public void testSelectCellReset() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .tableOrderDefault(COLUMN_ID, SortOrder.DESCENDING) .filterOn(false, true, true) .buildSettings(); TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View view = table.getView(); FilterLabelSet filterLabelSet = table.getFilterLabelSet(); table.addListener(displayerListener); table.addOnCellSelectedCommand(selectCommand); table.draw(); resetFilterLabelSet(filterLabelSet); table.selectCell(COLUMN_DEPARTMENT, 3); reset(view); reset(selectCommand); reset(displayerListener); resetFilterLabelSet(filterLabelSet); table.selectCell(COLUMN_DEPARTMENT, 3); verify(selectCommand).execute(); verify(view, never()).gotoFirstPage(); verify(filterLabelSet, never()).addLabel(anyString()); verify(displayerListener, never()).onRedraw(table); assertNull(table.getSelectedCellColumn()); assertNull(table.getSelectedCellRow()); } @Test public void testSelectCellCommands() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .tableOrderDefault(COLUMN_ID, SortOrder.DESCENDING) .filterOn(false, true, true) .buildSettings(); TableDisplayer table = createTableDisplayer(allRows); TableDisplayer.View view = table.getView(); FilterLabelSet filterLabelSet = table.getFilterLabelSet(); table.addListener(displayerListener); table.addOnCellSelectedCommand(selectCommand); final Command selectedCommand = mock(Command.class); table.addOnCellSelectedCommand(selectedCommand); table.draw(); resetFilterLabelSet(filterLabelSet); table.selectCell(COLUMN_DEPARTMENT, 3); verify(selectCommand).execute(); verify(selectedCommand).execute(); } @Test public void testFormatEmpty() { TableDisplayer table = createTableDisplayer(DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .buildSettings()); table.addFormatter(COLUMN_EMPLOYEE, new ValueFormatter() { public String formatValue(DataSet dataSet, int row, int column) { return "test"; } public String formatValue(Object value) { return "test"; } }); table.draw(); String value = table.formatValue(100, 3); assertEquals(value, "test"); } @Test public void test_DASHBUILDE_20_Fix() { DisplayerSettings groupedTable = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .group(COLUMN_CITY) .column(COLUMN_CITY, "City") .column(COUNT, "#Expenses").format("Number of expenses", "#,##0") .column(COLUMN_AMOUNT, MIN).format("Min", "$ #,###") .column(COLUMN_AMOUNT, MIN).format("Min", "$ #,###") .column(COLUMN_AMOUNT, MIN).format("Min", "$ #,###") .column(COLUMN_AMOUNT, MIN).format("Min", "$ #,###") .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(COLUMN_CITY, DESCENDING) .filterOn(false, true, true) .buildSettings(); TableDisplayer table = createTableDisplayer(groupedTable); table.addListener(displayerListener); table.draw(); table.sortBy("#Expenses", ASCENDING); verify(displayerListener, never()).onError(eq(table), any(ClientRuntimeError.class)); } @Test public void testIsTotalRowsExactSQL() { final DataSet dataSet = mock(DataSet.class); final DataSetDef dataSetDef = new DataSetDef(); dataSetDef.setProvider(DataSetProviderType.SQL); when(dataSet.getDefinition()).thenReturn(dataSetDef); TableDisplayer table = createTableDisplayer(DisplayerSettingsFactory.newTableSettings().tablePageSize(10).buildSettings()); assertTrue(table.isTotalRowsExact(dataSet, 5)); assertTrue(table.isTotalRowsExact(dataSet, 10)); assertTrue(table.isTotalRowsExact(dataSet, 15)); } @Test public void testIsTotalRowsExactRemote() { final DataSet dataSet = mock(DataSet.class); final DataSetDef dataSetDef = new DataSetDef(); dataSetDef.setProvider(() -> "REMOTE"); when(dataSet.getDefinition()).thenReturn(dataSetDef); TableDisplayer table = createTableDisplayer(DisplayerSettingsFactory.newTableSettings().tablePageSize(10).buildSettings()); assertTrue(table.isTotalRowsExact(dataSet, 5)); assertFalse(table.isTotalRowsExact(dataSet, 10)); assertFalse(table.isTotalRowsExact(dataSet, 15)); } @Test public void testIsPagerEnabledRemote() { final DataSet dataSet = mock(DataSet.class); final DataSetDef dataSetDef = new DataSetDef(); dataSetDef.setProvider(() -> "REMOTE"); when(dataSet.getDefinition()).thenReturn(dataSetDef); TableDisplayer table = createTableDisplayer(DisplayerSettingsFactory.newTableSettings().tablePageSize(10).buildSettings()); assertFalse(table.isPagerEnabled(dataSet, 5)); assertTrue(table.isPagerEnabled(dataSet, 10)); verify(dataSet, never()).getRowCountNonTrimmed(); } @Test public void testIsPagerEnabledSQL() { final DataSet dataSet = mock(DataSet.class); final DataSetDef dataSetDef = new DataSetDef(); dataSetDef.setProvider(DataSetProviderType.SQL); when(dataSet.getDefinition()).thenReturn(dataSetDef); when(dataSet.getRowCountNonTrimmed()).thenReturn(5, 10, 15); TableDisplayer table = createTableDisplayer(DisplayerSettingsFactory.newTableSettings().tablePageSize(10).buildSettings()); assertFalse(table.isPagerEnabled(dataSet, 5)); assertFalse(table.isPagerEnabled(dataSet, 10)); assertTrue(table.isPagerEnabled(dataSet, 15)); } @Test public void testIsRemoteProvider() { final DataSet dataSet = mock(DataSet.class); final DataSetDef dataSetDefSQL = new DataSetDef(); dataSetDefSQL.setProvider(DataSetProviderType.SQL); final DataSetDef dataSetDefRemote = new DataSetDef(); dataSetDefRemote.setProvider(() -> "REMOTE"); when(dataSet.getDefinition()).thenReturn(new DataSetDef(), dataSetDefSQL, dataSetDefRemote); TableDisplayer table = createTableDisplayer(null); //No provider set assertFalse(table.isRemoteProvider(dataSet)); //Provider SQL assertFalse(table.isRemoteProvider(dataSet)); //Provider REMOTE assertTrue(table.isRemoteProvider(dataSet)); } @Test public void testPageSize() { TableDisplayer table = createTableDisplayer(DisplayerSettingsFactory.newTableSettings().tablePageSize(10).buildSettings()); assertEquals(10, table.getPageSize()); when(table.getView().getPageSize()).thenReturn(20); assertEquals(20, table.getPageSize()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-default/src/test/java/org/dashbuilder/renderer/client/table/TableDisplayerViewTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.client.table; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.view.client.HasData; import com.google.gwt.view.client.Range; import com.google.gwtmockito.GwtMockitoTestRunner; import com.google.gwtmockito.WithClassesToStub; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.uberfire.ext.widgets.common.client.tables.PagedTable; import org.uberfire.ext.widgets.table.client.DataGrid; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) @WithClassesToStub(DataGrid.class) public class TableDisplayerViewTest { @Mock PagedTable table; @InjectMocks TableDisplayerView tableDisplayerView; @Test public void testCreateTable() { final HasWidgets hasWidgets = mock(HasWidgets.class); when(table.getRightToolbar()).thenReturn(hasWidgets); tableDisplayerView.setupToolbar(); verify(hasWidgets, times(2)).add(any()); } @Test public void testCreateTableUsingHorizontalPanel() { final HorizontalPanel panel = mock(HorizontalPanel.class); when(table.getRightToolbar()).thenReturn(panel); tableDisplayerView.setupToolbar(); verify(panel).insert(any(), eq(0)); verify(panel).insert(any(), eq(1)); } @Test public void testCurrentPageForNextPageWithoutTotalCount(){ final HasData display = mock(HasData.class); when(table.getRowCount()).thenReturn(1); when(display.getVisibleRange()).thenReturn(new Range(10, 10)); assertEquals(1, tableDisplayerView.tableProvider.getCurrentPageRows(display).size()); } @Test public void testCurrentPageForNextPageWithTotalCount(){ final HasData display = mock(HasData.class); when(table.getRowCount()).thenReturn(11); when(display.getVisibleRange()).thenReturn(new Range(10, 10)); assertEquals(1, tableDisplayerView.tableProvider.getCurrentPageRows(display).size()); } @Test public void testCurrentPageForNextPageWithoutRows(){ final HasData display = mock(HasData.class); when(table.getRowCount()).thenReturn(0); when(display.getVisibleRange()).thenReturn(new Range(10, 10)); assertEquals(0, tableDisplayerView.tableProvider.getCurrentPageRows(display).size()); } @Test public void testCurrentPage(){ final HasData display = mock(HasData.class); when(table.getRowCount()).thenReturn(5); when(display.getVisibleRange()).thenReturn(new Range(0, 10)); assertEquals(5, tableDisplayerView.tableProvider.getCurrentPageRows(display).size()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/README.md ================================================ Google Charts Renderer for Dashbuilder -- This project is a Dashbuilder renderer implementation. It is not provided by default in Dashbuilder, Business Central, jBPM WB or Drools WB distribution. The default implementation is `dashbuilder-renderer-c3`. Users that want to use Google Renderer again must build the target web application from sources after including google renderer JAR. For example, if you want the Google Charts back in Business Central you must: 1) Go to `kie-wb-distributions/business-central-parent/business-central-webapp` and modify `pom.xml` to add google charts back: ~~~ ... ... org.dashbuilder dashbuilder-renderer-google provided ... ... org.codehaus.mojo gwt-maven-plugin ... org.dashbuilder:dashbuilder-renderer-google ... ... ~~~ 2) Also add the GCharts module (`org.dashbuilder.renderer.GChartsRenderer`) to `kie-wb-distributions/business-central-parent/business-central-webapp/src/main/resources/org/kie/bc/KIEWebapp.gwt.xml`: ~~~ ... ... ~~~ 3) On `business-central-webapp` run `mvn clean install`. It will build the business-central-webapp WAR. After the build finishes you can build a distribution WAR by building some of the projects in `kie-wb-distributions/business-central-parent/business-central-distribution-wars` 4) Finally make sure to select Google Charts using the system property `org.dashbuilder.renderer.default=gwtcharts` when starting the server were Business Central is installed. If you don't do this C3 will still be used. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-renderers 7.75.0-SNAPSHOT dashbuilder-renderer-google jar Dashbuilder Renderer Google Dashbuilder Renderer for the Google Visualization API com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 com.googlecode.gwt-charts gwt-charts org.jboss.errai errai-ioc org.jboss.errai errai-common org.jboss.errai errai-ui org.uberfire uberfire-api org.dashbuilder dashbuilder-common-client org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-client org.uberfire uberfire-testing-utils test org.kie.soup kie-soup-dataset-api test-jar test org.dashbuilder dashbuilder-dataset-client test-jar test org.dashbuilder dashbuilder-displayer-client test-jar test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleAreaChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSubType; @Dependent public class GoogleAreaChartDisplayer extends GoogleCategoriesDisplayer { public interface View extends GoogleCategoriesDisplayer.View { void setIsStacked(boolean isStacked); } private View view; @Inject public GoogleAreaChartDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxGroups(1) .setMinColumns(2) .setMaxColumns(10) .setExtraColumnsAllowed(true) .setExtraColumnsType(ColumnType.NUMBER) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP ) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } public boolean isStacked() { return DisplayerSubType.AREA_STACKED.equals(displayerSettings.getSubtype()); } @Override protected void createVisualization() { view.setIsStacked(isStacked()); super.createVisualization(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleAreaChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.corechart.AreaChart; import com.googlecode.gwt.charts.client.corechart.AreaChartOptions; import com.googlecode.gwt.charts.client.corechart.CoreChartWidget; import com.googlecode.gwt.charts.client.options.Animation; import com.googlecode.gwt.charts.client.options.AnimationEasing; public class GoogleAreaChartDisplayerView extends GoogleCategoriesDisplayerView implements GoogleAreaChartDisplayer.View { protected boolean isStacked = true; @Override public void setIsStacked(boolean isStacked) { this.isStacked = isStacked; } @Override protected CoreChartWidget _createChart() { return new AreaChart(); } @Override protected AreaChartOptions createOptions() { AreaChartOptions options = AreaChartOptions.create(); options.setWidth(width); options.setHeight(height); options.setBackgroundColor(bgColor); options.setLegend(createChartLegend()); options.setChartArea(createChartArea()); options.setColors(colors); options.setIsStacked(isStacked); options.setHAxis(createHAxis()); options.setVAxis(createVAxis()); if (animationOn) { Animation anim = Animation.create(); anim.setDuration(animationDuration); anim.setEasing(AnimationEasing.IN_AND_OUT); options.setAnimation(anim); } return options; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleBarChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.DisplayerSubType; @Dependent public class GoogleBarChartDisplayer extends GoogleCategoriesDisplayer { public interface View extends GoogleCategoriesDisplayer.View { void setIsBar(boolean isBar); void setIsStacked(boolean isStacked); } private View view; @Inject public GoogleBarChartDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(10) .setMinColumns(2) .setExtraColumnsAllowed(true) .setExtraColumnsType( ColumnType.NUMBER) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } public boolean isBarChart() { return displayerSettings.getSubtype() == null || DisplayerSubType.BAR.equals(displayerSettings.getSubtype()) || DisplayerSubType.BAR_STACKED.equals(displayerSettings.getSubtype()); } public boolean isStacked() { return displayerSettings.getSubtype() != null && (DisplayerSubType.BAR_STACKED.equals(displayerSettings.getSubtype()) || DisplayerSubType.COLUMN_STACKED.equals(displayerSettings.getSubtype())); } @Override protected void createVisualization() { view.setIsBar(isBarChart()); view.setIsStacked(isStacked()); super.createVisualization(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleBarChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.corechart.BarChart; import com.googlecode.gwt.charts.client.corechart.BarChartOptions; import com.googlecode.gwt.charts.client.corechart.ColumnChart; import com.googlecode.gwt.charts.client.corechart.ColumnChartOptions; import com.googlecode.gwt.charts.client.corechart.CoreChartWidget; import com.googlecode.gwt.charts.client.options.Animation; import com.googlecode.gwt.charts.client.options.AnimationEasing; import com.googlecode.gwt.charts.client.options.CoreOptions; import com.googlecode.gwt.charts.client.options.Options; public class GoogleBarChartDisplayerView extends GoogleCategoriesDisplayerView implements GoogleBarChartDisplayer.View { protected boolean isBar = true; protected boolean isStacked = true; @Override public void setIsBar(boolean isBar) { this.isBar = isBar; } @Override public void setIsStacked(boolean isStacked) { this.isStacked = isStacked; } @Override protected CoreChartWidget _createChart() { return isBar ? new BarChart() : new ColumnChart(); } @Override protected Options createOptions() { return isBar ? createBarOptions() : createColumnOptions(); } protected CoreOptions createBarOptions() { BarChartOptions options = BarChartOptions.create(); options.setWidth(width); options.setHeight(height); options.setBackgroundColor(bgColor); options.setLegend(createChartLegend()); options.setIsStacked(isStacked); options.setHAxis(createHAxis()); options.setVAxis(createVAxis()); if (animationOn) { Animation anim = Animation.create(); anim.setDuration(animationDuration); anim.setEasing(AnimationEasing.IN_AND_OUT); options.setAnimation(anim); } // TODO: options.set3D(displayerSettings.is3d()); options.setChartArea(createChartArea()); options.setColors(colors); return options; } protected CoreOptions createColumnOptions() { ColumnChartOptions options = ColumnChartOptions.create(); options.setWidth(width); options.setHeight(height); options.setBackgroundColor(bgColor); options.setLegend(createChartLegend()); options.setIsStacked(isStacked); options.setChartArea(createChartArea()); options.setColors(colors); if (showXLabels) { options.setHAxis(createHAxis()); } if (showYLabels) { options.setVAxis(createVAxis()); } if (animationOn) { Animation anim = Animation.create(); anim.setDuration(animationDuration); anim.setEasing(AnimationEasing.IN_AND_OUT); options.setAnimation(anim); } return options; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleBubbleChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; @Dependent public class GoogleBubbleChartDisplayer extends GoogleCategoriesDisplayer { public interface View extends GoogleCategoriesDisplayer.View { String getXAxisColumnTitle(); String getYAxisColumnTitle(); String getBubbleColorColumnTitle(); String getBubbleSizeColumnTitle(); } private View view; @Inject public GoogleBubbleChartDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(5) .setMinColumns(5) .setExtraColumnsAllowed(false) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTitle(1, view.getXAxisColumnTitle()) .setColumnTitle(2, view.getYAxisColumnTitle()) .setColumnTitle(3, view.getBubbleColorColumnTitle()) .setColumnTitle(4, view.getBubbleSizeColumnTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER, ColumnType.NUMBER, ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleBubbleChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.corechart.BubbleChart; import com.googlecode.gwt.charts.client.corechart.BubbleChartOptions; import com.googlecode.gwt.charts.client.corechart.CoreChartWidget; import com.googlecode.gwt.charts.client.options.Animation; import com.googlecode.gwt.charts.client.options.AnimationEasing; import com.googlecode.gwt.charts.client.options.Options; import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants; public class GoogleBubbleChartDisplayerView extends GoogleCategoriesDisplayerView implements GoogleBubbleChartDisplayer.View { @Override public String getColumnsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Values(); } @Override public String getXAxisColumnTitle() { return GoogleDisplayerConstants.INSTANCE.googleBubbleDisplayer_XAxis(); } @Override public String getYAxisColumnTitle() { return GoogleDisplayerConstants.INSTANCE.googleBubbleDisplayer_YAxis(); } @Override public String getBubbleColorColumnTitle() { return GoogleDisplayerConstants.INSTANCE.googleBubbleDisplayer_BubbleColor(); } @Override public String getBubbleSizeColumnTitle() { return GoogleDisplayerConstants.INSTANCE.googleBubbleDisplayer_BubbleSize(); } @Override protected CoreChartWidget _createChart() { return new BubbleChart(); } @Override protected Options createOptions() { BubbleChartOptions options = BubbleChartOptions.create(); options.setWidth(width); options.setHeight(height); options.setBackgroundColor(bgColor); options.setChartArea(createChartArea()); options.setLegend(createChartLegend()); options.setColors(colors); options.setHAxis(createHAxis()); options.setVAxis(createVAxis()); if (animationOn) { Animation anim = Animation.create(); anim.setDuration(animationDuration); anim.setEasing(AnimationEasing.IN_AND_OUT); options.setAnimation(anim); } return options; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleCategoriesDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import java.util.List; import org.dashbuilder.common.client.widgets.FilterLabelSet; public abstract class GoogleCategoriesDisplayer extends GoogleChartDisplayer { public interface View

    extends GoogleChartDisplayer.View

    { void setFilterEnabled(boolean filterEnabled); void setBgColor(String bgColor); void setShowXLabels(boolean showXLabels); void setShowYLabels(boolean showYLabels); void setXAxisTitle(String xAxisTitle); void setXAxisAngle(int xAxisAngle); void setYAxisTitle(String yAxisTitle); void setColors(String[] colors); void setAnimationOn(boolean animationOn); void setAnimationDuration(int animationDuration); void createChart(); void nodata(); void drawChart(); } public static final String[] COLOR_ARRAY = new String[] { "#0088CE", "#CC0000", "#EC7A08", "#3F9C35", "#F0AB00", "#703FEC", "#007A87", "#92D400", "#35CAED", "#00659C", "#A30000", "#B35C00", "#B58100", "#6CA100", "#2D7623", "#005C66", "#008BAD", "#40199A"}; public static final String COLOR_NOT_SELECTED = "#8B8D8F"; public GoogleCategoriesDisplayer(FilterLabelSet filterLabelSet) { super(filterLabelSet); } protected String[] createColorArray() { String[] colorArray = new String[dataSet.getRowCount()]; for (int i = 0, j = 0; i < dataSet.getRowCount(); i++, j++) { if (j >= COLOR_ARRAY.length) j = 0; colorArray[i] = COLOR_ARRAY[j]; List selectedIdxs = filterIndexes(dataSet.getColumnByIndex(0).getId()); if (!displayerSettings.isFilterSelfApplyEnabled() && selectedIdxs != null && !selectedIdxs.isEmpty() && !selectedIdxs.contains(i)) { colorArray[i] = COLOR_NOT_SELECTED; } } return colorArray; } @Override protected void createVisualization() { super.createVisualization(); getView().createChart(); getView().setAnimationOn(true); getView().setAnimationDuration(700); getView().setFilterEnabled(displayerSettings.isFilterEnabled()); getView().setBgColor(displayerSettings.getChartBackgroundColor()); getView().setShowXLabels(displayerSettings.isXAxisShowLabels()); getView().setShowYLabels(displayerSettings.isYAxisShowLabels()); getView().setXAxisTitle(displayerSettings.getXAxisTitle()); getView().setXAxisAngle(displayerSettings.getXAxisLabelsAngle()); getView().setYAxisTitle(displayerSettings.getYAxisTitle()); drawChart(); } @Override protected void updateVisualization() { super.updateFilterStatus(); drawChart(); } protected void drawChart() { if (dataSet.getRowCount() == 0) { getView().nodata(); } else { super.pushDataToView(); getView().setColors(createColorArray()); getView().drawChart(); } } // View notifications public void onCategorySelected(String columnId, int row) { Integer maxSelections = displayerSettings.isFilterSelfApplyEnabled() ? null : dataSet.getRowCount(); filterUpdate(columnId, row, maxSelections); // Update the displayer in order to reflect the current selection // (only if not has already been redrawn as part of the drill-down processing in the above filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleCategoriesDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArray; import com.google.gwt.user.client.ui.FlowPanel; import com.googlecode.gwt.charts.client.Selection; import com.googlecode.gwt.charts.client.corechart.CoreChartWidget; import com.googlecode.gwt.charts.client.event.SelectEvent; import com.googlecode.gwt.charts.client.event.SelectHandler; import com.googlecode.gwt.charts.client.geochart.GeoChart; import com.googlecode.gwt.charts.client.options.ChartArea; import com.googlecode.gwt.charts.client.options.HAxis; import com.googlecode.gwt.charts.client.options.Options; import com.googlecode.gwt.charts.client.options.VAxis; import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants; import org.gwtbootstrap3.client.ui.Label; public abstract class GoogleCategoriesDisplayerView

    extends GoogleChartDisplayerView

    implements GoogleCategoriesDisplayer.View

    { private CoreChartWidget chart = null; protected String bgColor = null; protected boolean showXLabels = false; protected boolean showYLabels = false; protected String xAxisTitle = null; protected String yAxisTitle = null; protected int xAxisAngle = 0; protected boolean animationOn = false; protected int animationDuration = 700; protected String[] colors = null; @Override public void setBgColor(String bgColor) { this.bgColor = bgColor; } @Override public void setShowXLabels(boolean showXLabels) { this.showXLabels = showXLabels; } @Override public void setShowYLabels(boolean showYLabels) { this.showYLabels = showYLabels; } @Override public void setXAxisTitle(String xAxisTitle) { this.xAxisTitle = xAxisTitle; } @Override public void setXAxisAngle(int xAxisAngle) { this.xAxisAngle = xAxisAngle; } @Override public void setYAxisTitle(String yAxisTitle) { this.yAxisTitle = yAxisTitle; } @Override public void setColors(String[] colors) { this.colors = colors; } @Override public void setFilterEnabled(boolean enabled) { if (enabled) { checkChartCreated(); chart.addSelectHandler(createSelectHandler(chart)); } } @Override public void setAnimationOn(boolean animationOn) { this.animationOn = animationOn; } @Override public void setAnimationDuration(int animationDuration) { this.animationDuration = animationDuration; } @Override public void createChart() { chart = _createChart(); } @Override public void drawChart() { checkChartCreated(); chart.draw(getDataTable(), createOptions()); super.showDisplayer(chart); } @Override public void nodata() { FlowPanel noDataPanel = new FlowPanel(); noDataPanel.setWidth(width + "px"); noDataPanel.setHeight(height + "px"); noDataPanel.add(new Label(GoogleDisplayerConstants.INSTANCE.common_noData())); super.showDisplayer(noDataPanel); } // Common methods used in subclasses protected void checkChartCreated() { if (chart == null) { throw new RuntimeException("Chart not created. Call to view.createChart() first"); } } protected CoreChartWidget _createChart() { return null; } protected Options createOptions() { return null; } protected SelectHandler createSelectHandler(final CoreChartWidget selectable) { return new SelectHandler() { public void onSelect(SelectEvent event) { JsArray selections = selectable.getSelection(); for (int i = 0; i < selections.length(); i++) { Selection selection = selections.get(i); int row = selection.getRow(); getPresenter().onCategorySelected(getDataTable().getColumnId(0), row); } } }; } protected SelectHandler createSelectHandler(final GeoChart selectable) { return new SelectHandler() { public void onSelect(SelectEvent event) { JsArray selections = selectable.getSelection(); for (int i = 0; i < selections.length(); i++) { Selection selection = selections.get(i); int row = selection.getRow(); getPresenter().onCategorySelected(getDataTable().getColumnId(0), row); } } }; } protected ChartArea createChartArea() { int chartWidth = width - marginRight - marginLeft; int chartHeight = height - marginTop - marginBottom; ChartArea chartArea = ChartArea.create(); chartArea.setLeft(marginLeft); chartArea.setTop(marginTop); chartArea.setWidth(chartWidth); chartArea.setHeight(chartHeight); return chartArea; } protected HAxis createHAxis() { HAxis xAxis = xAxisTitle == null ? HAxis.create() : HAxis.create(xAxisTitle); xAxis.setSlantedTextAngle(xAxisAngle); return xAxis; } protected VAxis createVAxis() { return yAxisTitle == null ? null : VAxis.create(yAxisTitle); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.Position; /** * Base class for all the Google chart displayers */ public abstract class GoogleChartDisplayer extends GoogleDisplayer { public interface View

    extends GoogleDisplayer.View

    { void setWidth(int width); void setHeight(int height); void setMarginTop(int marginTop); void setMarginBottom(int marginBottom); void setMarginRight(int marginRight); void setMarginLeft(int marginLeft); void setLegendPosition(Position position); void setSubType(DisplayerSubType subType); } public GoogleChartDisplayer(FilterLabelSet filterLabelSet) { super(filterLabelSet); } @Override protected void createVisualization() { super.createVisualization(); getView().setWidth(displayerSettings.getChartWidth()); getView().setHeight(displayerSettings.getChartHeight()); getView().setMarginTop(displayerSettings.getChartMarginTop()); getView().setMarginBottom(displayerSettings.getChartMarginBottom()); getView().setMarginRight(displayerSettings.getChartMarginRight()); getView().setMarginLeft(displayerSettings.getChartMarginLeft()); getView().setLegendPosition(displayerSettings.isChartShowLegend() ? displayerSettings.getChartLegendPosition() : null); getView().setSubType(displayerSettings.getSubtype()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.options.Legend; import com.googlecode.gwt.charts.client.options.LegendAlignment; import com.googlecode.gwt.charts.client.options.LegendPosition; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.Position; /** * Base class for all the Google chart like displayers */ public abstract class GoogleChartDisplayerView

    extends GoogleDisplayerView

    implements GoogleChartDisplayer.View

    { protected int width = 500; protected int height= 300; protected int marginTop = 10; protected int marginBottom = 10; protected int marginRight = 10; protected int marginLeft = 10; protected Position legendPosition = null; protected DisplayerSubType subType = null; @Override public void setWidth(int width) { this.width = width; } @Override public void setHeight(int height) { this.height = height; } @Override public void setMarginTop(int marginTop) { this.marginTop = marginTop; } @Override public void setMarginBottom(int marginBottom) { this.marginBottom = marginBottom; } @Override public void setMarginRight(int marginRight) { this.marginRight = marginRight; } @Override public void setMarginLeft(int marginLeft) { this.marginLeft = marginLeft; } @Override public void setLegendPosition(Position legendPosition) { this.legendPosition = legendPosition; } @Override public void setSubType(DisplayerSubType subType) { this.subType = subType; } protected Legend createChartLegend() { GoogleLegendWrapper legend = GoogleLegendWrapper.create(); legend.setLegendPosition(getLegendPosition()); legend.setAligment(LegendAlignment.CENTER); return legend; } protected String getLegendPosition() { if (legendPosition != null) { switch (legendPosition) { case TOP: return LegendPosition.TOP.toString().toLowerCase(); case BOTTOM: return LegendPosition.BOTTOM.toString().toLowerCase(); case RIGHT: return LegendPosition.RIGHT.toString().toLowerCase(); case IN: return LegendPosition.IN.toString().toLowerCase(); case LEFT: return "left"; default: return LegendPosition.RIGHT.toString().toLowerCase(); } } return LegendPosition.NONE.toString().toLowerCase(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import java.util.Date; import java.util.List; import java.util.Set; import org.dashbuilder.common.client.widgets.FilterLabel; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.group.Interval; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.client.AbstractGwtDisplayer; public abstract class GoogleDisplayer extends AbstractGwtDisplayer { public interface View

    extends AbstractGwtDisplayer.View

    { void draw(); void dataClear(); void dataRowCount(int rowCount); void dataAddColumn(ColumnType type, String id, String name); void dataSetValue(int row, int column, Date value); void dataSetValue(int row, int column, double value); void dataSetValue(int row, int column, String value); void dataFormatDateColumn(String pattern, int column); void dataFormatNumberColumn(String pattern, int column); String getGroupsTitle(); String getColumnsTitle(); void showTitle(String title); void setFilterLabelSet(FilterLabelSet widget); } private FilterLabelSet filterLabelSet; public GoogleDisplayer(FilterLabelSet filterLabelSet) { this.filterLabelSet = filterLabelSet; this.filterLabelSet.setOnClearAllCommand(this::onFilterClearAll); } public FilterLabelSet getFilterLabelSet() { return filterLabelSet; } /** * GCharts drawing is done asynchronously via the GoogleRenderer (see ready() method below) */ @Override public void draw() { getView().draw(); } /** * Invoked asynchronously by the GoogleRenderer when the displayer is ready for display */ public void ready() { super.draw(); } @Override protected void createVisualization() { getView().setFilterLabelSet(filterLabelSet); if (displayerSettings.isTitleVisible()) { getView().showTitle(displayerSettings.getTitle()); } } protected void updateFilterStatus() { filterLabelSet.clear(); Set columnFilters = filterColumns(); if (displayerSettings.isFilterEnabled() && !columnFilters.isEmpty()) { for (String columnId : columnFilters) { List selectedValues = filterIntervals(columnId); DataColumn column = dataSet.getColumnById(columnId); for (Interval interval : selectedValues) { String formattedValue = formatInterval(interval, column); FilterLabel filterLabel = filterLabelSet.addLabel(formattedValue); filterLabel.setOnRemoveCommand(() -> onFilterLabelRemoved(columnId, interval.getIndex())); } } } } // Data generation public void pushDataToView() { getView().dataClear(); getView().dataRowCount(dataSet.getRowCount()); List columns = dataSet.getColumns(); for (int i = 0; i < columns.size(); i++) { DataColumn dataColumn = columns.get(i); String columnId = dataColumn.getId(); ColumnType columnType = dataColumn.getColumnType(); ColumnSettings columnSettings = displayerSettings.getColumnSettings(dataColumn); getView().dataAddColumn(dataColumn.getColumnType(), columnId, columnSettings.getColumnName()); List columnValues = dataColumn.getValues(); for (int j = 0; j < columnValues.size(); j++) { Object value = columnValues.get(j); if (ColumnType.DATE.equals(columnType)) { getView().dataSetValue(j, i, value == null ? new Date() : (Date) value); } else if (ColumnType.NUMBER.equals(columnType)) { if (value == null) { getView().dataSetValue(j, i, 0d); } else { String valueStr = getEvaluator().evalExpression(value.toString(), columnSettings.getValueExpression()); getView().dataSetValue(j, i, Double.parseDouble(valueStr)); } } else { String valueStr = super.formatValue(j, i); getView().dataSetValue(j, i, valueStr); } } } // Format the table values for (int i = 0; i < dataSet.getColumns().size(); i++) { DataColumn dataColumn = columns.get(i); ColumnSettings columnSettings = displayerSettings.getColumnSettings(dataColumn); String pattern = columnSettings.getValuePattern(); if (ColumnType.DATE.equals(dataColumn.getColumnType())) { getView().dataFormatDateColumn(pattern, i); } else if (ColumnType.NUMBER.equals(dataColumn.getColumnType())) { getView().dataFormatNumberColumn(pattern, i); } } } // Filter label set component notifications void onFilterLabelRemoved(String columnId, int row) { super.filterUpdate(columnId, row); // Update the displayer view in order to reflect the current selection // (only if not has already been redrawn in the previous filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } void onFilterClearAll() { super.filterReset(); // Update the displayer view in order to reflect the current selection // (only if not has already been redrawn in the previous filterUpdate() call) if (!displayerSettings.isFilterSelfApplyEnabled()) { updateVisualization(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import com.googlecode.gwt.charts.client.DataTable; import com.googlecode.gwt.charts.client.format.DateFormat; import com.googlecode.gwt.charts.client.format.DateFormatOptions; import com.googlecode.gwt.charts.client.format.NumberFormat; import com.googlecode.gwt.charts.client.format.NumberFormatOptions; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.displayer.client.AbstractGwtDisplayerView; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants; import org.jboss.errai.common.client.dom.HTMLElement; import org.jboss.errai.common.client.ui.ElementWrapperWidget; public abstract class GoogleDisplayerView

    extends AbstractGwtDisplayerView

    implements GoogleDisplayer.View

    { private Panel container = new FlowPanel(); private Panel filterPanel = new FlowPanel(); private Panel displayerPanel = new FlowPanel(); private HTML titleHtml = new HTML(); private DataTable dataTable ; private GoogleRenderer googleRenderer; public void setRenderer(GoogleRenderer googleRenderer) { this.googleRenderer = googleRenderer; } public DataTable getDataTable() { return dataTable; } public void showDisplayer(Widget w) { displayerPanel.clear(); displayerPanel.add(w); } @Override public void init(P presenter) { super.setPresenter(presenter); super.setVisualization(container); container.add(titleHtml); container.add(filterPanel); container.add(displayerPanel); filterPanel.getElement().setAttribute("cellpadding", "2"); } /** * GCharts drawing is performed asynchronously */ @Override public void draw() { if (googleRenderer == null) { getPresenter().showError(new ClientRuntimeError("Google renderer not set")); } else if (!getPresenter().isDrawn()) { List displayerList = new ArrayList(); displayerList.add(getPresenter()); googleRenderer.draw(displayerList); } } @Override public void dataClear() { dataTable = DataTable.create(); } @Override public void dataRowCount(int rowCount) { dataTable.addRows(rowCount); } @Override public void dataAddColumn(ColumnType type, String id, String name) { dataTable.addColumn(getColumnType(type), name, id); } @Override public void dataSetValue(int row, int column, Date value) { dataTable.setValue(row, column, value); } @Override public void dataSetValue(int row, int column, double value) { dataTable.setValue(row, column, value); } @Override public void dataSetValue(int row, int column, String value) { dataTable.setValue(row, column, value); } @Override public void dataFormatDateColumn(String pattern, int column) { DateFormatOptions dateFormatOptions = DateFormatOptions.create(); dateFormatOptions.setPattern(pattern); DateFormat dateFormat = DateFormat.create(dateFormatOptions); dateFormat.format(dataTable, column); } @Override public void dataFormatNumberColumn(String pattern, int column) { NumberFormatOptions numberFormatOptions = NumberFormatOptions.create(); numberFormatOptions.setPattern(pattern); NumberFormat numberFormat = NumberFormat.create(numberFormatOptions); numberFormat.format(dataTable, column); } @Override public String getGroupsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Categories(); } @Override public String getColumnsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Series(); } @Override public void showTitle(String title) { titleHtml.setText(title); } @Override public void setFilterLabelSet(FilterLabelSet widget) { HTMLElement element = widget.getElement(); element.getStyle().setProperty("position", "absolute"); element.getStyle().setProperty("z-index", "10"); filterPanel.clear(); filterPanel.add(ElementWrapperWidget.getWidget(element)); } public com.googlecode.gwt.charts.client.ColumnType getColumnType(ColumnType type) { if (ColumnType.LABEL.equals(type)) { return com.googlecode.gwt.charts.client.ColumnType.STRING; } if (ColumnType.TEXT.equals(type)) { return com.googlecode.gwt.charts.client.ColumnType.STRING; } if (ColumnType.NUMBER.equals(type)) { return com.googlecode.gwt.charts.client.ColumnType.NUMBER; } if (ColumnType.DATE.equals(type)) { return com.googlecode.gwt.charts.client.ColumnType.DATE; } return com.googlecode.gwt.charts.client.ColumnType.STRING; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleLegendWrapper.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.options.Legend; /** * Extension of the google Legend in order to allow for positioning the legend to the left of the chart, which is not * possible with the original class, because the LegendPosition enum does not include the 'left' value. */ public class GoogleLegendWrapper extends Legend { public static GoogleLegendWrapper create() { return createObject().cast(); } protected GoogleLegendWrapper() { } public final void setLegendPosition(String alignment) { setPosition(alignment); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleLineChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; @Dependent public class GoogleLineChartDisplayer extends GoogleCategoriesDisplayer { public interface View extends GoogleCategoriesDisplayer.View { } private View view; @Inject public GoogleLineChartDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxGroups(1) .setMinColumns(2) .setMaxColumns(10) .setExtraColumnsAllowed(true) .setExtraColumnsType(ColumnType.NUMBER) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.AXIS_GROUP); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleLineChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.corechart.CoreChartWidget; import com.googlecode.gwt.charts.client.corechart.LineChart; import com.googlecode.gwt.charts.client.corechart.LineChartOptions; import com.googlecode.gwt.charts.client.options.Animation; import com.googlecode.gwt.charts.client.options.AnimationEasing; import com.googlecode.gwt.charts.client.options.CurveType; import com.googlecode.gwt.charts.client.options.Options; import org.dashbuilder.displayer.DisplayerSubType; public class GoogleLineChartDisplayerView extends GoogleCategoriesDisplayerView implements GoogleLineChartDisplayer.View { @Override protected CoreChartWidget _createChart() { return new LineChart(); } @Override protected Options createOptions() { boolean isLine = DisplayerSubType.LINE.equals(subType); LineChartOptions options = LineChartOptions.create(); options.setCurveType(isLine ? CurveType.NONE : CurveType.FUNCTION); options.setWidth(width); options.setHeight(height); options.setBackgroundColor(bgColor); options.setChartArea(createChartArea()); options.setLegend(createChartLegend()); options.setColors(colors); options.setHAxis(createHAxis()); options.setVAxis(createVAxis()); if (animationOn) { Animation anim = Animation.create(); anim.setDuration(animationDuration); anim.setEasing(AnimationEasing.IN_AND_OUT); options.setAnimation(anim); } return options; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleMapDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; @Dependent public class GoogleMapDisplayer extends GoogleCategoriesDisplayer { public interface View extends GoogleCategoriesDisplayer.View { } private View view; @Inject public GoogleMapDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMinColumns(2) .setMaxColumns(3) .setExtraColumnsAllowed(true) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[] { ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleMapDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.geochart.GeoChart; import com.googlecode.gwt.charts.client.geochart.GeoChartOptions; import com.googlecode.gwt.charts.client.options.DisplayMode; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants; public class GoogleMapDisplayerView extends GoogleCategoriesDisplayerView implements GoogleMapDisplayer.View { protected GeoChart map = null; @Override public String getGroupsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Locations(); } @Override public String getColumnsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Series(); } @Override public void setFilterEnabled(boolean enabled) { if (enabled) { checkMapCreated(); map.addSelectHandler(createSelectHandler(map)); } } @Override public void createChart() { map = new GeoChart(); } @Override public void drawChart() { checkMapCreated(); map.draw(getDataTable(), createMapOptions()); super.showDisplayer(map); } protected void checkMapCreated() { if (map == null) { throw new RuntimeException("Map not created. Call to view.createChart() first"); } } protected GeoChartOptions createMapOptions() { GeoChartOptions options = GeoChartOptions.create(); options.setWidth(width); options.setHeight(height); options.setDisplayMode(DisplayerSubType.MAP_REGIONS.equals(subType) ? DisplayMode.REGIONS : DisplayMode.MARKERS); return options; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleMeterChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; @Dependent public class GoogleMeterChartDisplayer extends GoogleCategoriesDisplayer { public interface View extends GoogleCategoriesDisplayer.View { void setMeterStart(long meterStart); void setMeterWarning(long meterWarning); void setMeterCritical(long meterCritical); void setMeterEnd(long meterEnd); } private View view; @Inject public GoogleMeterChartDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(false) .setGroupAllowed(true) .setGroupColumn(true) .setMaxColumns(2) .setMinColumns(1) .setExtraColumnsAllowed(false) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setFunctionRequired(true) .setColumnTypes(new ColumnType[] {ColumnType.NUMBER}, new ColumnType[] {ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.METER_GROUP); } @Override protected void createVisualization() { view.setMeterStart(displayerSettings.getMeterStart()); view.setMeterWarning(displayerSettings.getMeterWarning()); view.setMeterCritical(displayerSettings.getMeterCritical()); view.setMeterEnd(displayerSettings.getMeterEnd()); super.createVisualization(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleMeterChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.gauge.Gauge; import com.googlecode.gwt.charts.client.gauge.GaugeOptions; import com.googlecode.gwt.charts.client.options.Animation; import com.googlecode.gwt.charts.client.options.AnimationEasing; import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants; public class GoogleMeterChartDisplayerView extends GoogleCategoriesDisplayerView implements GoogleMeterChartDisplayer.View { private Gauge meter = null; protected long meterStart = 0; protected long meterWarning = 600; protected long meterCritical = 800; protected long meterEnd = 1000; @Override public void setMeterStart(long meterStart) { this.meterStart = meterStart; } @Override public void setMeterWarning(long meterWarning) { this.meterWarning = meterWarning; } @Override public void setMeterCritical(long meterCritical) { this.meterCritical = meterCritical; } @Override public void setMeterEnd(long meterEnd) { this.meterEnd = meterEnd; } @Override public String getColumnsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Value(); } @Override public void setFilterEnabled(boolean enabled) { // Metrics does not provide filter support } @Override public void createChart() { meter = new Gauge(); } @Override public void drawChart() { meter.draw(getDataTable(), createMeterOptions()); super.showDisplayer(meter); } protected GaugeOptions createMeterOptions() { GaugeOptions options = GaugeOptions.create(); options.setWidth(width); options.setWidth(width); options.setHeight(height); options.setMin(meterStart); options.setMax(meterEnd); options.setGreenFrom(meterStart); options.setGreenTo(meterWarning); options.setYellowFrom(meterWarning); options.setYellowTo(meterCritical); options.setRedFrom(meterCritical); options.setRedTo(meterEnd); options.setGreenColor("#0088CE"); options.setYellowColor("#EC7A08"); options.setRedColor("#CC0000"); if (animationOn) { Animation anim = Animation.create(); anim.setDuration(animationDuration); anim.setEasing(AnimationEasing.IN_AND_OUT); options.setAnimation(anim); } return options; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GooglePieChartDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; @Dependent public class GooglePieChartDisplayer extends GoogleCategoriesDisplayer { public interface View extends GoogleCategoriesDisplayer.View { } private View view; @Inject public GooglePieChartDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupRequired(true) .setGroupColumn(true) .setMaxColumns(2) .setMinColumns(2) .setExtraColumnsAllowed(false) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()) .setColumnTypes(new ColumnType[]{ ColumnType.LABEL, ColumnType.NUMBER}); return new DisplayerConstraints(lookupConstraints) .supportsAttribute(DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.SUBTYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_WIDTH) .supportsAttribute(DisplayerAttributeGroupDef.CHART_HEIGHT) .supportsAttribute(DisplayerAttributeGroupDef.CHART_RESIZABLE) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MAX_WIDTH) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MAX_HEIGHT) .supportsAttribute(DisplayerAttributeGroupDef.CHART_BGCOLOR) .supportsAttribute(DisplayerAttributeGroupDef.CHART_MARGIN_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.CHART_LEGEND_GROUP); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GooglePieChartDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.googlecode.gwt.charts.client.corechart.CoreChartWidget; import com.googlecode.gwt.charts.client.corechart.PieChart; import com.googlecode.gwt.charts.client.options.Options; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants; public class GooglePieChartDisplayerView extends GoogleCategoriesDisplayerView implements GooglePieChartDisplayer.View { @Override public String getColumnsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Values(); } @Override protected CoreChartWidget _createChart() { return new PieChart(); } @Override protected Options createOptions() { PieChartOptionsWrapper options = PieChartOptionsWrapper.newInstance(); options.setWidth(width); options.setHeight(height); options.setBackgroundColor(bgColor); options.setLegend(createChartLegend()); options.setColors(colors); options.setChartArea(createChartArea()); options.setIs3D(DisplayerSubType.PIE_3D.equals(subType)); options.setHole(DisplayerSubType.DONUT.equals(subType) ? 0.4d : 0); return options.get(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleRenderer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.googlecode.gwt.charts.client.ChartLoader; import com.googlecode.gwt.charts.client.ChartPackage; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.AbstractRendererLibrary; import org.dashbuilder.displayer.client.Displayer; import org.jboss.errai.ioc.client.container.SyncBeanManager; import static org.dashbuilder.displayer.DisplayerType.*; import static org.dashbuilder.displayer.DisplayerSubType.*; import java.util.EnumSet; /** * Google's Visualization API based renderer. */ @ApplicationScoped public class GoogleRenderer extends AbstractRendererLibrary { public static final String UUID = "gwtcharts"; private static Map _packageTypes = new HashMap(); static { _packageTypes.put(BARCHART, ChartPackage.CORECHART); _packageTypes.put(PIECHART, ChartPackage.CORECHART); _packageTypes.put(AREACHART, ChartPackage.CORECHART); _packageTypes.put(LINECHART, ChartPackage.CORECHART); _packageTypes.put(BUBBLECHART, ChartPackage.CORECHART); _packageTypes.put(METERCHART, ChartPackage.GAUGE); _packageTypes.put(TABLE, ChartPackage.TABLE); _packageTypes.put(MAP, ChartPackage.GEOCHART); } private List _supportedTypes = Arrays.asList( BARCHART, PIECHART, AREACHART, LINECHART, BUBBLECHART, METERCHART, TABLE, MAP); @Inject protected SyncBeanManager beanManager; @Override public String getUUID() { return UUID; } @Override public String getName() { return "GWT Charts"; } @Override public List getSupportedTypes() { return _supportedTypes; } @Override public List getSupportedSubtypes(DisplayerType displayerType) { switch (displayerType) { case BARCHART: return Arrays.asList(BAR, BAR_STACKED, COLUMN, COLUMN_STACKED); case PIECHART: return Arrays.asList(PIE, PIE_3D, DONUT); case AREACHART: return Arrays.asList(AREA, AREA_STACKED /*,STEPPED*/); case LINECHART: return Arrays.asList(LINE, SMOOTH); case MAP: return Arrays.asList(MAP_REGIONS, MAP_MARKERS); default: return Arrays.asList(); } } public Displayer lookupDisplayer(DisplayerSettings displayerSettings) { DisplayerType displayerType = displayerSettings.getType(); GoogleDisplayer displayer; switch (displayerType) { case BARCHART: displayer = beanManager.lookupBean(GoogleBarChartDisplayer.class).newInstance(); break; case PIECHART: displayer = beanManager.lookupBean(GooglePieChartDisplayer.class).newInstance(); break; case AREACHART: displayer = beanManager.lookupBean(GoogleAreaChartDisplayer.class).newInstance(); break; case LINECHART: displayer = beanManager.lookupBean(GoogleLineChartDisplayer.class).newInstance(); break; case BUBBLECHART: displayer = beanManager.lookupBean(GoogleBubbleChartDisplayer.class).newInstance(); break; case METERCHART: displayer = beanManager.lookupBean(GoogleMeterChartDisplayer.class).newInstance(); break; case TABLE: displayer = beanManager.lookupBean(GoogleTableDisplayer.class).newInstance(); break; case MAP: displayer = beanManager.lookupBean(GoogleMapDisplayer.class).newInstance(); break; default: return null; } ((GoogleDisplayerView) displayer.getView()).setRenderer(this); return displayer; } /** * In Google the renderer mechanism is asynchronous. */ public void draw(final List displayerList) { // Get the modules to load. Set packageList = EnumSet.noneOf(ChartPackage.class); for (Displayer displayer : displayerList) { try { GoogleDisplayer googleDisplayer = (GoogleDisplayer) displayer; packageList.add(_packageTypes.get(googleDisplayer.getDisplayerSettings().getType())); } catch (ClassCastException e) { // Just ignore non Google displayers. } } // Create an array of packages. ChartPackage[] packageArray = new ChartPackage[packageList.size()]; int i = 0; for (ChartPackage pkg : packageList) { packageArray[i++] = pkg; } // Load the visualization API ChartLoader chartLoader = new ChartLoader(packageArray); chartLoader.loadApi(new Runnable() { // Called when the visualization API has been loaded. public void run() { for (Displayer displayer : displayerList) { try { GoogleDisplayer googleDisplayer = (GoogleDisplayer) displayer; googleDisplayer.ready(); } catch (ClassCastException e) { // Just ignore non Google displayers. } } } }); } @Override public boolean isOffline() { return false; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleTableDisplayer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerAttributeDef; import org.dashbuilder.displayer.DisplayerAttributeGroupDef; import org.dashbuilder.displayer.DisplayerConstraints; import org.dashbuilder.displayer.client.Displayer; @Dependent public class GoogleTableDisplayer extends GoogleDisplayer { public interface View extends GoogleDisplayer.View { void createTable(); void setSortEnabled(boolean enabled); void setTotalPagesHintEnabled(boolean enabled); void setTotalRowsHintEnabled(boolean enabled); void setPageSize(int size); void setWidth(int width); void setPagerEnabled(boolean enabled); void setCurrentPage(int currentPage); void setTotalRows(int numberOfRows); void setTotalPages(int numberOfPages); void setLeftMostPageNumber(int n); void setRightMostPageNumber(int n); void nodata(); void drawTable(); } protected View view; protected int pageSize = 20; protected int currentPage = 1; protected int numberOfRows = 0; protected int numberOfPages = 1; protected int pageSelectorSize = 6; protected String lastOrderedColumn = null; protected SortOrder lastSortOrder = null; protected boolean showTotalRowsHint = true; protected boolean showTotalPagesHint = true; @Inject public GoogleTableDisplayer(View view, FilterLabelSet filterLabelSet) { super(filterLabelSet); this.view = view; this.view.init(this); } @Override public View getView() { return view; } @Override public DisplayerConstraints createDisplayerConstraints() { DataSetLookupConstraints lookupConstraints = new DataSetLookupConstraints() .setGroupAllowed(true) .setGroupRequired(false) .setExtraColumnsAllowed(true) .setGroupsTitle(view.getGroupsTitle()) .setColumnsTitle(view.getColumnsTitle()); return new DisplayerConstraints(lookupConstraints) .supportsAttribute( DisplayerAttributeDef.TYPE) .supportsAttribute(DisplayerAttributeDef.RENDERER) .supportsAttribute(DisplayerAttributeGroupDef.COLUMNS_GROUP) .supportsAttribute(DisplayerAttributeDef.COLUMN_EMPTY) .supportsAttribute(DisplayerAttributeGroupDef.FILTER_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.REFRESH_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.GENERAL_GROUP) .supportsAttribute(DisplayerAttributeGroupDef.TABLE_GROUP); } @Override protected void beforeDataSetLookup() { // Get the sort settings if (lastOrderedColumn == null) { String defaultSortColumn = displayerSettings.getTableDefaultSortColumnId(); if (defaultSortColumn != null && !"".equals( defaultSortColumn)) { lastOrderedColumn = defaultSortColumn; lastSortOrder = displayerSettings.getTableDefaultSortOrder(); } } // Apply the sort order specified (if any) if (lastOrderedColumn != null) { sortApply(lastOrderedColumn, lastSortOrder); } // Draw only the data subset corresponding to the current page. int pageSize = displayerSettings.getTablePageSize(); int offset = (currentPage - 1) * pageSize; dataSetHandler.limitDataSetRows(offset, pageSize); } @Override protected void afterDataSetLookup(DataSet dataSet) { pageSize = displayerSettings.getTablePageSize(); numberOfRows = dataSet.getRowCountNonTrimmed(); numberOfPages = ((numberOfRows - 1) / pageSize) + 1; if (currentPage > numberOfPages) { currentPage = 1; } } @Override protected void createVisualization() { super.createVisualization(); int tableWidth = displayerSettings.getTableWidth(); view.createTable(); view.setSortEnabled(displayerSettings.isTableSortEnabled()); view.setTotalPagesHintEnabled(showTotalPagesHint); view.setTotalRowsHintEnabled(showTotalRowsHint); view.setPageSize(displayerSettings.getTablePageSize()); view.setWidth(tableWidth > 0 ? tableWidth : dataSet.getColumns().size() * 100); this.updateVisualization(); } @Override protected void updateVisualization() { view.setPagerEnabled(displayerSettings.getTablePageSize() < dataSet.getRowCountNonTrimmed()); view.setCurrentPage(currentPage); view.setTotalRows(numberOfRows); view.setTotalPages(numberOfPages); view.setLeftMostPageNumber(getLeftMostPageNumber()); view.setRightMostPageNumber(getRightMostPageNumber()); if (numberOfRows == 0) { view.nodata(); } else { super.pushDataToView(); view.drawTable(); } } public void sortBy(String column) { if (displayerSettings.isTableSortEnabled()) { lastOrderedColumn = column; lastSortOrder = lastSortOrder != null ? lastSortOrder.reverse() : SortOrder.ASCENDING; super.redraw(); } } public void gotoPage(int pageNumber) { if (pageNumber != currentPage && pageNumber > 0 && pageNumber < numberOfPages + 1) { currentPage = pageNumber; super.redraw(); } } public int getLeftMostPageNumber() { int page = currentPage - pageSelectorSize/2; if (page < 1) return 1; return page; } public int getRightMostPageNumber() { int page = getLeftMostPageNumber() + pageSelectorSize - 1; if (page > numberOfPages) return numberOfPages; return page; } public int getCurrentPage() { return currentPage; } // Reset the current navigation status on filter requests from external displayers. @Override public void onFilterEnabled(Displayer displayer, DataSetGroup groupOp) { currentPage = 1; super.onFilterEnabled(displayer, groupOp); } @Override public void onFilterEnabled(Displayer displayer, DataSetFilter filter) { currentPage = 1; super.onFilterEnabled(displayer, filter); } @Override public void onFilterReset(Displayer displayer, List groupOps) { currentPage = 1; super.onFilterReset(displayer, groupOps); } @Override public void onFilterReset(Displayer displayer, DataSetFilter filter) { currentPage = 1; super.onFilterReset(displayer, filter); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/GoogleTableDisplayerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.googlecode.gwt.charts.client.event.SortEvent; import com.googlecode.gwt.charts.client.event.SortHandler; import com.googlecode.gwt.charts.client.options.TableSort; import com.googlecode.gwt.charts.client.table.Table; import com.googlecode.gwt.charts.client.table.TableOptions; import org.dashbuilder.renderer.google.client.resources.i18n.GoogleDisplayerConstants; import org.gwtbootstrap3.client.ui.AnchorListItem; import org.gwtbootstrap3.client.ui.Icon; import org.gwtbootstrap3.client.ui.Label; import org.gwtbootstrap3.client.ui.Pagination; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.client.ui.constants.IconSize; import org.gwtbootstrap3.client.ui.constants.IconType; import org.gwtbootstrap3.client.ui.constants.PaginationSize; public class GoogleTableDisplayerView extends GoogleDisplayerView implements GoogleTableDisplayer.View { private Table table; protected int pageSize = 10; protected int width = 500; protected int totalPages = 1; protected int currentPage = 1; protected int totalRows = 0; protected int leftMostPageNumber = 0; protected int rightMostPageNumber = 0; protected boolean pagerEnabled = false; protected boolean totalPagesHintEnabled = false; protected boolean totalRowsHintEnabled = false; @Override public String getGroupsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Rows(); } @Override public String getColumnsTitle() { return GoogleDisplayerConstants.INSTANCE.common_Columns(); } @Override public void createTable() { table = new Table(); } @Override public void setSortEnabled(boolean enabled) { if (enabled) { table.addSortHandler(new SortHandler() { public void onSort(SortEvent sortEvent) { String columnId = getDataTable().getColumnId(sortEvent.getColumn()); getPresenter().sortBy(columnId); } } ); } } @Override public void setTotalPagesHintEnabled(boolean enabled) { this.totalPagesHintEnabled = enabled; } @Override public void setTotalRowsHintEnabled(boolean enabled) { this.totalRowsHintEnabled = enabled; } @Override public void setPageSize(int size) { this.pageSize = size; } @Override public void setWidth(int width) { this.width = width; } @Override public void setPagerEnabled(boolean enabled) { this.pagerEnabled = enabled; } @Override public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } @Override public void setTotalRows(int numberOfRows) { this.totalRows = numberOfRows; } @Override public void setTotalPages(int numberOfPages) { this.totalPages = numberOfPages; } @Override public void setLeftMostPageNumber(int n) { this.leftMostPageNumber = n; } @Override public void setRightMostPageNumber(int n) { this.rightMostPageNumber = n; } @Override public void nodata() { table.draw(getDataTable(), createOptions()); FlowPanel tablePanel = new FlowPanel(); tablePanel.add(table); tablePanel.add(new Label(GoogleDisplayerConstants.INSTANCE.common_noData())); super.showDisplayer(tablePanel); } @Override public void drawTable() { table.draw(getDataTable(), createOptions()); FlowPanel tablePanel = new FlowPanel(); tablePanel.add(table); if (pagerEnabled) { HorizontalPanel pager = createTablePager(); tablePanel.add(pager); } super.showDisplayer(tablePanel); } protected TableOptions createOptions() { TableOptions options = TableOptions.create(); options.setSort(TableSort.EVENT); options.setPageSize(pageSize); options.setShowRowNumber(false); options.setWidth(width); return options; } protected HorizontalPanel createTablePager() { HorizontalPanel pagerPanel = new HorizontalPanel(); pagerPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); pagerPanel.getElement().setAttribute("cellpadding", "5"); Pagination pagination = new Pagination(); pagination.setPaginationSize(PaginationSize.NONE); for (int i = leftMostPageNumber; i <= rightMostPageNumber; i++) { AnchorListItem pageLink = new AnchorListItem(Integer.toString(i)); final Integer _currentPage = i; if (currentPage != i) { pageLink.setActive(false); pageLink.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { getPresenter().gotoPage(_currentPage.intValue()); } }); } else { pageLink.setActive(true); } pagination.add(pageLink); } Icon leftPageIcon = new Icon(IconType.ANGLE_LEFT); leftPageIcon.setSize(IconSize.LARGE ); leftPageIcon.getElement().getStyle().setCursor(Style.Cursor.POINTER); leftPageIcon.sinkEvents(Event.ONCLICK); leftPageIcon.addHandler(createGotoPageHandler(currentPage - 1), ClickEvent.getType()); Tooltip leftPageTooltip = new Tooltip(GoogleDisplayerConstants.INSTANCE.googleTableDisplayer_gotoPreviousPage()); leftPageTooltip.add(leftPageIcon); Icon rightPageIcon = new Icon(IconType.ANGLE_RIGHT); rightPageIcon.setSize(IconSize.LARGE); rightPageIcon.getElement().getStyle().setCursor(Style.Cursor.POINTER); rightPageIcon.sinkEvents(Event.ONCLICK); rightPageIcon.addHandler(createGotoPageHandler(currentPage + 1), ClickEvent.getType()); Tooltip rightPageTooltip = new Tooltip( GoogleDisplayerConstants.INSTANCE.googleTableDisplayer_gotoNextPage() ); rightPageTooltip.add(rightPageIcon); Icon firstPageIcon = new Icon(IconType.ANGLE_DOUBLE_LEFT); firstPageIcon.setSize(IconSize.LARGE); firstPageIcon.getElement().getStyle().setCursor(Style.Cursor.POINTER); firstPageIcon.sinkEvents(Event.ONCLICK); firstPageIcon.addHandler(createGotoPageHandler(1), ClickEvent.getType()); Tooltip firstPageTooltip = new Tooltip(GoogleDisplayerConstants.INSTANCE.googleTableDisplayer_gotoFirstPage()); firstPageTooltip.add(firstPageIcon); Icon lastPageIcon = new Icon(IconType.ANGLE_DOUBLE_RIGHT); lastPageIcon.setSize(IconSize.LARGE); lastPageIcon.getElement().getStyle().setCursor(Style.Cursor.POINTER); lastPageIcon.sinkEvents(Event.ONCLICK); lastPageIcon.addHandler(createGotoPageHandler(totalPages), ClickEvent.getType()); Tooltip lastPageTooltip = new Tooltip(GoogleDisplayerConstants.INSTANCE.googleTableDisplayer_gotoLastPage()); lastPageTooltip.add(lastPageIcon); pagerPanel.add(firstPageTooltip); pagerPanel.add(leftPageTooltip); pagerPanel.add(pagination); pagerPanel.add(rightPageTooltip); pagerPanel.add(lastPageTooltip); if (totalPagesHintEnabled) { pagerPanel.add(new Label(GoogleDisplayerConstants.INSTANCE.googleTableDisplayer_pages( Integer.toString(leftMostPageNumber), Integer.toString(rightMostPageNumber), Integer.toString(totalPages)))); } if (totalRowsHintEnabled) { int currentRowsShown = currentPage * pageSize > totalRows ? totalRows : currentPage * pageSize; pagerPanel.add(new Label(GoogleDisplayerConstants.INSTANCE.googleTableDisplayer_rows( Integer.toString(((currentPage - 1) * pageSize) + 1), Integer.toString(currentRowsShown), Integer.toString(totalRows)))); } return pagerPanel; } protected ClickHandler createGotoPageHandler(final int page) { return new ClickHandler() { public void onClick(ClickEvent event) { getPresenter().gotoPage(page); } }; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/PieChartOptionsWrapper.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import com.google.gwt.core.client.JsArray; import com.googlecode.gwt.charts.client.corechart.PieChartOptions; import com.googlecode.gwt.charts.client.corechart.PieChartTooltip; import com.googlecode.gwt.charts.client.options.BackgroundColor; import com.googlecode.gwt.charts.client.options.ChartArea; import com.googlecode.gwt.charts.client.options.Legend; import com.googlecode.gwt.charts.client.options.Options; import com.googlecode.gwt.charts.client.options.PieSliceText; import com.googlecode.gwt.charts.client.options.Slice; import com.googlecode.gwt.charts.client.options.TextStyle; public class PieChartOptionsWrapper { private PieChartOptions _this; private PieChartOptionsWrapper() { _this = PieChartOptions.create(); } public static PieChartOptionsWrapper newInstance() { return new PieChartOptionsWrapper(); } public PieChartOptions get() { return _this; } public final void setHeight(int height) { _this.setHeight(height); } public final void setWidth(int width) { _this.setWidth(width); } public final void setBackgroundColor(BackgroundColor backgroundColor) { _this.setBackgroundColor(backgroundColor); } public final void setBackgroundColor(String color) { _this.setBackgroundColor(color); } public final void setChartArea(ChartArea chartArea) { _this.setChartArea(chartArea); } public final void setColors(String... colors) { _this.setColors(colors); } public final void setFontName(String name) { _this.setFontName(name); } public final void setFontSize(double size) { _this.setFontSize(size); } public final void setIs3D(boolean is3D) { _this.setIs3D(is3D); } public final void setLegend(Legend legend) { _this.setLegend(legend); } public final void setPieResidueSliceColor(String pieResidueSliceColor) { _this.setPieResidueSliceColor(pieResidueSliceColor); } public final void setPieResidueSliceLabel(String pieResidueSliceLabel) { _this.setPieResidueSliceLabel(pieResidueSliceLabel); } public final void setPieSliceBorderColor(String pieSliceBorderColor) { _this.setPieSliceBorderColor(pieSliceBorderColor); } public final void setPieSliceText(PieSliceText pieSliceText) { _this.setPieSliceText(pieSliceText); } public final void setPieSliceTextStyle(TextStyle pieSliceTextStyle) { _this.setPieSliceTextStyle(pieSliceTextStyle); } public final void setReverseCategories(boolean reverseCategories) { _this.setReverseCategories(reverseCategories); } public final void setSlices(JsArray slices) { _this.setSlices(slices); } public final void setSliceVisibilityThreshold( double sliceVisibilityThreshold) { _this.setSliceVisibilityThreshold(sliceVisibilityThreshold); } public final void setTitle(String title) { _this.setTitle(title); } public final void setTitleTextStyle(TextStyle textStyle) { _this.setTitleTextStyle(textStyle); } public final void setTooltip(PieChartTooltip tooltip) { _this.setTooltip(tooltip); } public void setHole(double d) { setHole(get(), d); } private final native void setHole(PieChartOptions chartOptions, double d) /*-{ chartOptions.pieHole = d; }-*/; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/java/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface GoogleDisplayerConstants extends Messages { public static final GoogleDisplayerConstants INSTANCE = GWT.create( GoogleDisplayerConstants.class ); String common_Categories(); String common_Series(); String common_Values(); String common_Value(); String common_Locations(); String common_Rows(); String common_Columns(); String common_noData(); String googleDisplayer_resetAnchor(); String googleBubbleDisplayer_XAxis(); String googleBubbleDisplayer_YAxis(); String googleBubbleDisplayer_BubbleColor(); String googleBubbleDisplayer_BubbleSize(); String googleTableDisplayer_gotoFirstPage(); String googleTableDisplayer_gotoPreviousPage(); String googleTableDisplayer_gotoNextPage(); String googleTableDisplayer_gotoLastPage(); String googleTableDisplayer_pages( String leftMostPageNumber, String rightMostPageNumber, String totalPages); String googleTableDisplayer_rows( String from, String to, String totalRows); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/GChartsRenderer.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categories common_Series=Series common_Values=Values common_Value=Value common_Locations=Locations common_Rows=Group By common_Columns=Columns common_noData=No data googleDisplayer_resetAnchor=reset googleBubbleDisplayer_XAxis=X Axis googleBubbleDisplayer_YAxis=Y Axis googleBubbleDisplayer_BubbleColor=Bubble color googleBubbleDisplayer_BubbleSize=Bubble size googleTableDisplayer_gotoFirstPage=Go to first page googleTableDisplayer_gotoPreviousPage=Go to previous page googleTableDisplayer_gotoNextPage=Go to next page googleTableDisplayer_gotoLastPage=Go to last page googleTableDisplayer_pages=Pages {0}-{1} of {2} googleTableDisplayer_rows=Rows {0}-{1} of {2} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants_de.properties ================================================ common_Categories=Kategorien common_Series=Serie common_Values=Werte common_Value=Wert common_Locations=Speicherorte common_Columns=Spalten common_noData=Keine Daten googleDisplayer_resetAnchor=zurücksetzen googleBubbleDisplayer_XAxis=X-Achse googleBubbleDisplayer_YAxis=Y-Achse googleBubbleDisplayer_BubbleColor=Blasen-Farbe googleBubbleDisplayer_BubbleSize=Blasen-Größe googleTableDisplayer_gotoFirstPage=Zur ersten Seite googleTableDisplayer_gotoPreviousPage=Zur vorherigen Seite googleTableDisplayer_gotoNextPage=Zur nächsten Seite googleTableDisplayer_gotoLastPage=Zur letzten Seite googleTableDisplayer_pages=Seiten {0}-{1} von {2} googleTableDisplayer_rows=Reihen {0}-{1} von {2} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants_es.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categorías common_Series=Serie common_Values=Valores common_Value=Valor common_Locations=Ubicaciones common_Rows=Agrupar por common_Columns=Columnas common_noData=No hay datos googleDisplayer_resetAnchor=restablecer googleBubbleDisplayer_XAxis=Eje X googleBubbleDisplayer_YAxis=Eje Y googleBubbleDisplayer_BubbleColor=Color de la burbuja googleBubbleDisplayer_BubbleSize=Tamaño de la burbuja googleTableDisplayer_gotoFirstPage=Ir a la primera página googleTableDisplayer_gotoPreviousPage=Ir a la página anterior googleTableDisplayer_gotoNextPage=Ir a la siguiente página googleTableDisplayer_gotoLastPage=Ir a la última página googleTableDisplayer_pages=Páginas {0}-{1} de {2} googleTableDisplayer_rows=Filas {0}-{1} de {2} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants_fr.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Catégories common_Series=Séries common_Values=Valeurs common_Value=Valeur common_Locations=Sites common_Rows=Grouper par common_Columns=Colonnes common_noData=Aucune donnée googleDisplayer_resetAnchor=réinitialiser googleBubbleDisplayer_XAxis=Axe X googleBubbleDisplayer_YAxis=Axe Y googleBubbleDisplayer_BubbleColor=Couleur de la bulle googleBubbleDisplayer_BubbleSize=Taille de la bulle googleTableDisplayer_gotoFirstPage=Aller à la première page googleTableDisplayer_gotoPreviousPage=Aller à la page précédente googleTableDisplayer_gotoNextPage=Aller à la page suivante googleTableDisplayer_gotoLastPage=Aller à la dernière page googleTableDisplayer_pages=Pages {0}-{1} sur {2} googleTableDisplayer_rows=Lignes {0}-{1} sur {2} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants_it.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=Categorie common_Series=Serie common_Values=Valori common_Value=Valore common_Locations=Posizioni common_Rows=Raggruppa per common_Columns=Colonne common_noData=Nessun dato googleDisplayer_resetAnchor=reset googleBubbleDisplayer_XAxis=Asse X googleBubbleDisplayer_YAxis=Asse Y googleBubbleDisplayer_BubbleColor=Colore bolle googleBubbleDisplayer_BubbleSize=Dimensione bolle googleTableDisplayer_gotoFirstPage=Vai alla prima pagina googleTableDisplayer_gotoPreviousPage=Vai alla pagina precedente googleTableDisplayer_gotoNextPage=Vai alla pagina successiva googleTableDisplayer_gotoLastPage=Vai all''ultima pagina googleTableDisplayer_pages=Pagine {0}-{1} di {2} googleTableDisplayer_rows=Righe {0}-{1} di {2} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants_ja.properties ================================================ # # Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # common_Categories=カテゴリ common_Series=シリーズ common_Values=値 common_Value=値 common_Locations=場所 common_Rows=グループ化 common_Columns=カラム common_noData=データなし googleDisplayer_resetAnchor=リセット googleBubbleDisplayer_XAxis=X 軸 googleBubbleDisplayer_YAxis=Y 軸 googleBubbleDisplayer_BubbleColor=バブル色 googleBubbleDisplayer_BubbleSize=バブルサイズ googleTableDisplayer_gotoFirstPage=最初のページに移動 googleTableDisplayer_gotoPreviousPage=前のページに移動 googleTableDisplayer_gotoNextPage=次のページに移動 googleTableDisplayer_gotoLastPage=最後のページに移動 googleTableDisplayer_pages=ページ {0}-{1} / {2} googleTableDisplayer_rows=行 {0}-{1} / {2} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants_pt_BR.properties ================================================ common_Categories=Categorias common_Series=Séries common_Values=Valores common_Value=Valor common_Locations=Locais common_Columns=Colunas common_noData=Não há dados googleDisplayer_resetAnchor=reiniciar googleBubbleDisplayer_XAxis=X Axis googleBubbleDisplayer_YAxis=Y Axis googleBubbleDisplayer_BubbleColor=Cor do Bubble googleBubbleDisplayer_BubbleSize=Tamanho do Bubble googleTableDisplayer_gotoFirstPage=Vá para a primeira página googleTableDisplayer_gotoPreviousPage=Vá para a página anterior googleTableDisplayer_gotoNextPage=Vá para a próxima página googleTableDisplayer_gotoLastPage=Vá para a última página googleTableDisplayer_pages=Páginas {0}-{1} de {2} googleTableDisplayer_rows=Linhas {0}-{1} of {2} ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/main/resources/org/dashbuilder/renderer/google/client/resources/i18n/GoogleDisplayerConstants_zh_CN.properties ================================================ common_Categories=类别 common_Series=序列 common_Values=值 common_Value=值 common_Locations=位置 common_Columns=列 common_noData=没有数据 googleDisplayer_resetAnchor=重置 googleBubbleDisplayer_XAxis=X 轴 googleBubbleDisplayer_YAxis=Y 轴 googleBubbleDisplayer_BubbleColor=Bubble 颜色 googleBubbleDisplayer_BubbleSize=Bubble 大小 googleTableDisplayer_gotoFirstPage=进入第一页 googleTableDisplayer_gotoPreviousPage=进入前一页 googleTableDisplayer_gotoNextPage=进入下一页 googleTableDisplayer_gotoLastPage=进入最后一页 googleTableDisplayer_pages={2} 的 {0}-{1} 页 googleTableDisplayer_rows={2} 的 {0}-{1} 行 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/test/java/org/dashbuilder/renderer/google/client/GoogleDisplayerDataTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class GoogleDisplayerDataTest extends GoogleDisplayerTest { DisplayerSettings byYear = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .filterOn(false, true, true) .sort(COLUMN_DATE, SortOrder.ASCENDING) .buildSettings(); DisplayerSettings noData = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .buildSettings(); @Test public void testDataPush() { // Google renderer draw calls are processed asynchronously // A ready() call needs to be executed in order to ignite the real chart display GoogleBarChartDisplayer barChart = createBarChartDisplayer(byYear); barChart.ready(); GoogleBarChartDisplayer.View view = barChart.getView(); verify(view).dataClear(); verify(view).dataAddColumn(ColumnType.LABEL, COLUMN_DATE, COLUMN_DATE); verify(view).dataAddColumn(eq(ColumnType.NUMBER), anyString(), anyString()); verify(view).dataRowCount(4); verify(view, times(4)).dataSetValue(anyInt(), anyInt(), anyString()); verify(view, times(4)).dataSetValue(anyInt(), anyInt(), any(Double.class)); verify(view).dataFormatNumberColumn(anyString(), eq(1)); } @Test public void testNoData() { // Google renderer draw calls are processed asynchronously // A ready() call needs to be executed in order to ignite the real chart display GoogleBarChartDisplayer barChart = createBarChartDisplayer(noData); barChart.ready(); GoogleBarChartDisplayer.View view = barChart.getView(); verify(view).nodata(); verify(view, never()).dataClear(); verify(view, never()).dataAddColumn(any(ColumnType.class), anyString(), anyString()); verify(view, never()).dataRowCount(anyInt()); verify(view, never()).dataSetValue(anyInt(), anyInt(), anyString()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/test/java/org/dashbuilder/renderer/google/client/GoogleDisplayerDrawTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.Position; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class GoogleDisplayerDrawTest extends GoogleDisplayerTest { @Test public void testGeneralSettings() { DisplayerSettings byYear = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .subType_Bar() .title("Title").titleVisible(true) .width(500).height(300) .margins(1, 2, 3, 4) .backgroundColor("white") .legendOn(Position.LEFT) .refreshOn(5, false) .filterOn(false, true, true) .xAxisTitle("Date") .yAxisTitle("Total") .buildSettings(); // Google renderer draw calls are processed asynchronously // A ready() call needs to be executed in order to ignite the real chart display GoogleBarChartDisplayer barChart = createBarChartDisplayer(byYear); GoogleBarChartDisplayer.View barChartView = barChart.getView(); barChart.ready(); verify(barChartView).showTitle("Title"); verify(barChartView).setFilterEnabled(true); verify(barChartView).setSubType(DisplayerSubType.BAR); verify(barChartView).setWidth(500); verify(barChartView).setHeight(300); verify(barChartView).setBgColor("white"); verify(barChartView).setMarginTop(1); verify(barChartView).setMarginBottom(2); verify(barChartView).setMarginLeft(3); verify(barChartView).setMarginRight(4); verify(barChartView).setLegendPosition(Position.LEFT); verify(barChartView).enableRefreshTimer(5); verify(barChartView).setShowXLabels(true); verify(barChartView).setShowYLabels(true); verify(barChartView).setXAxisTitle("Date"); verify(barChartView).setYAxisTitle("Total"); verify(barChartView).setIsStacked(false); verify(barChartView).setIsBar(true); verify(barChartView).drawChart(); } @Test public void testBarChartDraw() { DisplayerSettings byYear = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .subType_Bar() .buildSettings(); // Bar GoogleBarChartDisplayer barChart = createBarChartDisplayer(byYear); GoogleBarChartDisplayer.View barChartView = barChart.getView(); barChart.ready(); verify(barChartView).setIsStacked(false); verify(barChartView).setIsBar(true); // Bar stacked byYear.setSubtype(DisplayerSubType.BAR_STACKED); barChart = createBarChartDisplayer(byYear); barChart.ready(); barChartView = barChart.getView(); verify(barChartView).setIsStacked(true); verify(barChartView).setIsBar(true); // Column byYear.setSubtype(DisplayerSubType.COLUMN); barChart = createBarChartDisplayer(byYear); barChart.ready(); barChartView = barChart.getView(); verify(barChartView).setIsStacked(false); verify(barChartView).setIsBar(false); // Bar stacked byYear.setSubtype(DisplayerSubType.COLUMN_STACKED); barChart = createBarChartDisplayer(byYear); barChart.ready(); barChartView = barChart.getView(); verify(barChartView).setIsStacked(true); verify(barChartView).setIsBar(false); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/test/java/org/dashbuilder/renderer/google/client/GoogleDisplayerFilterTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import org.dashbuilder.common.client.widgets.FilterLabel; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class GoogleDisplayerFilterTest extends GoogleDisplayerTest { DisplayerSettings byYear = DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(COLUMN_DATE) .column(COLUMN_DATE) .column(COLUMN_AMOUNT, SUM) .filterOn(false, true, true) .sort(COLUMN_DATE, SortOrder.ASCENDING) .buildSettings(); @Mock FilterLabel filterLabel; public void resetFilterLabelSet(FilterLabelSet filterLabelSet) { reset(filterLabelSet); doAnswer(invocationOnMock -> filterLabel).when(filterLabelSet).addLabel(anyString()); } @Test public void testFilter() { // Google renderer draw calls are processed asynchronously // A ready() call needs to be executed in order to ignite the real chart display GoogleBarChartDisplayer barChart = createBarChartDisplayer(byYear); GoogleBarChartDisplayer.View barChartView = barChart.getView(); FilterLabelSet filterLabelSet = barChart.getFilterLabelSet(); barChart.ready(); // Select first bar reset(barChartView); resetFilterLabelSet(filterLabelSet); barChart.onCategorySelected(COLUMN_DATE, 0); verify(filterLabelSet).clear(); verify(filterLabelSet).addLabel("2012"); verify(barChartView).drawChart(); // Select another bar reset(barChartView); resetFilterLabelSet(filterLabelSet); barChart.onCategorySelected(COLUMN_DATE, 1); verify(filterLabelSet).clear(); verify(filterLabelSet).addLabel("2012"); verify(filterLabelSet).addLabel("2013"); verify(barChartView).drawChart(); // Reset the filter reset(barChartView); resetFilterLabelSet(filterLabelSet); barChart.onFilterClearAll(); verify(filterLabelSet).clear(); verify(filterLabelSet, never()).addLabel(anyString()); verify(barChartView).drawChart(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/test/java/org/dashbuilder/renderer/google/client/GoogleDisplayerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import org.dashbuilder.common.client.widgets.FilterLabelSet; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import static org.mockito.Mockito.*; public abstract class GoogleDisplayerTest extends AbstractDisplayerTest { public GoogleBarChartDisplayer createBarChartDisplayer(DisplayerSettings settings) { return initDisplayer(new GoogleBarChartDisplayer(mock(GoogleBarChartDisplayer.View.class), mock(FilterLabelSet.class)), settings); } public GoogleTableDisplayer createTableDisplayer(DisplayerSettings settings) { return initDisplayer(new GoogleTableDisplayer(mock(GoogleTableDisplayer.View.class), mock(FilterLabelSet.class)), settings); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/dashbuilder-renderer-google/src/test/java/org/dashbuilder/renderer/google/client/GoogleTableDisplayerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.renderer.google.client; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.dashbuilder.dataset.ExpenseReportsData.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class GoogleTableDisplayerTest extends GoogleDisplayerTest { @Test public void testTableDraw() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tableOrderDefault(COLUMN_DEPARTMENT, SortOrder.DESCENDING) .tableOrderEnabled(true) .tablePageSize(10) .tableWidth(1000) .buildSettings(); GoogleTableDisplayer table = createTableDisplayer(allRows); GoogleTableDisplayer.View tableView = table.getView(); table.ready(); verify(tableView).setWidth(1000); verify(tableView).setSortEnabled(true); verify(tableView).setPageSize(10); verify(tableView).setTotalRows(50); verify(tableView).setTotalPages(5); verify(tableView).setPagerEnabled(true); verify(tableView).drawTable(); } @Test public void testEmptyTableDraw() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .filter(COLUMN_ID, FilterFactory.isNull()) .tablePageSize(10) .buildSettings(); GoogleTableDisplayer table = createTableDisplayer(allRows); GoogleTableDisplayer.View tableView = table.getView(); table.ready(); verify(tableView).setPageSize(10); verify(tableView).setTotalRows(0); verify(tableView).setTotalPages(1); verify(tableView).setPagerEnabled(false); verify(tableView).nodata(); } @Test public void testTablePager() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .buildSettings(); GoogleTableDisplayer table = createTableDisplayer(allRows); GoogleTableDisplayer.View tableView = table.getView(); table.ready(); // Initialization verify(tableView).setPageSize(10); verify(tableView).setTotalRows(50); verify(tableView).setTotalPages(5); verify(tableView).setCurrentPage(1); verify(tableView).setPagerEnabled(true); verify(tableView).drawTable(); // Non existent page (no effect) reset(tableView); table.gotoPage(-1); assertEquals(table.getCurrentPage(), 1); verifyZeroInteractions(tableView); // Non existent page (no effect) reset(tableView); table.gotoPage(11); assertEquals(table.getCurrentPage(), 1); verifyZeroInteractions(tableView); // Goto page reset(tableView); table.gotoPage(5); verify(tableView).setCurrentPage(5); assertEquals(table.getCurrentPage(), 5); verify(tableView).drawTable(); } @Test public void testTableSort() { DisplayerSettings allRows = DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .tablePageSize(10) .tableOrderDefault(COLUMN_ID, SortOrder.DESCENDING) .buildSettings(); // Sorted by ID descending by default GoogleTableDisplayer table = createTableDisplayer(allRows); GoogleTableDisplayer.View tableView = table.getView(); table.ready(); assertEquals(table.getDataSetHandler().getLastDataSet().getValueAt(0,0), 50d); // Sort disabled (no effect) allRows.setTableSortEnabled(false); table = createTableDisplayer(allRows); tableView = table.getView(); table.ready(); reset(tableView); table.sortBy(COLUMN_ID); verify(tableView, never()).drawTable(); assertEquals(table.getDataSetHandler().getLastDataSet().getValueAt(0, 0), 50d); // Sort enabled allRows.setTableSortEnabled(true); table = createTableDisplayer(allRows); tableView = table.getView(); table.ready(); reset(tableView); table.sortBy(COLUMN_ID); verify(tableView).setCurrentPage(1); verify(tableView).drawTable(); assertEquals(table.getDataSetHandler().getLastDataSet().getValueAt(0, 0), 1d); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-renderers/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-client 7.75.0-SNAPSHOT dashbuilder-renderers pom Dashbuilder Renderer Libraries dashbuilder-renderer-default dashbuilder-renderer-chartjs dashbuilder-renderer-c3 dashbuilder-renderer-google ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/pom.xml ================================================ dashbuilder-client org.dashbuilder 7.75.0-SNAPSHOT 4.0.0 dashbuilder-widgets jar Dashbuilder Widgets com.google.gwt gwt-user provided org.gwtbootstrap3 gwtbootstrap3 org.gwtbootstrap3 gwtbootstrap3-extras org.jboss.errai errai-common org.jboss.errai errai-ioc org.uberfire uberfire-client-all org.uberfire uberfire-client-api org.uberfire uberfire-api org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-workbench-client org.uberfire uberfire-widgets-commons org.dashbuilder dashbuilder-validations org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-services-api org.dashbuilder dashbuilder-common-client org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-displayer-client org.dashbuilder dashbuilder-renderer-default com.google.gwt.gwtmockito gwtmockito test org.uberfire uberfire-testing-utils test org.kie.soup kie-soup-dataset-api test-jar test org.dashbuilder dashbuilder-dataset-client test-jar test org.dashbuilder dashbuilder-displayer-client test-jar test ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/common/ClientRuntimeErrorPopupPresenter.java ================================================ package org.dashbuilder.client.widgets.common; import org.dashbuilder.client.widgets.resources.i18n.DataSetExplorerConstants; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Specializes; import javax.inject.Inject; /** *

    Error Popup presenter for client runtime errors.

    * @since 0.4.0 */ @ApplicationScoped @Specializes public class ClientRuntimeErrorPopupPresenter extends ErrorPopupPresenter { @Inject public ClientRuntimeErrorPopupPresenter(View view) { super(view); } /** * Shows the given message in a modal popup that appears above all other workbench contents. * // TODO: Improve generated message by getting intermediate exception cause messages. * @param error The client runtime error. */ public void showMessage( final ClientRuntimeError error) { StringBuilder result = new StringBuilder(DataSetExplorerConstants.INSTANCE.error()); if (error != null) { final String message = error.getMessage(); Throwable t = error.getRootCause(); String localizedMessage = t != null ? t.getLocalizedMessage() : null; result = new StringBuilder(message); if (localizedMessage != null) { result.append(" ").append(DataSetExplorerConstants.INSTANCE.cause()). append(": ").append(localizedMessage); } } showMessage(result.toString()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/common/DataSetEditorPlugin.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.common; import org.dashbuilder.dataprovider.DataSetProviderType; import com.google.gwt.safehtml.shared.SafeUri; public interface DataSetEditorPlugin { String getTypeSelectorTitle(); String getTypeSelectorText(); SafeUri getTypeSelectorImageUri(); DataSetProviderType getProviderType(); Class getBasicAttributesWorkflowClass(); Class getWorkflowClass(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/common/LoadingBox.java ================================================ package org.dashbuilder.client.widgets.common; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; /** *

    A loading box presenter.

    * * @since 0.8.0 */ @ApplicationScoped public class LoadingBox { public interface View { void show(String message); void close(); } View view; public LoadingBox() { } @Inject public LoadingBox(View view) { this.view = view; } public void show() { view.show(DataSetEditorConstants.INSTANCE.loading()); } public void hide() { view.close(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/common/LoadingBoxView.java ================================================ package org.dashbuilder.client.widgets.common; import org.uberfire.ext.widgets.common.client.common.BusyPopup; /** *

    A loading box view using org.uberfire.ext.widgets.common.client.common.BusyPopup.

    * * @since 0.8.0 */ public class LoadingBoxView implements LoadingBox.View { @Override public void show(final String message) { BusyPopup.showMessage(message); } @Override public void close() { BusyPopup.close(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefColumnsFilterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.dataset.editor.column.DataSetDefColumnsEditor; import org.dashbuilder.client.widgets.dataset.event.FilterChangedEvent; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.DataSetFilter; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** *

    Data Set columns and filter editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefColumnsFilterEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefColumnsFilterEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(IsWidget columnsEditorView, DataSetDefFilterEditor.View dataSetFilterEditorView); void setMaxHeight(final String maxHeight); } DataSetDefColumnsEditor columnsEditor; DataSetDefFilterEditor dataSetFilterEditor; public View view; @Inject public DataSetDefColumnsFilterEditor(final DataSetDefColumnsEditor columnsEditor, final DataSetDefFilterEditor dataSetFilterEditor, final View view) { this.columnsEditor = columnsEditor; this.dataSetFilterEditor = dataSetFilterEditor; this.view = view; } @PostConstruct public void init() { view.init(this); view.initWidgets(columnsEditor.asWidget(), dataSetFilterEditor.view); } @Override public Widget asWidget() { return view.asWidget(); } public void setMaxHeight(final String maxHeight) { view.setMaxHeight(maxHeight); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public org.dashbuilder.dataset.client.editor.DataSetDefColumnsEditor columnListEditor() { return columnsEditor; } @Override public org.dashbuilder.dataset.client.editor.DataSetDefFilterEditor dataSetFilter() { return dataSetFilterEditor; } @Override public void setAcceptableValues(final List acceptableValues) { columnsEditor.setAcceptableValues(acceptableValues); } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final DataSetDef value) { if (value != null && value.getDataSetFilter() != null) { updateColumnsRestrictedByFilter(null, value.getDataSetFilter()); } } @Override public void setDelegate(final EditorDelegate delegate) { } private void updateColumnsRestrictedByFilter(final DataSetFilter oldFilter, final DataSetFilter f) { final List oldFilterColumns = getFilterColumnIds(oldFilter); final List newFilterColumns = getFilterColumnIds(f); // Check columns removed from filter. if (!oldFilterColumns.isEmpty()) { for (final String oldFilterColumn : oldFilterColumns) { final boolean isRemoved = !newFilterColumns.contains(oldFilterColumn); if (isRemoved) { columnsEditor.onValueUnRestricted(oldFilterColumn); } } } // Check columns removed from filter. if (!newFilterColumns.isEmpty()) { for (final String newFilterColumn : newFilterColumns) { columnsEditor.onValueRestricted(newFilterColumn); } } } private List getFilterColumnIds(final DataSetFilter filter) { final List result = new ArrayList(); if (filter != null) { List columnFilters = filter.getColumnFilterList(); if (columnFilters != null && !columnFilters.isEmpty()) { for (final ColumnFilter cFilter : columnFilters) { result.add(cFilter.getColumnId()); } } } return result; } /** * Listen to filter changed event in order to restrict or enable again columns used in it. * * @param filterChangedEvent The event. */ void onFilterChangedEvent(@Observes FilterChangedEvent filterChangedEvent) { checkNotNull("filterChangedEvent", filterChangedEvent); if (filterChangedEvent.getContext().equals(dataSetFilterEditor)) { final DataSetFilter old = filterChangedEvent.getOldFilter(); final DataSetFilter f = filterChangedEvent.getFilter(); updateColumnsRestrictedByFilter(old, f); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefColumnsFilterEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.TabContent; import org.gwtbootstrap3.client.ui.TabListItem; import org.gwtbootstrap3.client.ui.TabPane; import javax.enterprise.context.Dependent; /** *

    Data Set columns and filter editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefColumnsFilterEditorView extends Composite implements DataSetDefColumnsFilterEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } DataSetDefColumnsFilterEditor presenter; @UiField TabListItem columnsTabItem; @UiField TabListItem filterTabItem; @UiField TabContent tabContent; @UiField TabPane columnsTabPane; @UiField TabPane filterTabPane; @UiField(provided = true) IsWidget columnsEditorView; @UiField(provided = true) DataSetDefFilterEditor.View dataSetFilterEditorView; @Override public void init(final DataSetDefColumnsFilterEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(IsWidget columnsEditorView, DataSetDefFilterEditor.View dataSetFilterEditorView) { this.columnsEditorView = columnsEditorView; this.dataSetFilterEditorView = dataSetFilterEditorView; initWidget(Binder.BINDER.createAndBindUi(this)); columnsTabItem.setDataTargetWidget(columnsTabPane); filterTabItem.setDataTargetWidget(filterTabPane); } public void setMaxHeight(final String maxHeight) { tabContent.getElement().getStyle().setProperty("maxHeight", maxHeight); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefColumnsFilterEditorView.ui.xml ================================================ .tabContent { margin-top: 10px; margin-right: 10px; overflow-y: auto; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefFilterEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.dataset.event.FilterChangedEvent; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.displayer.client.events.DataSetFilterChangedEvent; import org.dashbuilder.displayer.client.widgets.filter.DataSetFilterEditor; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; /** *

    Data Set filter editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefFilterEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefFilterEditor { public interface View extends UberView { View setWidget(IsWidget filterView); } Event filterChangedEvent; public View view; DataSetFilterEditor filterEditor; DataSetFilter value; @Inject public DataSetDefFilterEditor(View view, DataSetFilterEditor filterEditor, final Event filterChangedEvent) { this.view = view; this.filterEditor = filterEditor; this.filterChangedEvent = filterChangedEvent; view.init(this); } @Override public void init(DataSetMetadata metadata) { view.setWidget(filterEditor); filterEditor.init(value != null ? value.cloneInstance() : null, metadata); } @Override public Widget asWidget() { return view.asWidget(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final DataSetFilter value) { this.value = value != null ? value.cloneInstance() : null; } @Override public void setDelegate(final EditorDelegate delegate) { // No delegation required. } void onValueChanged(@Observes DataSetFilterChangedEvent event) { // Set the new value. DataSetFilter before = this.value; setValue(event.getFilter()); // Fire the value change event. filterChangedEvent.fire(new FilterChangedEvent(DataSetDefFilterEditor.this, before, value)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefFilterEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import javax.enterprise.context.Dependent; /** *

    Data Set filter editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefFilterEditorView extends Composite implements DataSetDefFilterEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } DataSetDefFilterEditor presenter; @UiField FlowPanel mainPanel; @Override public void init(final DataSetDefFilterEditor presenter) { this.presenter = presenter; initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public DataSetDefFilterEditor.View setWidget(final IsWidget filterView) { mainPanel.clear(); mainPanel.add(filterView); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefFilterEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefPreviewTable.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.TableDisplayerSettingsBuilder; import org.dashbuilder.displayer.client.AbstractDisplayerListener; import org.dashbuilder.displayer.client.DataSetEditHandler; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerListener; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.renderer.client.DefaultRenderer; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import java.util.Collection; /** *

    Data Set table preview presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefPreviewTable implements IsWidget { public interface View extends UberView { View setDisplayer(IsWidget widget); View clear(); } DataSetClientServices clientServices; DisplayerLocator displayerLocator; public View view; Displayer tableDisplayer; @Inject public DataSetDefPreviewTable(final DisplayerLocator displayerLocator, final DataSetClientServices clientServices, final View view) { this.displayerLocator = displayerLocator; this.clientServices = clientServices; this.view = view; } @PostConstruct public void init() { view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void show(final DataSetDef dataSetDef, final Collection columns, final DisplayerListener displayerListener) { clear(); if (dataSetDef != null) { // Build the table displayer settings. final TableDisplayerSettingsBuilder settingsBuilder = DisplayerSettingsFactory.newTableSettings() .dataset(dataSetDef.getUUID()) .renderer(DefaultRenderer.UUID) .titleVisible(false) .tablePageSize(10) .resizable(true) .tableOrderEnabled(true) .tableColumnPickerEnabled(false) .filterOn(true, false, false); // Make only the specified columns visible (if null then show all) if (columns != null && !columns.isEmpty()) { for (final DataColumnDef column : columns) { settingsBuilder.column(column.getId()); } } // Disable backend cache for preview. DataSetDef editCloneWithoutCacheSettings = dataSetDef.clone(); editCloneWithoutCacheSettings.setCacheEnabled(false); // Close the current displayer (if any) if (tableDisplayer != null) { tableDisplayer.close(); } // Configure the table displayer and the data set handler for edition. DisplayerSettings settings = settingsBuilder.buildSettings(); tableDisplayer = displayerLocator.lookupDisplayer(settings); tableDisplayer.setDataSetHandler(new DataSetEditHandler(clientServices, settings.getDataSetLookup(), editCloneWithoutCacheSettings)); // For CSV datasets, make sure dates & numbers are displayed as defined in the CSV configuration if (dataSetDef instanceof CSVDataSetDef) { CSVDataSetDef csvDataSetDef = (CSVDataSetDef) dataSetDef; tableDisplayer.addListener(new AbstractDisplayerListener() { // The column settings are set right after the data set load, once the dataset columns are known @Override public void onDataLoaded(Displayer displayer) { configureColumnSettings(displayer, csvDataSetDef); } }); } // Draw the table draw(displayerListener); } } protected void configureColumnSettings(Displayer displayer, CSVDataSetDef csvDataSetDef) { DataSet dataSet = displayer.getDataSetHandler().getLastDataSet(); dataSet.getColumns().stream().forEach(column -> { if (column.getColumnType().equals(ColumnType.DATE)) { String pattern = csvDataSetDef.getDatePattern(column.getId()); if (pattern != null) { displayer.getDisplayerSettings().setColumnValuePattern(column.getId(), pattern); } } else if (column.getColumnType().equals(ColumnType.NUMBER)) { String pattern = csvDataSetDef.getNumberPattern(column.getId()); if (pattern != null) { displayer.getDisplayerSettings().setColumnValuePattern(column.getId(), pattern); } } }); } // Show the table displayer. void draw(final DisplayerListener displayerListener) { tableDisplayer.addListener(displayerListener); view.setDisplayer(tableDisplayer); tableDisplayer.draw(); } public void clear() { tableDisplayer = null; view.clear(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefPreviewTableView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Document; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import javax.enterprise.context.Dependent; /** *

    Data Set table preview view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefPreviewTableView extends Composite implements DataSetDefPreviewTable.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } DataSetDefPreviewTable presenter; @UiField FlowPanel mainPanel; @UiConstructor public DataSetDefPreviewTableView() { initWidget(Binder.BINDER.createAndBindUi(this)); // Set id for selenium tests mainPanel.getElement() .setId("ds-preview-editor-" + Document.get().createUniqueId()); } @Override public void init(final DataSetDefPreviewTable presenter) { this.presenter = presenter; } @Override public DataSetDefPreviewTable.View setDisplayer(final IsWidget widget) { mainPanel.add(widget); return this; } @Override public DataSetDefPreviewTable.View clear() { mainPanel.clear(); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefPreviewTableView.ui.xml ================================================ .mainPanel { margin-top: 10px; width: 100%; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefProviderTypeEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor; import static org.dashbuilder.dataprovider.DataSetProviderType.BEAN; import static org.dashbuilder.dataprovider.DataSetProviderType.CSV; import static org.dashbuilder.dataprovider.DataSetProviderType.PROMETHEUS; import static org.dashbuilder.dataprovider.DataSetProviderType.SQL; import static org.dashbuilder.dataprovider.DataSetProviderType.KAFKA; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.client.widgets.dataset.event.DataSetDefCreationRequestEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.list.HorizImageListEditor; import org.dashbuilder.common.client.editor.list.ImageListEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.resources.bundles.DataSetClientResources; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.kie.soup.commons.validation.PortablePreconditions; import org.uberfire.client.mvp.UberView; import com.google.gwt.editor.client.EditorError; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; /** *

    Data Set provider type editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefProviderTypeEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefProviderTypeEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(IsWidget listEditorView); } HorizImageListEditor provider; Event createEvent; public View view; ManagedInstance dataSetEditorPlugin; @Inject public DataSetDefProviderTypeEditor(final HorizImageListEditor provider, final Event createEvent, final View view, final ManagedInstance dataSetEditorPlugin) { this.provider = provider; this.createEvent = createEvent; this.view = view; this.dataSetEditorPlugin = dataSetEditorPlugin; } @PostConstruct public void init() { view.init(this); // Initialize the acceptable values for DataSetProviderType. final Collection.Entry> entries = getDefaultEntries(); provider.setEntries(entries); view.initWidgets(provider.view); } @Override public Widget asWidget() { return view.asWidget(); } void onItemClicked(@Observes ValueChangeEvent event) { PortablePreconditions.checkNotNull("ValueChangeEvent", event); if (event.getContext().equals(provider)) { createEvent.fire(new DataSetDefCreationRequestEvent(this, event.getValue())); } } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public void showErrors(final List errors) { // Defaults to no-operation. Errors are delegated to the ImageListEditor component. } @Override public HorizImageListEditor provider() { return provider; } /** * The provider types supported by this editor */ DataSetProviderType[] CORE_TYPES = new DataSetProviderType[]{BEAN, CSV, SQL, PROMETHEUS, KAFKA}; protected Collection.Entry> getDefaultEntries() { final DataSetProviderType[] providerTypes = CORE_TYPES; final Collection.Entry> entries = new ArrayList<>(providerTypes.length); for (final DataSetProviderType type : providerTypes) { final String title = getTypeSelectorTitle(type); final String text = getTypeSelectorText(type); final SafeUri uri = getTypeSelectorImageUri(type); final ImageListEditor.Entry entry = provider.newEntry(type, uri, new SafeHtmlBuilder().appendEscaped(title).toSafeHtml(), new SafeHtmlBuilder().appendEscaped(text).toSafeHtml()); entries.add(entry); } if (!dataSetEditorPlugin.isUnsatisfied()) { for (DataSetEditorPlugin pluginEditor : dataSetEditorPlugin) { final String title = pluginEditor.getTypeSelectorTitle(); final String text = pluginEditor.getTypeSelectorText(); final SafeUri uri = pluginEditor.getTypeSelectorImageUri(); final ImageListEditor.Entry entry = provider.newEntry(pluginEditor.getProviderType(), uri, new SafeHtmlBuilder().appendEscaped(title).toSafeHtml(), new SafeHtmlBuilder().appendEscaped(text).toSafeHtml()); entries.add(entry); } } return entries; } String getTypeSelectorTitle(final DataSetProviderType type) { if (BEAN.equals(type)) { return DataSetEditorConstants.INSTANCE.bean(); } if (CSV.equals(type)) { return DataSetEditorConstants.INSTANCE.csv(); } if (SQL.equals(type)) { return DataSetEditorConstants.INSTANCE.sql(); } if (PROMETHEUS.equals(type)) { return DataSetEditorConstants.INSTANCE.prometheus(); } if (KAFKA.equals(type)) { return DataSetEditorConstants.INSTANCE.kafka(); } return null; } String getTypeSelectorText(final DataSetProviderType type) { if (BEAN.equals(type)) { return DataSetEditorConstants.INSTANCE.bean_description(); } if (CSV.equals(type)) { return DataSetEditorConstants.INSTANCE.csv_description(); } if (SQL.equals(type)) { return DataSetEditorConstants.INSTANCE.sql_description(); } if (PROMETHEUS.equals(type)) { return DataSetEditorConstants.INSTANCE.prometheus_description(); } if (KAFKA.equals(type)) { return DataSetEditorConstants.INSTANCE.kafka_description(); } return null; } SafeUri getTypeSelectorImageUri(final DataSetProviderType type) { if (BEAN.equals(type)) { return DataSetClientResources.INSTANCE.images().javaIcon160().getSafeUri(); } if (CSV.equals(type)) { return DataSetClientResources.INSTANCE.images().csvIcon160().getSafeUri(); } if (SQL.equals(type)) { return DataSetClientResources.INSTANCE.images().sqlIcon160().getSafeUri(); } if (PROMETHEUS.equals(type)) { return DataSetClientResources.INSTANCE.images().prometheusIcon160().getSafeUri(); } if (KAFKA.equals(type)) { return DataSetClientResources.INSTANCE.images().kafkaIcon160().getSafeUri(); } return null; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefProviderTypeEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import javax.enterprise.context.Dependent; /** *

    The Data Set provider type editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefProviderTypeEditorView extends Composite implements DataSetDefProviderTypeEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } @UiField(provided = true) IsWidget listEditorView; DataSetDefProviderTypeEditor presenter; @Override public void init(final DataSetDefProviderTypeEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final IsWidget listEditorView) { this.listEditorView = listEditorView; initWidget(Binder.BINDER.createAndBindUi(this)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefProviderTypeEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.attributes.*; import org.dashbuilder.client.widgets.dataset.event.ColumnsChangedEvent; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.FilterChangedEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.DataSetDefEditor; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.displayer.client.AbstractDisplayerListener; import org.dashbuilder.displayer.client.Displayer; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import java.util.List; import static org.dashbuilder.dataprovider.DataSetProviderType.*; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** *

    Data Set Editor presenter.

    * * @since 0.4.0 */ public abstract class DataSetEditor implements IsWidget, DataSetDefEditor { public static final String TAB_CONFIGURATION = "configuration"; public static final String TAB_PREVIEW = "preview"; public static final String TAB_ADVANCED = "advanced"; public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(DataSetDefBasicAttributesEditor.View basicAttributesEditorView, IsWidget providerAttributesEditorView, DataSetDefColumnsFilterEditor.View columnsAndFilterEditorView, DataSetDefPreviewTable.View previewTableView, DataSetDefCacheAttributesEditorView backendCacheAttributesEditorView, DataSetDefCacheAttributesEditorView clientCacheAttributesEditorView, DataSetDefRefreshAttributesEditor.View refreshEditorView); void setConfigurationTabTitle(String title); void showConfigurationTab(); void addConfigurationTabItemClickHandler(final Command command); void showPreviewTab(); void addPreviewTabItemClickHandler(final Command command); void showAdvancedTab(); void addAdvancedTabItemClickHandler(final Command command); void openColumnsFilterPanel(String title); void closeColumnsFilterPanel(String title); void showErrorNotification(final SafeHtml text); void clearErrorNotification(); } protected DataSetDefBasicAttributesEditor basicAttributesEditor; protected IsWidget providerAttributesEditorView; protected DataSetDefColumnsFilterEditor columnsAndFilterEditor; protected DataSetDefPreviewTable previewTable; protected DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor; protected DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor; private DataSetDefRefreshAttributesEditor refreshEditor; protected DataSetClientServices clientServices; protected LoadingBox loadingBox; protected Event errorEvent; protected Event tabChangedEvent; /* The Data Set Editor view. */ public View view; protected DataSetDef dataSetDef; protected Command afterPreviewCommand; @Inject public DataSetEditor(final DataSetDefBasicAttributesEditor basicAttributesEditor, final IsWidget providerAttributesEditorView, final DataSetDefColumnsFilterEditor columnsAndFilterEditor, final DataSetDefPreviewTable previewTable, final DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor, final DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor, final DataSetDefRefreshAttributesEditor refreshEditor, final DataSetClientServices clientServices, final LoadingBox loadingBox, final Event errorEvent, final Event tabChangedEvent, final View view) { this.basicAttributesEditor = basicAttributesEditor; this.providerAttributesEditorView = providerAttributesEditorView; this.columnsAndFilterEditor = columnsAndFilterEditor; this.previewTable = previewTable; this.backendCacheAttributesEditor = backendCacheAttributesEditor; this.clientCacheAttributesEditor = clientCacheAttributesEditor; this.refreshEditor = refreshEditor; this.clientServices = clientServices; this.loadingBox = loadingBox; this.errorEvent = errorEvent; this.tabChangedEvent = tabChangedEvent; this.view = view; } public void init() { view.init(this); view.initWidgets(basicAttributesEditor.view, providerAttributesEditorView, columnsAndFilterEditor.view, previewTable.view, backendCacheAttributesEditor.view, clientCacheAttributesEditor.view, refreshEditor.view); view.addConfigurationTabItemClickHandler(configurationTabItemClickHandler); view.addPreviewTabItemClickHandler(previewTabItemClickHandler); view.addAdvancedTabItemClickHandler(advancedTabItemClickHandler); columnsAndFilterEditor.setMaxHeight("400px"); backendCacheAttributesEditor.setRange(200d, 10000d); clientCacheAttributesEditor.setRange(00d, 4096d); } /************************************************************* ** PUBLIC EDITOR METHODS ** *************************************************************/ @Override public Widget asWidget() { return view.asWidget(); } public void showConfigurationTab() { afterPreviewCommand = new Command() { @Override public void execute() { view.showConfigurationTab(); } }; } public void showPreviewTab() { afterPreviewCommand = new Command() { @Override public void execute() { view.showPreviewTab(); } }; } public void showAdvancedTab() { afterPreviewCommand = new Command() { @Override public void execute() { view.showAdvancedTab(); } }; } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public void setAcceptableValues(final List acceptableValues) { columnsAndFilterEditor.setAcceptableValues(acceptableValues); } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final T value) { this.dataSetDef = value; // Check specific provider type constraints. final DataSetProviderType type = value.getProvider() != null ? value.getProvider() : null; final String typeTitle = getTypeTitle(type); view.setConfigurationTabTitle(new StringBuffer(typeTitle).append(" ") .append(DataSetEditorConstants.INSTANCE.tab_configguration()).toString()); final boolean isBean = type != null && DataSetProviderType.BEAN.equals(type); if (isBean) { // Bean data sets do not support backend cache, its used by its own nature... backendCacheAttributesEditor = null; } // Load the preview table and update filter editor when having the resulting data set. doPreview(true); } @Override public void setDelegate(final EditorDelegate delegate) { // No delegation required. } @Override public org.dashbuilder.dataset.client.editor.DataSetDefBasicAttributesEditor basicAttributesEditor() { return basicAttributesEditor; } @Override public org.dashbuilder.dataset.client.editor.DataSetDefColumnsFilterEditor columnsAndFilterEditor() { return columnsAndFilterEditor; } @Override public DataSetDefBackendCacheAttributesEditor backendCacheEditor() { return backendCacheAttributesEditor; } @Override public org.dashbuilder.dataset.client.editor.DataSetDefClientCacheAttributesEditor clientCacheEditor() { return clientCacheAttributesEditor; } @Override public org.dashbuilder.dataset.client.editor.DataSetDefRefreshAttributesEditor refreshEditor() { return refreshEditor; } /************************************************************* ** VIEW CALLBACK METHODS ** *************************************************************/ void onOpenColumnsFilterPanel() { view.openColumnsFilterPanel(DataSetEditorConstants.INSTANCE.hideColumnsAndFilter()); } void onCloseColumnsFilterPanel() { view.closeColumnsFilterPanel(DataSetEditorConstants.INSTANCE.showColumnsAndFilter()); } /************************************************************* ** PRIVATE EDITOR METHODS ** *************************************************************/ protected void doPreview(final boolean isUpdateFilter) { loadingBox.show(); previewTable.show(dataSetDef, dataSetDef.getColumns(), new DataSetEditorListener(isUpdateFilter)); } protected void afterPreview(final DataSet dataSet, final boolean isUpdateFilter) { view.clearErrorNotification(); if (isUpdateFilter) { columnsAndFilterEditor.dataSetFilter().init(dataSet.getMetadata()); } if (afterPreviewCommand != null) { afterPreviewCommand.execute(); afterPreviewCommand = null; } loadingBox.hide(); } private class DataSetEditorListener extends AbstractDisplayerListener { private boolean isUpdateFilter; public DataSetEditorListener(final boolean isUpdateFilter) { this.isUpdateFilter = isUpdateFilter; } @Override public void onDraw(final Displayer displayer) { final DataSet dataSet = displayer.getDataSetHandler().getLastDataSet(); afterPreview(dataSet, isUpdateFilter); } @Override public void onRedraw(final Displayer displayer) { final DataSet dataSet = displayer.getDataSetHandler().getLastDataSet(); afterPreview(dataSet, isUpdateFilter); } @Override public void onClose(final Displayer displayer) { loadingBox.hide(); } @Override public void onError(final Displayer displayer, final ClientRuntimeError error) { showError(error); } } protected void showError(final ClientRuntimeError error) { loadingBox.hide(); final String message = error.getCause() != null ? error.getCause() : error.getMessage(); view.showErrorNotification(new SafeHtmlBuilder().appendEscaped(message).toSafeHtml()); errorEvent.fire(new ErrorEvent(this, error)); if (afterPreviewCommand != null) { this.afterPreviewCommand.execute(); } } private String getTypeTitle(final DataSetProviderType type) { if (BEAN.equals(type)) { return DataSetEditorConstants.INSTANCE.bean(); } if (CSV.equals(type)) { return DataSetEditorConstants.INSTANCE.csv(); } if (SQL.equals(type)) { return DataSetEditorConstants.INSTANCE.sql(); } return ""; } protected final Command configurationTabItemClickHandler = new Command() { @Override public void execute() { tabChangedEvent.fire(new TabChangedEvent(DataSetEditor.this, TAB_CONFIGURATION)); } }; protected final Command previewTabItemClickHandler = new Command() { @Override public void execute() { tabChangedEvent.fire(new TabChangedEvent(DataSetEditor.this, TAB_PREVIEW)); } }; protected final Command advancedTabItemClickHandler = new Command() { @Override public void execute() { tabChangedEvent.fire(new TabChangedEvent(DataSetEditor.this, TAB_ADVANCED)); } }; void onColumnsChangedEvent(@Observes ColumnsChangedEvent columnsChangedEvent) { checkNotNull("columnsChangedEvent", columnsChangedEvent); if (columnsChangedEvent.getContext().equals(columnsAndFilterEditor.columnListEditor().columns())) { final List cols = columnsChangedEvent.getColumns(); dataSetDef.setColumns(cols); doPreview(true); } } void onFilterChangedEvent(@Observes FilterChangedEvent filterChangedEvent) { checkNotNull("filterChangedEvent", filterChangedEvent); if (filterChangedEvent.getContext().equals(columnsAndFilterEditor.dataSetFilter())) { final DataSetFilter f = filterChangedEvent.getFilter(); dataSetDef.setDataSetFilter(f); // Do not update filter, as the component status has been already updated by the user interaction. doPreview(false); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.logical.shared.OpenEvent; import com.google.gwt.event.logical.shared.OpenHandler; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.*; import org.dashbuilder.client.widgets.dataset.editor.attributes.*; import org.gwtbootstrap3.client.ui.Alert; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.TabListItem; import org.gwtbootstrap3.client.ui.TabPane; import org.gwtbootstrap3.client.ui.constants.IconType; import org.gwtbootstrap3.client.ui.html.Text; import org.uberfire.mvp.Command; import javax.enterprise.context.Dependent; /** *

    The Data Set Editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetEditorView extends Composite implements DataSetEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } DataSetEditor presenter; @UiField TabListItem basicAttributesTabItem; @UiField TabListItem previewTabItem; @UiField TabListItem advancedAttributesTabItem; @UiField TabPane basicAttributesTabPane; @UiField TabPane previewTabPane; @UiField DisclosurePanel filterAndColumnsPanel; @UiField Button filterAndColumnsPanelToggleButton; @UiField TabPane advancedAttributesTabPane; @UiField(provided = true) DataSetDefBasicAttributesEditor.View basicAttributesEditorView; @UiField(provided = true) IsWidget providerAttributesEditorView; @UiField(provided = true) DataSetDefColumnsFilterEditor.View columnsAndFilterEditorView; @UiField FlowPanel previewTablePanel; @UiField(provided = true) DataSetDefPreviewTable.View previewTableView; @UiField Alert previewErrorNotification; @UiField Text notificationLabel; @UiField(provided = true) DataSetDefCacheAttributesEditorView backendCacheAttributesEditorView; @UiField(provided = true) DataSetDefCacheAttributesEditorView clientCacheAttributesEditorView; @UiField(provided = true) DataSetDefRefreshAttributesEditor.View refreshEditorView; @Override public void init(final DataSetEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final DataSetDefBasicAttributesEditor.View basicAttributesEditorView, final IsWidget providerAttributesEditorView, final DataSetDefColumnsFilterEditor.View columnsAndFilterEditorView, final DataSetDefPreviewTable.View previewTableView, final DataSetDefCacheAttributesEditorView backendCacheAttributesEditorView, final DataSetDefCacheAttributesEditorView clientCacheAttributesEditorView, final DataSetDefRefreshAttributesEditor.View refreshEditorView) { this.basicAttributesEditorView = basicAttributesEditorView; this.providerAttributesEditorView = providerAttributesEditorView; this.columnsAndFilterEditorView = columnsAndFilterEditorView; this.previewTableView = previewTableView; this.backendCacheAttributesEditorView = backendCacheAttributesEditorView; this.clientCacheAttributesEditorView = clientCacheAttributesEditorView; this.refreshEditorView = refreshEditorView; initWidget(Binder.BINDER.createAndBindUi(this)); basicAttributesTabItem.setDataTargetWidget(basicAttributesTabPane); previewTabItem.setDataTargetWidget(previewTabPane); advancedAttributesTabItem.setDataTargetWidget(advancedAttributesTabPane); filterAndColumnsPanel.addOpenHandler(new OpenHandler() { @Override public void onOpen(final OpenEvent event) { presenter.onOpenColumnsFilterPanel(); } }); filterAndColumnsPanel.addCloseHandler(new CloseHandler() { @Override public void onClose(final CloseEvent event) { presenter.onCloseColumnsFilterPanel(); } }); } @Override public void setConfigurationTabTitle(String title) { basicAttributesTabItem.setText(title); basicAttributesTabItem.setTitle(title); } @Override public void showConfigurationTab() { basicAttributesTabItem.showTab(); } @Override public void showPreviewTab() { previewTabItem.showTab(); } @Override public void addPreviewTabItemClickHandler(final Command command) { previewTabItem.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { command.execute(); } }); } @Override public void showAdvancedTab() { advancedAttributesTabItem.showTab(); } @Override public void addAdvancedTabItemClickHandler(final Command command) { advancedAttributesTabItem.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { command.execute(); } }); } @Override public void openColumnsFilterPanel(final String title) { filterAndColumnsPanelToggleButton.setTitle(title); filterAndColumnsPanelToggleButton.setIcon(IconType.STEP_BACKWARD); filterAndColumnsPanelToggleButton.getElement().getStyle().setBorderStyle(Style.BorderStyle.SOLID); } @Override public void closeColumnsFilterPanel(final String title) { filterAndColumnsPanelToggleButton.setTitle(title); filterAndColumnsPanelToggleButton.setIcon(IconType.STEP_FORWARD); filterAndColumnsPanelToggleButton.getElement().getStyle().setBorderStyle(Style.BorderStyle.NONE); } public void addConfigurationTabItemClickHandler(final Command command) { basicAttributesTabItem.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { command.execute(); } }); } public void showErrorNotification(final SafeHtml text) { notificationLabel.setText(text.asString()); previewErrorNotification.setVisible(true); filterAndColumnsPanel.setVisible(false); previewTablePanel.setVisible(false); } public void clearErrorNotification() { notificationLabel.setText(""); previewErrorNotification.setVisible(false); filterAndColumnsPanel.setVisible(true); previewTablePanel.setVisible(true); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/DataSetEditorView.ui.xml ================================================ .mainPanel { width: 100%; margin: 20px; } .tabPane { margin-top: 25px; } .editorPanel { width: 100%; } .filterAndColumnsPanel { float: left; margin-right: 20px; } .filterAndColumnsPanelToggleButton { position: absolute; left: 25px; color: black; filter: alpha(opacity=5); opacity: 0.5; } .tablePreviewPanel { margin-left: 40px; height: 100%; max-height: 450px; overflow: auto; } .previewErrorAlert { margin-top: 20px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefBackendCacheAttributesEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ToggleSwitchEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** *

    Data Set backend cache attributes editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefBackendCacheAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefBackendCacheAttributesEditor { ToggleSwitchEditor cacheEnabled; ValueBoxEditor cacheMaxRows; public DataSetDefCacheAttributesEditorView view; @Inject public DataSetDefBackendCacheAttributesEditor(final ToggleSwitchEditor cacheEnabled, final ValueBoxEditor cacheMaxRows, final DataSetDefCacheAttributesEditorView view) { this.cacheEnabled = cacheEnabled; this.cacheMaxRows = cacheMaxRows; this.view = view; } @PostConstruct public void init() { view.init(viewCallback); view.init(DataSetEditorConstants.INSTANCE.backendCache(), DataSetEditorConstants.INSTANCE.rows(), cacheEnabled.asWidget(), cacheMaxRows.view); cacheMaxRows.addHelpContent(DataSetEditorConstants.INSTANCE.attributeMaxRows(), DataSetEditorConstants.INSTANCE.attributeMaxRows_description(), Placement.BOTTOM); } public void setRange(final Double min, final Double max) { view.setRange(min, max); } @Override public Widget asWidget() { return view.asWidget(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ToggleSwitchEditor cacheEnabled() { return cacheEnabled; } @Override public ValueBoxEditor cacheMaxRows() { return cacheMaxRows; } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final DataSetDef value) { Double _value = value != null ? value.getCacheMaxRows() : 100d; if (value != null && value.isCacheEnabled()) { enable(); } else { disable(); } view.setValue(_value); } @Override public void setDelegate(final EditorDelegate delegate) { } /************************************************************* ** VIEW CALLBACK METHODS ** *************************************************************/ final DataSetDefCacheAttributesEditorView.ViewCallback viewCallback = new DataSetDefCacheAttributesEditorView.ViewCallback() { @Override public void onValueChange(final Double value) { cacheMaxRows.setValue(value != null ? value.intValue() : 100); } }; /************************************************************* ** PRIVATE PRESENTER METHODS ** *************************************************************/ void enable() { view.setEnabled(true); } void disable() { view.setEnabled(false); } void onEnabledChangedEvent(@Observes ValueChangeEvent valueChangeEvent) { checkNotNull("valueChangeEvent", valueChangeEvent); if (valueChangeEvent.getContext().equals(cacheEnabled)) { if (valueChangeEvent.getValue()) { enable(); } else { disable(); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefBasicAttributesEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; /** *

    Data Set basic attributes (uuid, name) editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefBasicAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefBasicAttributesEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(ValueBoxEditor.View uuidEditor, ValueBoxEditor.View nameEditor); } ValueBoxEditor uuidEditor; ValueBoxEditor nameEditor; public View view; @Inject public DataSetDefBasicAttributesEditor(final ValueBoxEditor uuidEditor, final ValueBoxEditor nameEditor, final View view) { this.uuidEditor = uuidEditor; this.nameEditor = nameEditor; this.view = view; } @PostConstruct public void init() { view.init(this); view.initWidgets(uuidEditor.view, nameEditor.view); uuidEditor.addHelpContent(DataSetEditorConstants.INSTANCE.attributeUUID(), DataSetEditorConstants.INSTANCE.attributeUUID_description(), Placement.BOTTOM); nameEditor.addHelpContent(DataSetEditorConstants.INSTANCE.attributeName(), DataSetEditorConstants.INSTANCE.attributeName_description(), Placement.BOTTOM); } @Override public Widget asWidget() { return view.asWidget(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ValueBoxEditor UUID() { return uuidEditor; } @Override public ValueBoxEditor name() { return nameEditor; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefBasicAttributesEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import javax.enterprise.context.Dependent; /** *

    The Data Set Editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefBasicAttributesEditorView extends Composite implements DataSetDefBasicAttributesEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } DataSetDefBasicAttributesEditor presenter; @UiField(provided = true) ValueBoxEditor.View uuid; @UiField(provided = true) ValueBoxEditor.View name; @Override public void init(final DataSetDefBasicAttributesEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final ValueBoxEditor.View uuidEditor, final ValueBoxEditor.View nameEditor) { this.uuid = uuidEditor; this.name = nameEditor; initWidget(Binder.BINDER.createAndBindUi(this)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefBasicAttributesEditorView.ui.xml ================================================ .row { margin-bottom: 5px; } .attr { float: left; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefCacheAttributesEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.uberfire.client.mvp.UberView; /** *

    The Data Set cache attributes editor view.

    * * @since 0.4.0 */ public interface DataSetDefCacheAttributesEditorView extends UberView { interface ViewCallback { void onValueChange(Double value); } /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void init(String title, String units, IsWidget enabledView, ValueBoxEditor.View valueView); void setValue(final Double value); void setRange(Double min, Double max); void setEnabled(final boolean isEnabled); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefCacheAttributesEditorViewImpl.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.gwtbootstrap3.client.ui.Container; import org.gwtbootstrap3.client.ui.IntegerBox; import org.gwtbootstrap3.extras.slider.client.ui.Slider; import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideStopEvent; import org.gwtbootstrap3.extras.slider.client.ui.base.event.SlideStopHandler; import javax.enterprise.context.Dependent; /** *

    The Data Set cache attributes editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefCacheAttributesEditorViewImpl extends Composite implements DataSetDefCacheAttributesEditorView { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } ViewCallback callback; @UiField Container mainContainer; @UiField(provided = true) IsWidget enabledView; @UiField HTML title; @UiField(provided = true) ValueBoxEditor.View valueView; @UiField IntegerBox valueBox; @UiField HTML units; @UiField Slider slider; @Override public void init(final ViewCallback callback) { this.callback = callback; } @Override public void init(final String title, final String units, final IsWidget enabledView, final ValueBoxEditor.View valueView) { this.enabledView = enabledView; this.valueView = valueView; initWidget(Binder.BINDER.createAndBindUi(this)); this.units.setText(units); this.units.setTitle(units); this.title.setText(title); slider.addSlideStopHandler(new SlideStopHandler() { @Override public void onSlideStop(final SlideStopEvent event) { // NOTE: Parse double from string value to avoid https://github.com/gwtbootstrap3/gwtbootstrap3-extras/issues/169 final Object value = event.getValue(); final Double _v = Double.parseDouble(value.toString()); callback.onValueChange(_v); } }); } public void setEnabled(final boolean isEnabled) { valueBox.setEnabled(isEnabled); slider.setEnabled(isEnabled); } public void setValue(final Double value) { mainContainer.setVisible(true); slider.setValue(value); } @Override public void setRange(final Double min, final Double max) { slider.setMin(min); slider.setMax(max); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefCacheAttributesEditorViewImpl.ui.xml ================================================ .valueBox { width: 50px; } .inlineText { margin-left: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefClientCacheAttributesEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ToggleSwitchEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** *

    Data Set client cache attributes editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefClientCacheAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefClientCacheAttributesEditor { ToggleSwitchEditor pushEnabled; ValueBoxEditor pushMaxSize; public DataSetDefCacheAttributesEditorView view; @Inject public DataSetDefClientCacheAttributesEditor(final ToggleSwitchEditor pushEnabled, final ValueBoxEditor pushMaxSize, final DataSetDefCacheAttributesEditorView view) { this.pushEnabled = pushEnabled; this.pushMaxSize = pushMaxSize; this.view = view; } @PostConstruct public void init() { view.init(viewCallback); view.init(DataSetEditorConstants.INSTANCE.clientCache(), DataSetEditorConstants.INSTANCE.bytes(), pushEnabled.asWidget(), pushMaxSize.view); pushMaxSize.addHelpContent(DataSetEditorConstants.INSTANCE.attributeMaxBytes(), DataSetEditorConstants.INSTANCE.attributeMaxBytes_description(), Placement.BOTTOM); } public void setRange(final Double min, final Double max) { view.setRange(min, max); } @Override public Widget asWidget() { return view.asWidget(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ToggleSwitchEditor pushEnabled() { return pushEnabled; } @Override public ValueBoxEditor pushMaxSize() { return pushMaxSize; } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final DataSetDef value) { Double _value = value != null ? value.getPushMaxSize() : 100d; if (value != null && value.isPushEnabled()) { enable(); } else { disable(); } view.setValue(_value); } @Override public void setDelegate(final EditorDelegate delegate) { } /************************************************************* ** VIEW CALLBACK METHODS ** *************************************************************/ final DataSetDefCacheAttributesEditorView.ViewCallback viewCallback = new DataSetDefCacheAttributesEditorView.ViewCallback() { @Override public void onValueChange(Double value) { pushMaxSize.setValue(value != null ? value.intValue() : 100); } }; /************************************************************* ** PRIVATE PRESENTER METHODS ** *************************************************************/ void enable() { view.setEnabled(true); } void disable() { view.setEnabled(false); } void onEnabledChangedEvent(@Observes ValueChangeEvent valueChangeEvent) { checkNotNull("valueChangeEvent", valueChangeEvent); if (valueChangeEvent.getContext().equals(pushEnabled)) { if (valueChangeEvent.getValue()) { enable(); } else { disable(); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefRefreshAttributesEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ToggleSwitchEditor; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; /** *

    Data Set refresh attributes editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataSetDefRefreshAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefRefreshAttributesEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(IsWidget enabledView, DataSetDefRefreshIntervalEditor.View valueView); void addRefreshEnabledButtonHandler(Command handler); void setEnabled(boolean enabled); } ToggleSwitchEditor refreshAlways; DataSetDefRefreshIntervalEditor refreshTime; public View view; boolean isRefreshEnabled; @Inject public DataSetDefRefreshAttributesEditor(final ToggleSwitchEditor refreshAlways, final DataSetDefRefreshIntervalEditor refreshTime, final View view) { this.refreshAlways = refreshAlways; this.refreshTime = refreshTime; this.view = view; } @PostConstruct public void init() { view.init(this); view.initWidgets(refreshAlways.asWidget(), refreshTime.view); view.addRefreshEnabledButtonHandler(refreshEnabledButtonHandler); refreshTime.addHelpContent(DataSetEditorConstants.INSTANCE.attributeRefreshInterval(), DataSetEditorConstants.INSTANCE.attributeRefreshInterval_description(), Placement.RIGHT); } public boolean isRefreshEnabled() { return isRefreshEnabled; } @Override public Widget asWidget() { return view.asWidget(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ToggleSwitchEditor refreshAlways() { return refreshAlways; } @Override public DataSetDefRefreshIntervalEditor refreshTime() { return refreshTime; } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final DataSetDef value) { final String rTime = value != null ? value.getRefreshTime() : null; setRefreshEnabled(rTime != null); } @Override public void setDelegate(final EditorDelegate delegate) { } /************************************************************* ** PRIVATE PRESENTER METHODS ** *************************************************************/ private void setRefreshEnabled(final boolean refreshEnabled) { this.isRefreshEnabled = refreshEnabled; view.setEnabled(refreshEnabled); refreshTime.setEnabled(refreshEnabled); refreshAlways.setEnabled(refreshEnabled); } final Command refreshEnabledButtonHandler = new Command() { @Override public void execute() { setRefreshEnabled(!isRefreshEnabled); } }; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefRefreshAttributesEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.core.client.GWT; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.extras.toggleswitch.client.ui.ToggleSwitch; import org.uberfire.mvp.Command; import javax.enterprise.context.Dependent; /** *

    The Data Set refresh attributes editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefRefreshAttributesEditorView extends Composite implements DataSetDefRefreshAttributesEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } DataSetDefRefreshAttributesEditor presenter; @UiField ToggleSwitch refreshEnabled; @UiField(provided = true) DataSetDefRefreshIntervalEditor.View refreshTimeView; @UiField(provided = true) IsWidget refreshOnStaleDataView; private HandlerRegistration handlerRegistration; @Override public void init(final DataSetDefRefreshAttributesEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final IsWidget enabledView, final DataSetDefRefreshIntervalEditor.View refreshTimeView) { this.refreshOnStaleDataView = enabledView; this.refreshTimeView = refreshTimeView; initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public void addRefreshEnabledButtonHandler(final Command handler) { if (handlerRegistration != null) { handlerRegistration.removeHandler(); } handlerRegistration = refreshEnabled.addValueChangeHandler(new ValueChangeHandler() { @Override public void onValueChange(final ValueChangeEvent event) { handler.execute();; } }); } @Override public void setEnabled(final boolean isEnabled) { refreshEnabled.setValue(isEnabled); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefRefreshAttributesEditorView.ui.xml ================================================ .inlineText { margin-left: 10px; } .refreshOnStaleDataRow { margin-top: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefRefreshIntervalEditor.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.client.resources.i18n.DateIntervalTypeConstants; import org.dashbuilder.dataset.date.TimeAmount; import org.dashbuilder.dataset.group.DateIntervalType; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import java.util.Arrays; import java.util.List; /** *

    Provides an editor for a the refreshInterval data set definition attribute..

    * * @since 0.4.0 */ @Dependent public class DataSetDefRefreshIntervalEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefRefreshIntervalEditor { private static final DateIntervalType DEFAULT_INTERVAL_TYPE = DateIntervalType.HOUR; private static List ALLOWED_TYPES = Arrays.asList( DateIntervalType.SECOND, DateIntervalType.MINUTE, DateIntervalType.HOUR, DateIntervalType.DAY, DateIntervalType.MONTH, DateIntervalType.YEAR); public interface View extends UberView { View addHelpContent(final String title, final String content, final Placement placement); View addIntervalTypeItem(String item); View setSelectedIntervalType(int index); int getSelectedIntervalTypeIndex(); View setQuantity(double value); double getQuantity(); View setEnabled(boolean enabled); } Event> valueChangeEvent; public View view; @Inject public DataSetDefRefreshIntervalEditor(final View view, final Event> valueChangeEvent) { this.view = view; this.valueChangeEvent = valueChangeEvent; } @PostConstruct public void init() { view.init(this); // List box for available date interval types. for (final DateIntervalType dateInterval : ALLOWED_TYPES) { final String s = DateIntervalTypeConstants.INSTANCE.getString(dateInterval.name()); view.addIntervalTypeItem(s); } } @Override public Widget asWidget() { return view.asWidget(); } public void addHelpContent(final String title, final String content, final Placement placement) { view.addHelpContent(title, content, placement); } @Override public void setEnabled(final boolean isEnabled) { view.setEnabled(isEnabled); } @Override public void setValue(final String value) { double quantity = 1; int index = -1; if (value != null) { final TimeAmount timeAmount = TimeAmount.parse(value); quantity = timeAmount.getQuantity(); final DateIntervalType dType = timeAmount.getType(); index = getIntervalTypeIndex(dType); } view.setQuantity(quantity); view.setSelectedIntervalType(index > -1 ? index : getIntervalTypeIndex(DEFAULT_INTERVAL_TYPE)); } @Override public String getValue() { final Double quantity = view.getQuantity(); final DateIntervalType type = getSelectedIntervalType(); return new TimeAmount(quantity.longValue(), type).toString(); } private DateIntervalType getSelectedIntervalType() { return ALLOWED_TYPES.get(view.getSelectedIntervalTypeIndex()); } private int getIntervalTypeIndex(DateIntervalType type) { for (int i=0; iThe DataSetDefRefreshIntervalEditor editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetDefRefreshIntervalEditorView extends Composite implements DataSetDefRefreshIntervalEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } @UiField HorizontalPanel mainPanel; @UiField IntegerBox valueBox; @UiField ListBox intervalType; DataSetDefRefreshIntervalEditor presenter; @UiConstructor public DataSetDefRefreshIntervalEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public void init(final DataSetDefRefreshIntervalEditor presenter) { this.presenter = presenter; } @Override public DataSetDefRefreshIntervalEditor.View addIntervalTypeItem(final String item) { intervalType.addItem(item); return this; } @Override public DataSetDefRefreshIntervalEditor.View setSelectedIntervalType(final int index) { intervalType.setSelectedIndex(index); return this; } @Override public int getSelectedIntervalTypeIndex() { return intervalType.getSelectedIndex(); } @Override public DataSetDefRefreshIntervalEditor.View setQuantity(final double value) { valueBox.setValue((int) value); return this; } @Override public double getQuantity() { final Integer value = valueBox.getValue(); return value != null ? value.doubleValue() : 0; } @Override public DataSetDefRefreshIntervalEditor.View setEnabled(final boolean isEnabled) { valueBox.setEnabled(isEnabled); intervalType.setEnabled(isEnabled); return this; } @Override public DataSetDefRefreshIntervalEditor.View addHelpContent(final String title, final String content, final Placement placement) { final Tooltip tooltip = new Tooltip(intervalType); tooltip.setContainer("body"); tooltip.setShowDelayMs(1000); tooltip.setPlacement(placement); tooltip.setTitle(content); mainPanel.add(tooltip); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefRefreshIntervalEditorView.ui.xml ================================================ .valueBox { width: 50px; } .inline { margin-left: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/bean/BeanDataSetDefAttributesEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.bean; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.map.MapEditor; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; /** *

    Bean Data Set specific attributes editor presenter.

    * * @since 0.4.0 */ @Dependent public class BeanDataSetDefAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.BeanDataSetDefAttributesEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(ValueBoxEditor.View generatorClassView, IsWidget parameterMapView); } ValueBoxEditor generatorClass; MapEditor paramaterMap; public View view; @Inject public BeanDataSetDefAttributesEditor(final ValueBoxEditor generatorClass, final MapEditor paramaterMap, final View view) { this.generatorClass = generatorClass; this.paramaterMap = paramaterMap; this.view = view; } @PostConstruct public void init() { // Initialize the Bean specific attributes editor view. view.init(this); view.initWidgets(generatorClass.view, paramaterMap.asWidget()); generatorClass.addHelpContent(DataSetEditorConstants.INSTANCE.bean_generator_class(), DataSetEditorConstants.INSTANCE.bean_generator_class_description(), Placement.BOTTOM); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public Widget asWidget() { return view.asWidget(); } @Override public ValueBoxEditor generatorClass() { return generatorClass; } @Override public MapEditor paramaterMap() { return paramaterMap; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/bean/BeanDataSetDefAttributesEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.bean; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import javax.enterprise.context.Dependent; /** *

    The Bean Data Set attributes editor view.

    * * @since 0.4.0 */ @Dependent public class BeanDataSetDefAttributesEditorView extends Composite implements BeanDataSetDefAttributesEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } BeanDataSetDefAttributesEditor presenter; @UiField(provided = true) ValueBoxEditor.View generatorClassView; @UiField(provided = true) IsWidget parameterMapView; @Override public void init(final BeanDataSetDefAttributesEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final ValueBoxEditor.View generatorClassView, final IsWidget parameterMapView) { this.generatorClassView = generatorClassView; this.parameterMapView = parameterMapView; initWidget(Binder.BINDER.createAndBindUi(this)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/bean/BeanDataSetDefAttributesEditorView.ui.xml ================================================ .row { margin-bottom: 5px; } .parameterMap { width: 80%; background-color: ghostwhite; border: 1px solid #E3E3E3; border-radius: 4px 4px 4px 4px; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05) inset; min-height: 20px; padding: 20px; } .attr { float: left; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/bean/BeanDataSetEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.bean; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.map.MapEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.BeanDataSetDef; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; /** *

    Bean Data Set editor presenter.

    * * @since 0.4.0 */ @Dependent public class BeanDataSetEditor extends DataSetEditor implements org.dashbuilder.dataset.client.editor.BeanDataSetDefEditor { BeanDataSetDefAttributesEditor attributesEditor; @Inject public BeanDataSetEditor(final DataSetDefBasicAttributesEditor basicAttributesEditor, final BeanDataSetDefAttributesEditor attributesEditor, final DataSetDefColumnsFilterEditor columnsAndFilterEditor, final DataSetDefPreviewTable previewTable, final DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor, final DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor, final DataSetDefRefreshAttributesEditor refreshEditor, final DataSetClientServices clientServices, final LoadingBox loadingBox, final Event errorEvent, final Event tabChangedEvent, final View view) { super(basicAttributesEditor, attributesEditor.view, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); this.attributesEditor = attributesEditor; } @PostConstruct public void init() { // Initialize the generic data set editor view. super.init(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ValueBoxEditor generatorClass() { return attributesEditor.generatorClass(); } @Override public MapEditor paramaterMap() { return attributesEditor.paramaterMap(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/ColumnListEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.editor.client.EditorError; import com.google.gwt.editor.client.adapters.EditorSource; import com.google.gwt.editor.client.adapters.ListEditor; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.dataset.editor.driver.DataColumnDefDriver; import org.dashbuilder.client.widgets.dataset.event.ColumnsChangedEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.editor.DataColumnDefEditor; import org.dashbuilder.dataset.def.DataColumnDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import java.util.LinkedList; import java.util.List; /** *

    Data Set column list editor presenter.

    * * @since 0.4.0 */ @Dependent public class ColumnListEditor implements IsWidget, org.dashbuilder.dataset.client.editor.ColumnListEditor { public interface View extends UberView { View insert(int index, org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor.View columnEditorView, boolean selected, boolean enabled, String altText); View remove(int index); View clear(); } SyncBeanManager beanManager; DataColumnDefDriver dataColumnDefDriver; Event columnsChangedEvent; public View view; ListEditor listEditor; List acceptableColumns; final List restrictedColumns = new LinkedList(); DataSetProviderType providerType; @Inject public ColumnListEditor(final SyncBeanManager beanManager, final DataColumnDefDriver dataColumnDefDriver, final Event columnsChangedEvent, final View view) { this.beanManager = beanManager; this.dataColumnDefDriver = dataColumnDefDriver; this.columnsChangedEvent = columnsChangedEvent; this.view = view; } @PostConstruct public void init() { listEditor = ListEditor.of(createDataColumnDefEditorSource()); view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } /** * Set all data set available columns (not only the current used ones) * * @param acceptableValues Acceptable values for the editor. */ @Override public void setAcceptableValues(final List acceptableValues) { clear(); // Register column editor for each available column of the data set. this.acceptableColumns = new LinkedList(acceptableValues); int index = 0; for (final DataColumnDef columnDef : this.acceptableColumns ) { org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor editor = createDummyColumnEditor(columnDef); view.insert(index, editor.view, false, true, null); index++; } } /** * Set the column that cannot be removed from the list, as it's used by the filter. * @param value The column id. */ @Override public void onValueRestricted(final String value) { this.restrictedColumns.add(value); setEditorEnabled(value, false, DataSetEditorConstants.INSTANCE.columnIsUsedInFilter()); } /** * Set the column that can be removed again from the list, as it's no longer used by the filter. * @param value The column id. */ @Override public void onValueUnRestricted(final String value) { this.restrictedColumns.remove(value); // Check single column used in data set -> it cannot be unselected. if (listEditor.getList().size() == 1) { setEditorEnabled(0 ,false, DataSetEditorConstants.INSTANCE.dataSetMustHaveAtLeastOneColumn()); } else { setEditorEnabled(value, true, null); } } @Override public void setProviderType(final DataSetProviderType type) { this.providerType = type; } public void clear() { acceptableColumns = null; providerType = null; view.clear(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public DataColumnDefEditor createEditorForTraversal() { return listEditor.createEditorForTraversal(); } @Override public String getPathElement(final DataColumnDefEditor subEditor) { return listEditor.getPathElement(subEditor); } @Override public void setEditorChain(final EditorChain chain) { listEditor.setEditorChain(chain); } @Override public void setDelegate(final EditorDelegate> delegate) { listEditor.setDelegate(delegate); } @Override public void showErrors(final List errors) { } @Override public void flush() { listEditor.flush(); } @Override public void onPropertyChange(final String... paths) { listEditor.onPropertyChange(paths); } @Override public void setValue(final List value) { listEditor.setValue(value); } /************************************************************* ** VIEW CALLBACK METHODS ** *************************************************************/ void onColumnSelect(final int index, final boolean selected) { final DataColumnDef columnDef = acceptableColumns.get(index); if (selected) { listEditor.getList().add(columnDef.clone()); } else { listEditor.getList().remove(columnDef); } columnsChangedEvent.fire(new ColumnsChangedEvent(this, listEditor.getList())); } /************************************************************* ** PRIVATE EDITOR METHODS ** *************************************************************/ private void replace(final int index, final org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor columnEditor, final boolean selected, final boolean enabled, final String altText) { view.remove(index); columnEditor.isEditMode(selected && enabled); view.insert(index, columnEditor.view, selected, enabled, altText); } private int getAvailableColumnIndex(final String id) { int x = 0; for (final DataColumnDef column : acceptableColumns) { if (column.getId().equals(id)) return x; x++; } return -1; } DataColumnDefEditorSource createDataColumnDefEditorSource() { return new DataColumnDefEditorSource(); } class DataColumnDefEditorSource extends EditorSource { @Override public DataColumnDefEditor create(final int index) { final DataColumnDef column = listEditor.getList().get(index); final int localIndex = acceptableColumns.indexOf(column); // Check single column used in data set -> it cannot be unselected. if (!checkSingleColumnEditorDisabled()) { // Enable column selection if more than one column remains on the data set. checkMultipleColumnsEditorEnabled(); } // Create the new editor. final org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor editor = createColumnEditor(); final boolean hasSingleColumn = listEditor.getList().size() == 1; final boolean isRestricted = restrictedColumns.contains(column.getId()); final String tooltipText = hasSingleColumn ? DataSetEditorConstants.INSTANCE.dataSetMustHaveAtLeastOneColumn() : ( isRestricted ? DataSetEditorConstants.INSTANCE.columnIsUsedInFilter() : null ); doSetOriginalColumnType(column.getId(), editor); replace(localIndex, editor, true, !isRestricted && !hasSingleColumn, tooltipText); return editor; } @Override public void dispose(DataColumnDefEditor subEditor) { // Column to be removed. final String columnId = subEditor.id().getValue(); final int localIndex = getAvailableColumnIndex(columnId); if (localIndex > -1) { final DataColumnDef column = acceptableColumns.get(localIndex); // Dispose and remove sub-editor. super.dispose(subEditor); subEditor.removeFromParent(); // Create a new dummy editor for the available column. final org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor editor = createDummyColumnEditor(column); replace(localIndex, editor, false, true, null); // Disable column selection if only one column remains on the data set. checkSingleColumnEditorDisabled(); } } }; /** * Checks that if only single column used in data set -> it cannot be unselected. */ private boolean checkSingleColumnEditorDisabled() { final int size = listEditor.getList().size(); final boolean hasEditors = !listEditor.getEditors().isEmpty(); if (size == 1 && hasEditors) { setEditorEnabled(0 ,false, DataSetEditorConstants.INSTANCE.dataSetMustHaveAtLeastOneColumn()); return true; } return false; } /** * Checks that if multiple columns are used in data set -> the column editors must be enabed, if the columns are not are restricted. */ private boolean checkMultipleColumnsEditorEnabled() { final int size = listEditor.getList().size(); if (size == 2 && !listEditor.getEditors().isEmpty()) { final String cId = listEditor.getEditors().get(0).id().getValue(); if (!restrictedColumns.contains(cId)) { setEditorEnabled(0, true, null); } return true; } return false; } private void setEditorEnabled(final String columnId, final boolean enabled, final String altText) { final org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor e = getEditor(columnId); if (e != null) { setEditorEnabled(e, enabled, altText); } } private void setEditorEnabled(final int index, final boolean enabled, final String altText) { final org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor _e = (org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor) listEditor.getEditors().get(index); if (_e != null) { setEditorEnabled(_e, enabled, altText); } } private void setEditorEnabled(org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor _e, final boolean enabled, final String altText) { final String cId = _e.id().getValue(); final int _index = getAvailableColumnIndex(cId); if (_index > -1) { replace(_index, _e, true, enabled, altText); } } private void doSetOriginalColumnType(final String cId, final DataColumnDefEditor editor) { final int _index = getAvailableColumnIndex(cId); final DataColumnDef originalCol = acceptableColumns.get(_index); if (originalCol != null) { editor.setOriginalColumnType(originalCol.getColumnType()); } } private org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor getEditor(final String columnId) { List editors = listEditor.getEditors(); if (editors != null && !editors.isEmpty()) { for (final DataColumnDefEditor editor : editors) { final String cId = editor.id().getValue(); if (columnId.equals(cId)) return (org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor) editor; } } return null; } private org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor createColumnEditor() { org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor e = beanManager.lookupBean(org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor.class).newInstance(); e.setProviderType(providerType); return e; } private org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor createDummyColumnEditor(final DataColumnDef def) { final org.dashbuilder.client.widgets.dataset.editor.column.DataColumnDefEditor editor = createColumnEditor(); // Column is available but not selected, do not allow edition. editor.isEditMode(false); // Initialze edtiro with the column attributes. dataColumnDefDriver.initialize(editor); dataColumnDefDriver.edit(def); doSetOriginalColumnType(def.getId(), editor); return editor; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/ColumnListEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.CheckBox; import org.gwtbootstrap3.client.ui.Row; import javax.enterprise.context.Dependent; /** *

    Data Set column list editor view.

    * * @since 0.4.0 */ @Dependent public class ColumnListEditorView extends Composite implements ColumnListEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } ColumnListEditor presenter; @UiField FlowPanel container; @UiConstructor public ColumnListEditorView() { initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public void init(final ColumnListEditor presenter) { this.presenter = presenter; } @Override public ColumnListEditor.View insert(final int index, final DataColumnDefEditor.View columnEditorView, final boolean selected, final boolean enabled, final String altText) { final CheckBox selectedInput = new CheckBox(); selectedInput.getElement().getStyle().setCursor(Style.Cursor.POINTER); selectedInput.getElement().getStyle().setTop(-7, Style.Unit.PX); selectedInput.setEnabled(enabled); selectedInput.setValue(selected); selectedInput.setTitle(altText != null ? altText : ""); selectedInput.addValueChangeHandler(new ValueChangeHandler() { @Override public void onValueChange(final ValueChangeEvent event) { presenter.onColumnSelect(index, event.getValue()); } }); final HorizontalPanel panel = new HorizontalPanel(); panel.setWidth("100%"); panel.add(selectedInput); panel.add(columnEditorView.asWidget()); container.insert(panel, index); return this; } @Override public ColumnListEditor.View remove(final int index) { container.remove(index); return this; } @Override public ColumnListEditor.View clear() { container.clear(); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/ColumnListEditorView.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/ColumnTypeEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.list.DropDownImageListEditor; import org.dashbuilder.common.client.editor.list.ImageListEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.client.resources.bundles.DataSetClientResources; import org.dashbuilder.dataset.def.DataColumnDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.kie.soup.commons.validation.PortablePreconditions; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import java.util.ArrayList; import java.util.Collection; /** *

    Data Set column type editor presenter.

    * * @since 0.4.0 */ @Dependent public class ColumnTypeEditor implements IsWidget, org.dashbuilder.dataset.client.editor.ColumnTypeEditor { DropDownImageListEditor columnType; ColumnType originalColumnType; @Inject public ColumnTypeEditor(final DropDownImageListEditor columnType) { this.columnType = columnType; } @PostConstruct public void init() { final Collection.Entry> entries = getDefaultEntries(); columnType.setImageSize("16px", "16px"); columnType.setEntries(entries); } @Override public Widget asWidget() { return columnType.asWidget(); } public void addHelpContent(final String title, final String content, final Placement placement) { columnType.setHelpContent(title, content, placement); } @Override public void setOriginalColumnType(final ColumnType columnType) { this.originalColumnType = columnType; final Collection.Entry> acceptableEntries = getAcceptableEntries(columnType); this.columnType.setEntries(acceptableEntries); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public DropDownImageListEditor columnType() { return columnType; } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final DataColumnDef value) { final ColumnType ct = originalColumnType != null ? originalColumnType : (value != null ? value.getColumnType() : null); String columnTypeDescr = getColumnTypeDescription(ct); final Collection.Entry> acceptableEntries = getAcceptableEntries(ct); columnType.setEntries(acceptableEntries); columnType.setHelpContent(DataSetEditorConstants.INSTANCE.attributeColumnType(), columnTypeDescr, Placement.RIGHT); } @Override public void setDelegate(final EditorDelegate delegate) { } /** * Acceptable column types to be changed from: * LABEL -> TEXT * NUMBER -> LABEL */ private Collection.Entry> getAcceptableEntries(final ColumnType type) { final Collection.Entry> result = new ArrayList.Entry>(); if (type != null) { if (ColumnType.DATE.equals(type)) { result.add(buildEntry(ColumnType.DATE)); } else if (ColumnType.LABEL.equals(type)) { result.add(buildEntry(ColumnType.LABEL)); result.add(buildEntry(ColumnType.TEXT)); } else if (ColumnType.TEXT.equals(type)) { result.add(buildEntry(ColumnType.LABEL)); result.add(buildEntry(ColumnType.TEXT)); } else if (ColumnType.NUMBER.equals(type)) { result.add(buildEntry(ColumnType.LABEL)); result.add(buildEntry(ColumnType.NUMBER)); } } return result; } protected Collection.Entry> getDefaultEntries() { final ColumnType[] providerTypes = ColumnType.values(); final Collection.Entry> entries = new ArrayList.Entry>(providerTypes.length); for (final ColumnType type : providerTypes) { final ImageListEditor.Entry entry = buildEntry(type); entries.add(entry); } return entries; } private ImageListEditor.Entry buildEntry(final ColumnType type) { final String name = type.name(); final String descr = getColumnTypeDescription(type); final SafeUri uri = getImageUri(type); return columnType.newEntry(type, uri, new SafeHtmlBuilder().appendEscaped(name).toSafeHtml(), new SafeHtmlBuilder().appendEscaped(descr).toSafeHtml()); } SafeUri getImageUri(final ColumnType type) { SafeUri result = null; switch (type) { case DATE: result = DataSetClientResources.INSTANCE.images().dateIcon32().getSafeUri(); break; case NUMBER: result = DataSetClientResources.INSTANCE.images().numberIcon32V3().getSafeUri(); break; case TEXT: result = DataSetClientResources.INSTANCE.images().textIcon32().getSafeUri(); break; case LABEL: result = DataSetClientResources.INSTANCE.images().labelIcon32().getSafeUri(); break; } return result; } String getColumnTypeDescription(final ColumnType type) { switch (type) { case DATE: return DataSetEditorConstants.INSTANCE.dateColumnType_description(); case NUMBER: return DataSetEditorConstants.INSTANCE.numberColumnType_description(); case TEXT: return DataSetEditorConstants.INSTANCE.textColumnType_description(); case LABEL: return DataSetEditorConstants.INSTANCE.labelColumnType_description(); default: return null; } } @Override public void isEditMode(final boolean isEdit) { columnType.isEditMode(isEdit); } // Listen to changes in the column type void onColumnTypeChanged(@Observes ValueChangeEvent event) { PortablePreconditions.checkNotNull("ValueChangeEvent", event); if (event.getContext().equals(columnType)) { // Update the help tooltip when the column type changes String columnTypeDescr = getColumnTypeDescription(event.getValue()); columnType.setHelpContent(DataSetEditorConstants.INSTANCE.attributeColumnType(), columnTypeDescr, Placement.RIGHT); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/DataColumnDefEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; /** *

    Data Column Definition editor presenter.

    * * @since 0.4.0 */ @Dependent public class DataColumnDefEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataColumnDefEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(ValueBoxEditor.View idView, IsWidget columnTypeView); } ValueBoxEditor id; ColumnTypeEditor columnType; public View view; boolean isEditMode = true; DataSetProviderType providerType; @Inject public DataColumnDefEditor(final ValueBoxEditor id, final ColumnTypeEditor columnType, final View view) { this.id = id; this.columnType = columnType; this.view = view; } @PostConstruct public void init() { view.init(this); view.initWidgets(id.view, columnType.asWidget()); } @Override public Widget asWidget() { return view.asWidget(); } @Override public void removeFromParent() { id.asWidget().removeFromParent(); } @Override public void setProviderType(final DataSetProviderType type) { this.providerType = type; updateColumnTypeEditMode(); } @Override public void setOriginalColumnType(final ColumnType columnType) { this.columnType.setOriginalColumnType(columnType); } @Override public void isEditMode(final boolean isEdit) { this.isEditMode = isEdit; updateColumnTypeEditMode(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ValueBoxEditor id() { return id; } @Override public org.dashbuilder.dataset.client.editor.ColumnTypeEditor columnType() { return columnType; } private void updateColumnTypeEditMode() { final boolean isTypeEditable = !DataSetProviderType.BEAN.equals(providerType); columnType.isEditMode(isTypeEditable && isEditMode); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/DataColumnDefEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import javax.enterprise.context.Dependent; /** *

    Data Column Definition editor view.

    * * @since 0.4.0 */ @Dependent public class DataColumnDefEditorView extends Composite implements DataColumnDefEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } DataColumnDefEditor presenter; @UiField(provided = true) ValueBoxEditor.View idView; @UiField(provided = true) IsWidget columnTypeView; @Override public void init(final DataColumnDefEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final ValueBoxEditor.View idView, final IsWidget columnTypeView) { this.idView = idView; this.columnTypeView = columnTypeView; initWidget(Binder.BINDER.createAndBindUi(this)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/DataColumnDefEditorView.ui.xml ================================================ .columnTypePanel { margin-left: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/column/DataSetDefColumnsEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import javax.enterprise.context.Dependent; import javax.inject.Inject; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** *

    Data Set columns editor.

    *

    It's attached in the gwt editors chain to handle the allColumns flag.

    * * @since 0.4.0 */ @Dependent public class DataSetDefColumnsEditor implements IsWidget, org.dashbuilder.dataset.client.editor.DataSetDefColumnsEditor { ColumnListEditor columnListEditor; List acceptableValues; @Inject public DataSetDefColumnsEditor(final ColumnListEditor columnListEditor) { this.columnListEditor = columnListEditor; } @Override public Widget asWidget() { return columnListEditor.asWidget(); } @Override public ColumnListEditor columns() { return columnListEditor; } @Override public void setAcceptableValues(final List acceptableValues) { this.acceptableValues = acceptableValues; columnListEditor.setAcceptableValues(acceptableValues); } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final DataSetDef value) { checkAvailableColumns(); /* This editor and sub-editors do not take care about 'allColumnsEnable' flag. If all column flag is enabled, just add all the available column into the data set definition. */ if (value != null && value.isAllColumnsEnabled()) { final List columns = new ArrayList(acceptableValues.size()); for (final DataColumnDef columnDef : acceptableValues) { columns.add(columnDef.clone()); } value.setColumns(columns); value.setAllColumnsEnabled(false); } // Columns edition depends on the data set provider type. columnListEditor.setProviderType( value != null ? value.getProvider() : null); } @Override public void setDelegate(final EditorDelegate delegate) { } private void checkAvailableColumns() { if (acceptableValues == null) { throw new IllegalArgumentException("Must call setAcceptableValues() before setting the data set definition columns to edit."); } } @Override public void onValueRestricted(final String value) { columnListEditor.onValueRestricted(value); } @Override public void onValueUnRestricted(final String value) { columnListEditor.onValueUnRestricted(value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/csv/CSVDataSetDefAttributesEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.csv; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.file.FileUploadEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; /** *

    CSV Data Set specific attributes editor presenter.

    * * @since 0.4.0 */ @Dependent public class CSVDataSetDefAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.CSVDataSetDefAttributesEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(ValueBoxEditor.View fileURLView, IsWidget filePathView, ValueBoxEditor.View sepCharView, ValueBoxEditor.View quoteCharView, ValueBoxEditor.View escCharView, ValueBoxEditor.View datePatternView, ValueBoxEditor.View numberPatternView); void showFilePathInput(); void showFileURLInput(); } DataSetClientServices dataSetClientServices; ValueBoxEditor fileURL; FileUploadEditor filePath; ValueBoxEditor separatorChar; ValueBoxEditor quoteChar; ValueBoxEditor escapeChar; ValueBoxEditor datePattern; ValueBoxEditor numberPattern; public View view; CSVDataSetDef value; boolean isUsingFilePath = true; @Inject public CSVDataSetDefAttributesEditor(final DataSetClientServices dataSetClientServices, final ValueBoxEditor fileURL, final FileUploadEditor filePath, final ValueBoxEditor separatorChar, final ValueBoxEditor quoteChar, final ValueBoxEditor escapeChar, final ValueBoxEditor datePattern, final ValueBoxEditor numberPattern, final View view) { this.dataSetClientServices = dataSetClientServices; this.fileURL = fileURL; this.filePath = filePath; this.separatorChar = separatorChar; this.quoteChar = quoteChar; this.escapeChar = escapeChar; this.datePattern = datePattern; this.numberPattern = numberPattern; this.view = view; } @PostConstruct public void init() { // Initialize the Bean specific attributes editor view. view.init(this); view.initWidgets(fileURL.view, filePath.view, separatorChar.view, quoteChar.view, escapeChar.view, datePattern.view, numberPattern.view); fileURL.addHelpContent(DataSetEditorConstants.INSTANCE.csv_URL(), DataSetEditorConstants.INSTANCE.csv_URL_description(), Placement.BOTTOM); filePath.addHelpContent(DataSetEditorConstants.INSTANCE.csv_filePath(), DataSetEditorConstants.INSTANCE.csv_filePath_description(), Placement.BOTTOM); separatorChar.addHelpContent(DataSetEditorConstants.INSTANCE.csv_sepChar(), DataSetEditorConstants.INSTANCE.csv_sepChar_description(), Placement.BOTTOM); quoteChar.addHelpContent(DataSetEditorConstants.INSTANCE.csv_quoteChar(), DataSetEditorConstants.INSTANCE.csv_quoteChar_description(), Placement.BOTTOM); escapeChar.addHelpContent(DataSetEditorConstants.INSTANCE.csv_escapeChar(), DataSetEditorConstants.INSTANCE.csv_escapeChar_description(), Placement.BOTTOM); datePattern.addHelpContent(DataSetEditorConstants.INSTANCE.csv_datePattern(), DataSetEditorConstants.INSTANCE.csv_datePattern_description(), Placement.BOTTOM); numberPattern.addHelpContent(DataSetEditorConstants.INSTANCE.csv_numberPattern(), DataSetEditorConstants.INSTANCE.csv_numberPattern_description(), Placement.BOTTOM); // Configure file upload component. filePath.configure("csvFileUpload", new FileUploadEditor.FileUploadEditorCallback() { @Override public String getUploadFileName() { return value.getUUID() + ".csv"; } @Override public String getUploadFileUrl() { String csvPath = "default://master@dashbuilder/datasets/tmp/" + value.getUUID() + ".csv"; return dataSetClientServices.getUploadFileUrl(csvPath); } }); // By default, show the file path input. view.showFilePathInput(); } @Override public Widget asWidget() { return view.asWidget(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ValueBoxEditor fileURL() { return fileURL; } @Override public FileUploadEditor filePath() { return filePath; } @Override public ValueBoxEditor separatorChar() { return separatorChar; } @Override public ValueBoxEditor quoteChar() { return quoteChar; } @Override public ValueBoxEditor escapeChar() { return escapeChar; } @Override public ValueBoxEditor datePattern() { return datePattern; } @Override public ValueBoxEditor numberPattern() { return numberPattern; } @Override public boolean isUsingFilePath() { return isUsingFilePath; } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final CSVDataSetDef value) { this.value = value; if (value != null && value.getFileURL() != null) { useFileURL(); } else { useFilePath(); } } @Override public void setDelegate(final EditorDelegate delegate) { } /************************************************************* ** VIEW CALLBACK METHODS ** *************************************************************/ void onUseFilePathButtonClick() { useFilePath(); } void onUseFileURLButtonClick() { useFileURL(); } /************************************************************* ** PRIVATE PRESENTER METHODS ** *************************************************************/ void useFilePath() { this.isUsingFilePath = true; view.showFilePathInput(); } void useFileURL() { this.isUsingFilePath = false; view.showFileURLInput(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/csv/CSVDataSetDefAttributesEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.csv; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.Row; import javax.enterprise.context.Dependent; /** *

    The CSV Data Set attributes editor view.

    * * @since 0.4.0 */ @Dependent public class CSVDataSetDefAttributesEditorView extends Composite implements CSVDataSetDefAttributesEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } CSVDataSetDefAttributesEditor presenter; @UiField Row filePathRow; @UiField(provided = true) IsWidget filePathView; @UiField Row fileURLRow; @UiField(provided = true) ValueBoxEditor.View fileURLView; @UiField Button useFilePathButton; @UiField Button useFileURLButton; @UiField(provided = true) ValueBoxEditor.View sepCharView; @UiField(provided = true) ValueBoxEditor.View quoteCharView; @UiField(provided = true) ValueBoxEditor.View escCharView; @UiField(provided = true) ValueBoxEditor.View datePatternView; @UiField(provided = true) ValueBoxEditor.View numberPatternView; @Override public void init(final CSVDataSetDefAttributesEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final ValueBoxEditor.View fileURLView, final IsWidget filePathView, final ValueBoxEditor.View sepCharView, final ValueBoxEditor.View quoteCharView, final ValueBoxEditor.View escCharView, final ValueBoxEditor.View datePatternView, final ValueBoxEditor.View numberPatternView) { this.fileURLView = fileURLView; this.filePathView = filePathView; this.sepCharView = sepCharView; this.quoteCharView = quoteCharView; this.escCharView = escCharView; this.datePatternView = datePatternView; this.numberPatternView = numberPatternView; initWidget(Binder.BINDER.createAndBindUi(this)); useFilePathButton.addClickHandler(useFilePathButtonHandler); useFileURLButton.addClickHandler(useFileURLButtonHandler); } @Override public void showFilePathInput() { fileURLRow.setVisible(false); filePathRow.setVisible(true); } @Override public void showFileURLInput() { fileURLRow.setVisible(true); filePathRow.setVisible(false); } final ClickHandler useFilePathButtonHandler = new ClickHandler() { @Override public void onClick(final ClickEvent event) { presenter.onUseFilePathButtonClick(); } }; final ClickHandler useFileURLButtonHandler = new ClickHandler() { @Override public void onClick(final ClickEvent event) { presenter.onUseFileURLButtonClick(); } }; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/csv/CSVDataSetDefAttributesEditorView.ui.xml ================================================ .inline { margin-right: 5px; } .row { margin-bottom: 5px; } .attr { float: left; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/csv/CSVDataSetEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.csv; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.file.FileUploadEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.CSVDataSetDef; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; /** *

    CSV Data Set editor presenter.

    * * @since 0.4.0 */ @Dependent public class CSVDataSetEditor extends DataSetEditor implements org.dashbuilder.dataset.client.editor.CSVDataSetDefEditor { CSVDataSetDefAttributesEditor attributesEditor; @Inject public CSVDataSetEditor(final DataSetDefBasicAttributesEditor basicAttributesEditor, final CSVDataSetDefAttributesEditor attributesEditor, final DataSetDefColumnsFilterEditor columnsAndFilterEditor, final DataSetDefPreviewTable previewTable, final DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor, final DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor, final DataSetDefRefreshAttributesEditor refreshEditor, final DataSetClientServices clientServices, final LoadingBox loadingBox, final Event errorEvent, final Event tabChangedEvent, final View view) { super(basicAttributesEditor, attributesEditor.view, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); this.attributesEditor = attributesEditor; } @PostConstruct public void init() { // Initialize the generic data set editor view. super.init(); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public ValueBoxEditor fileURL() { return attributesEditor.fileURL(); } @Override public FileUploadEditor filePath() { return attributesEditor.filePath(); } @Override public ValueBoxEditor separatorChar() { return attributesEditor.separatorChar(); } @Override public ValueBoxEditor quoteChar() { return attributesEditor.quoteChar(); } @Override public ValueBoxEditor escapeChar() { return attributesEditor.escapeChar(); } @Override public ValueBoxEditor datePattern() { return attributesEditor.datePattern(); } @Override public ValueBoxEditor numberPattern() { return attributesEditor.numberPattern(); } public boolean isUsingFilePath() { return attributesEditor.isUsingFilePath(); } @Override public void setValue(final CSVDataSetDef value) { super.setValue(value); // As gwt editor inheritance does not work fine, try to reuse CSV attributes editor logic here. attributesEditor.setValue(value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/BeanDataSetDefAttributesDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.BeanDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.BeanDataSetDef; /** *

    Driver for BeanDataSetDefAttributesEditor.

    * * @since 0.4.0 */ public interface BeanDataSetDefAttributesDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/BeanDataSetDefDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.BeanDataSetDefEditor; import org.dashbuilder.dataset.def.BeanDataSetDef; /** *

    Driver for BeanDataSetDefEditor.

    * * @since 0.4.0 */ public interface BeanDataSetDefDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/CSVDataSetDefAttributesDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.CSVDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.CSVDataSetDef; /** *

    Driver for CSVDataSetDefAttributesEditor.

    * * @since 0.4.0 */ public interface CSVDataSetDefAttributesDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/CSVDataSetDefDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.CSVDataSetDefEditor; import org.dashbuilder.dataset.def.CSVDataSetDef; /** *

    Driver for CSVDataSetDefEditor.

    * * @since 0.4.0 */ public interface CSVDataSetDefDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/DataColumnDefDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.DataColumnDefEditor; import org.dashbuilder.dataset.def.DataColumnDef; /** *

    Driver for DataColumnDefEditor.

    * * @since 0.4.0 */ public interface DataColumnDefDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/DataSetDefBasicAttributesDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.DataSetDefBasicAttributesEditor; import org.dashbuilder.dataset.def.DataSetDef; /** *

    Driver for DataSetDefBasicAttributesEditor.

    * * @since 0.4.0 */ public interface DataSetDefBasicAttributesDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/DataSetDefProviderTypeDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.DataSetDefProviderTypeEditor; import org.dashbuilder.dataset.def.DataSetDef; /** *

    Driver for DataSetDefProviderTypeEditor.

    * * @since 0.4.0 */ public interface DataSetDefProviderTypeDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/DataSetEditorDriverFactory.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import com.google.gwt.core.client.GWT; /** *

    Factory for the different gwt editor drivers for a DataSetDef. Drivers must be created at compile time via deferred binding.

    */ @ApplicationScoped public class DataSetEditorDriverFactory { final DataSetDefProviderTypeDriver dataSetDefProviderTypeDriver = GWT.create(DataSetDefProviderTypeDriver.class); final DataSetDefBasicAttributesDriver dataSetDefBasicAttributesDriver = GWT.create(DataSetDefBasicAttributesDriver.class); final SQLDataSetDefAttributesDriver sqlDataSetDefAttributesDriver = GWT.create(SQLDataSetDefAttributesDriver.class); final BeanDataSetDefAttributesDriver beanDataSetDefAttributesDriver = GWT.create(BeanDataSetDefAttributesDriver.class); final PrometheusDataSetDefAttributesDriver prometheusSearchDataSetDefAttributesDriver = GWT.create(PrometheusDataSetDefAttributesDriver.class); final KafkaDataSetDefAttributesDriver kafkaSearchDataSetDefAttributesDriver = GWT.create(KafkaDataSetDefAttributesDriver.class); final CSVDataSetDefAttributesDriver csvDataSetDefAttributesDriver = GWT.create(CSVDataSetDefAttributesDriver.class); final SQLDataSetDefDriver sqlDataSetDefDriver = GWT.create(SQLDataSetDefDriver.class); final BeanDataSetDefDriver beanDataSetDefDriver = GWT.create(BeanDataSetDefDriver.class); final CSVDataSetDefDriver csvDataSetDefDriver = GWT.create(CSVDataSetDefDriver.class); final PrometheusDataSetDefDriver prometheusSearchDataSetDefDriver = GWT.create(PrometheusDataSetDefDriver.class); final KafkaDataSetDefDriver kafkaSearchDataSetDefDriver = GWT.create(KafkaDataSetDefDriver.class); final DataColumnDefDriver dataColumnDefDriver = GWT.create(DataColumnDefDriver.class); @Produces public DataSetDefProviderTypeDriver dataSetDefProviderTypeDriver() { return dataSetDefProviderTypeDriver; } @Produces public SQLDataSetDefDriver sqlDataSetDefDriver() { return sqlDataSetDefDriver; } @Produces public DataColumnDefDriver dataColumnDefDriver() { return dataColumnDefDriver; } @Produces public SQLDataSetDefAttributesDriver sqlDataSetDefAttributesDriver() { return sqlDataSetDefAttributesDriver; } @Produces public DataSetDefBasicAttributesDriver dataSetDefBasicAttributesDriver() { return dataSetDefBasicAttributesDriver; } @Produces public BeanDataSetDefAttributesDriver beanDataSetDefAttributesDriver() { return beanDataSetDefAttributesDriver; } @Produces public CSVDataSetDefAttributesDriver csvDataSetDefAttributesDriver() { return csvDataSetDefAttributesDriver; } @Produces public CSVDataSetDefDriver csvDataSetDefDriver() { return csvDataSetDefDriver; } @Produces public BeanDataSetDefDriver beanDataSetDefDriver() { return beanDataSetDefDriver; } @Produces public PrometheusDataSetDefAttributesDriver prometheusDataSetDefAttributesDriver() { return prometheusSearchDataSetDefAttributesDriver; } @Produces public PrometheusDataSetDefDriver prometheusDataSetDefDriver() { return prometheusSearchDataSetDefDriver; } @Produces public KafkaDataSetDefAttributesDriver kafkaDataSetDefAttributesDriver() { return kafkaSearchDataSetDefAttributesDriver; } @Produces public KafkaDataSetDefDriver kafkaDataSetDefDriver() { return kafkaSearchDataSetDefDriver; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/KafkaDataSetDefAttributesDriver.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.kafka.KafkaDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.KafkaDataSetDef; /** *

    Driver for KafkaDataSetDefAttributesEditor.

    * */ public interface KafkaDataSetDefAttributesDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/KafkaDataSetDefDriver.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.KafkaDataSetDefEditor; import org.dashbuilder.dataset.def.KafkaDataSetDef; /** *

    Driver for KafkaDataSetDefEditor.

    * */ public interface KafkaDataSetDefDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/PrometheusDataSetDefAttributesDriver.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.PrometheusDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.PrometheusDataSetDef; /** *

    Driver for PrometheusDataSetDefAttributesEditor.

    * */ public interface PrometheusDataSetDefAttributesDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/PrometheusDataSetDefDriver.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.PrometheusDataSetDefEditor; import org.dashbuilder.dataset.def.PrometheusDataSetDef; /** *

    Driver for PrometheusDataSetDefEditor.

    * */ public interface PrometheusDataSetDefDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/SQLDataSetDefAttributesDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.SQLDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; /** *

    Driver for SQLDataSetDefAttributesEditor.

    * * @since 0.4.0 */ public interface SQLDataSetDefAttributesDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/driver/SQLDataSetDefDriver.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.driver; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.dataset.client.editor.SQLDataSetDefEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; /** *

    Driver for SQLDataSetDefEditor.

    * * @since 0.4.0 */ public interface SQLDataSetDefDriver extends SimpleBeanEditorDriver { } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/kafka/KafkaDataSetDefAttributesEditor.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.kafka; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.KafkaDataSetDef; import org.dashbuilder.dataset.def.KafkaDataSetDef.MetricsTarget; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; /** *

    Kafka Data Set specific attributes editor presenter.

    * */ @Dependent public class KafkaDataSetDefAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.KafkaDataSetDefAttributesEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(ValueBoxEditor.View hostView, ValueBoxEditor.View portView, DropDownEditor.View targetView, ValueBoxEditor.View clientIdView, ValueBoxEditor.View filterView, ValueBoxEditor.View nodeIdView, ValueBoxEditor.View topicView, ValueBoxEditor.View partitionView); void brokerFields(); void consumerConstraints(); void producerConstraints(); } DataSetClientServices dataSetClientServices; ValueBoxEditor host; ValueBoxEditor port; MetricsTargetEditorAdapter target; ValueBoxEditor filter; ValueBoxEditor clientId; ValueBoxEditor nodeId; ValueBoxEditor topic; ValueBoxEditor partition; public View view; KafkaDataSetDef value; @Inject public KafkaDataSetDefAttributesEditor(final DataSetClientServices dataSetClientServices, final View view, final ValueBoxEditor host, final ValueBoxEditor port, final MetricsTargetEditorAdapter target, final ValueBoxEditor filter, final ValueBoxEditor clientId, final ValueBoxEditor nodeId, final ValueBoxEditor topic, final ValueBoxEditor partition) { this.dataSetClientServices = dataSetClientServices; this.view = view; this.host = host; this.port = port; this.target = target; this.filter = filter; this.clientId = clientId; this.nodeId = nodeId; this.topic = topic; this.partition = partition; } @PostConstruct public void init() { // Initialize the Bean specific attributes editor view. view.init(this); view.initWidgets(host.view, port.view, target.getDropDownEditor().view, filter.view, clientId.view, nodeId.view, topic.view, partition.view); host.addHelpContent(DataSetEditorConstants.INSTANCE.kafka_host(), DataSetEditorConstants.INSTANCE.kafka_host_description(), Placement.BOTTOM); port.addHelpContent(DataSetEditorConstants.INSTANCE.kafka_port(), DataSetEditorConstants.INSTANCE.kafka_port_description(), Placement.BOTTOM); target.getDropDownEditor().addHelpContent(DataSetEditorConstants.INSTANCE.kafka_target(), DataSetEditorConstants.INSTANCE.kafka_target_description(), Placement.TOP); filter.addHelpContent(DataSetEditorConstants.INSTANCE.kafka_filter(), DataSetEditorConstants.INSTANCE.kafka_filter_description(), Placement.BOTTOM); clientId.addHelpContent(DataSetEditorConstants.INSTANCE.kafka_clientId(), DataSetEditorConstants.INSTANCE.kafka_clientId_description(), Placement.BOTTOM); nodeId.addHelpContent(DataSetEditorConstants.INSTANCE.kafka_nodeId(), DataSetEditorConstants.INSTANCE.kafka_nodeId_description(), Placement.BOTTOM); topic.addHelpContent(DataSetEditorConstants.INSTANCE.kafka_topic(), DataSetEditorConstants.INSTANCE.kafka_topic_description(), Placement.BOTTOM); partition.addHelpContent(DataSetEditorConstants.INSTANCE.kafka_partition(), DataSetEditorConstants.INSTANCE.kafka_partition_description(), Placement.BOTTOM); target.getDropDownEditor().setValue(MetricsTarget.BROKER.name()); } @Override public Widget asWidget() { return view.asWidget(); } @Override public void flush() { // do nothing } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final KafkaDataSetDef value) { this.value = value; target.setValue(value.getTarget()); updateViewFields(this.value.getTarget()); } @Override public void setDelegate(final EditorDelegate delegate) { } @Override public LeafAttributeEditor host() { return host; } @Override public LeafAttributeEditor port() { return port; } @Override public LeafAttributeEditor target() { return target; } @Override public LeafAttributeEditor filter() { return filter; } @Override public LeafAttributeEditor clientId() { return clientId; } @Override public LeafAttributeEditor nodeId() { return nodeId; } @Override public LeafAttributeEditor topic() { return topic; } @Override public LeafAttributeEditor partition() { return partition; } public void onTargetChanged(@Observes ValueChangeEvent valueChangeEvent) { if (valueChangeEvent.getContext() == target.getDropDownEditor() && valueChangeEvent.getValue() != null) { MetricsTarget target = MetricsTarget.valueOf(valueChangeEvent.getValue().toString()); updateViewFields(target); } } private void updateViewFields(MetricsTarget target) { switch (target) { case BROKER: view.brokerFields(); break; case CONSUMER: view.consumerConstraints(); break; case PRODUCER: view.producerConstraints(); break; } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/kafka/KafkaDataSetDefAttributesEditorView.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.kafka; import java.util.Iterator; import java.util.function.Consumer; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NodeList; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor.View; import org.dashbuilder.common.client.editor.list.DropDownEditor; /** *

    The Prometheus Data Set attributes editor view.

    * */ @Dependent public class KafkaDataSetDefAttributesEditorView extends Composite implements KafkaDataSetDefAttributesEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } KafkaDataSetDefAttributesEditor presenter; @UiField(provided = true) ValueBoxEditor.View hostView; @UiField(provided = true) ValueBoxEditor.View portView; @UiField(provided = true) DropDownEditor.View targetView; @UiField(provided = true) ValueBoxEditor.View filterView; @UiField(provided = true) ValueBoxEditor.View clientIdView; @UiField(provided = true) ValueBoxEditor.View nodeIdView; @UiField(provided = true) ValueBoxEditor.View topicView; @UiField(provided = true) ValueBoxEditor.View partitionView; @Override public void init(final KafkaDataSetDefAttributesEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(View hostView, View portView, DropDownEditor.View targetView, View filterView, View clientIdView, View nodeIdView, View topicView, View partitionView) { this.hostView = hostView; this.portView = portView; this.targetView = targetView; this.filterView = filterView; this.clientIdView = clientIdView; this.nodeIdView = nodeIdView; this.topicView = topicView; this.partitionView = partitionView; initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public void brokerFields() { disable(clientIdView, nodeIdView, topicView, partitionView); } @Override public void consumerConstraints() { enable(clientIdView, nodeIdView, topicView, partitionView); } @Override public void producerConstraints() { disable(partitionView); enable(clientIdView, nodeIdView, topicView); } void enable(IsWidget... isWidgets) { elementOp(el -> el.removeAttribute("disabled"), isWidgets); } void disable(IsWidget... isWidgets) { elementOp(el -> el.setAttribute("disabled", "true"), isWidgets); } void elementOp(Consumer action, IsWidget... isWidgets) { for (IsWidget isWidget : isWidgets) { NodeList inputs = isWidget.asWidget().getElement().getElementsByTagName("input"); for (int i = 0; i < inputs.getLength(); i++) { action.accept(inputs.getItem(i)); } } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/kafka/KafkaDataSetDefAttributesEditorView.ui.xml ================================================ .inline { margin-right: 5px; } .row { margin-bottom: 5px; } .attr { float: left; margin-right: 5px; } .hidden { display: none; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/kafka/KafkaDataSetEditor.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.kafka; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.KafkaDataSetDefEditor; import org.dashbuilder.dataset.def.KafkaDataSetDef; import org.dashbuilder.dataset.def.KafkaDataSetDef.MetricsTarget; /** *

    Kafka Data Set editor presenter.

    * */ @Dependent public class KafkaDataSetEditor extends DataSetEditor implements KafkaDataSetDefEditor { KafkaDataSetDefAttributesEditor attributesEditor; @Inject public KafkaDataSetEditor(final DataSetDefBasicAttributesEditor basicAttributesEditor, final KafkaDataSetDefAttributesEditor attributesEditor, final DataSetDefColumnsFilterEditor columnsAndFilterEditor, final DataSetDefPreviewTable previewTable, final DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor, final DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor, final DataSetDefRefreshAttributesEditor refreshEditor, final DataSetClientServices clientServices, final LoadingBox loadingBox, final Event errorEvent, final Event tabChangedEvent, final View view) { super(basicAttributesEditor, attributesEditor.view, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); this.attributesEditor = attributesEditor; } @PostConstruct public void init() { super.init(); } @Override public void setValue(KafkaDataSetDef value) { super.setValue(value); attributesEditor.setValue(value); } @Override public LeafAttributeEditor host() { return attributesEditor.host(); } @Override public LeafAttributeEditor port() { return attributesEditor.port(); } @Override public LeafAttributeEditor target() { return attributesEditor.target(); } @Override public LeafAttributeEditor filter() { return attributesEditor.filter(); } @Override public LeafAttributeEditor clientId() { return attributesEditor.clientId(); } @Override public LeafAttributeEditor nodeId() { return attributesEditor.nodeId(); } @Override public LeafAttributeEditor topic() { return attributesEditor.topic(); } @Override public LeafAttributeEditor partition() { return attributesEditor.partition(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/kafka/MetricsTargetEditorAdapter.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.kafka; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.editor.client.EditorError; import org.dashbuilder.common.client.editor.LeafAttributeEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor.Entry; import org.dashbuilder.dataset.def.KafkaDataSetDef.MetricsTarget; /** * Adapts values from a DropDownEditor to work with MetricsTarget enum. * */ @Dependent public class MetricsTargetEditorAdapter implements LeafAttributeEditor { private DropDownEditor editor; @Inject public MetricsTargetEditorAdapter(DropDownEditor editor) { this.editor = editor; updateEntries(); } public void showErrors(List errors) { editor.showErrors(errors); } @Override public void setValue(MetricsTarget value) { editor.setValue(value.name()); } @Override public MetricsTarget getValue() { return MetricsTarget.valueOf(editor.getValue()); } public DropDownEditor getDropDownEditor() { return this.editor; } private void updateEntries() { List entries = Arrays.stream(MetricsTarget.values()) .map(e -> editor.newEntry(e.name(), e.name())) .collect(Collectors.toList()); editor.setEntries(entries); editor.setValue(MetricsTarget.BROKER.name()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/prometheus/PrometheusDataSetDefAttributesEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.prometheus; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.PrometheusDataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.client.mvp.UberView; /** *

    Prometheus Data Set specific attributes editor presenter.

    * */ @Dependent public class PrometheusDataSetDefAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.PrometheusDataSetDefAttributesEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(ValueBoxEditor.View serverUrlView, ValueBoxEditor.View queryView); } DataSetClientServices dataSetClientServices; ValueBoxEditor serverUrl; ValueBoxEditor query; public View view; PrometheusDataSetDef value; @Inject public PrometheusDataSetDefAttributesEditor(final DataSetClientServices dataSetClientServices, final ValueBoxEditor serverUrl, final ValueBoxEditor query, final View view) { this.dataSetClientServices = dataSetClientServices; this.serverUrl = serverUrl; this.query = query; this.view = view; } @PostConstruct public void init() { // Initialize the Bean specific attributes editor view. view.init(this); view.initWidgets(serverUrl.view, query.view); serverUrl.addHelpContent(DataSetEditorConstants.INSTANCE.prometheus_server_url(), DataSetEditorConstants.INSTANCE.prometheus_server_url_description(), Placement.BOTTOM); query.addHelpContent(DataSetEditorConstants.INSTANCE.prometheus_query(), DataSetEditorConstants.INSTANCE.prometheus_query_description(), Placement.BOTTOM); } @Override public Widget asWidget() { return view.asWidget(); } @Override public ValueBoxEditor serverUrl() { return this.serverUrl; } @Override public ValueBoxEditor query() { return this.query; } @Override public void flush() { // do nothing } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final PrometheusDataSetDef value) { this.value = value; } @Override public void setDelegate(final EditorDelegate delegate) { } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/prometheus/PrometheusDataSetDefAttributesEditorView.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.prometheus; import javax.enterprise.context.Dependent; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; /** *

    The Prometheus Data Set attributes editor view.

    * */ @Dependent public class PrometheusDataSetDefAttributesEditorView extends Composite implements PrometheusDataSetDefAttributesEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } PrometheusDataSetDefAttributesEditor presenter; @UiField(provided = true) ValueBoxEditor.View serverUrlView; @UiField(provided = true) ValueBoxEditor.View queryView; @Override public void init(final PrometheusDataSetDefAttributesEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final ValueBoxEditor.View serverUrlView, final ValueBoxEditor.View queryView) { this.serverUrlView = serverUrlView; this.queryView = queryView; initWidget(Binder.BINDER.createAndBindUi(this)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/prometheus/PrometheusDataSetDefAttributesEditorView.ui.xml ================================================ .inline { margin-right: 5px; } .row { margin-bottom: 5px; } .attr { float: left; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/prometheus/PrometheusDataSetEditor.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.prometheus; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.PrometheusDataSetDefEditor; import org.dashbuilder.dataset.def.PrometheusDataSetDef; /** *

    Prometheus Data Set editor presenter.

    * */ @Dependent public class PrometheusDataSetEditor extends DataSetEditor implements PrometheusDataSetDefEditor { PrometheusDataSetDefAttributesEditor attributesEditor; @Inject public PrometheusDataSetEditor(final DataSetDefBasicAttributesEditor basicAttributesEditor, final PrometheusDataSetDefAttributesEditor attributesEditor, final DataSetDefColumnsFilterEditor columnsAndFilterEditor, final DataSetDefPreviewTable previewTable, final DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor, final DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor, final DataSetDefRefreshAttributesEditor refreshEditor, final DataSetClientServices clientServices, final LoadingBox loadingBox, final Event errorEvent, final Event tabChangedEvent, final View view) { super(basicAttributesEditor, attributesEditor.view, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); this.attributesEditor = attributesEditor; } @PostConstruct public void init() { super.init(); } @Override public ValueBoxEditor serverUrl() { return attributesEditor.serverUrl(); } @Override public ValueBoxEditor query() { return attributesEditor.query(); } @Override public void setValue(PrometheusDataSetDef value) { super.setValue(value); attributesEditor.setValue(value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/sql/SQLDataSetDefAttributesEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.sql; import java.util.List; import java.util.stream.Collectors; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.def.SQLDataSourceDef; import org.dashbuilder.dataset.service.SQLProviderServices; import org.gwtbootstrap3.client.ui.constants.Placement; import org.jboss.errai.common.client.api.Caller; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; /** *

    SQL Data Set specific attributes editor presenter.

    * * @since 0.4.0 */ @Dependent public class SQLDataSetDefAttributesEditor implements IsWidget, org.dashbuilder.dataset.client.editor.SQLDataSetDefAttributesEditor { public interface View extends UberView { /** *

    Specify the views to use for each sub-editor before calling initWidget.

    */ void initWidgets(DropDownEditor.View dataSource, ValueBoxEditor.View dbSchema, ValueBoxEditor.View dbTable, ValueBoxEditor.View dbSQL); /** *

    Enables edition for sql attribute dbTable

    */ void table(); /** *

    Enables edition for sql attribute dbSQL

    */ void query(); } Caller sqlProviderServices; DropDownEditor dataSource; ValueBoxEditor dbSchema; ValueBoxEditor dbTable; ValueBoxEditor dbSQL; public View view; private boolean isQuery; @Inject public SQLDataSetDefAttributesEditor(final DropDownEditor dataSource, final ValueBoxEditor dbSchema, final ValueBoxEditor dbTable, final ValueBoxEditor dbSQL, final Caller sqlProviderServices, final View view) { this.dataSource = dataSource; this.dbSchema = dbSchema; this.dbTable = dbTable; this.dbSQL = dbSQL; this.sqlProviderServices = sqlProviderServices; this.view = view; } @PostConstruct public void init() { // Initialize the SQL specific attributes editor view. view.init(this); view.initWidgets(dataSource.view, dbSchema.view, dbTable.view, dbSQL.view); dataSource.setSelectHint(DataSetEditorConstants.INSTANCE.sql_datasource_selectHint()); sqlProviderServices.call((List list) -> onSqlDataSourcesLoad(list)).getDataSourceDefs(); dataSource.addHelpContent(DataSetEditorConstants.INSTANCE.sql_datasource(), DataSetEditorConstants.INSTANCE.sql_datasource_description(), Placement.RIGHT); //bottom placement would interfere with the dropdown dbSchema.addHelpContent(DataSetEditorConstants.INSTANCE.sql_schema(), DataSetEditorConstants.INSTANCE.sql_schema_description(), Placement.BOTTOM); dbTable.addHelpContent(DataSetEditorConstants.INSTANCE.sql_table(), DataSetEditorConstants.INSTANCE.sql_table_description(), Placement.BOTTOM); dbSQL.addHelpContent(DataSetEditorConstants.INSTANCE.sql_query(), DataSetEditorConstants.INSTANCE.sql_query_description(), Placement.BOTTOM); // Use query editor by default. onSelectQuery(); } private DropDownEditor.Entry toDropDownEntry(SQLDataSourceDef d) { return dataSource.newEntry(d.getName(), d.getDescription()); } private void onSqlDataSourcesLoad(List list) { List entries = list.stream().map(this::toDropDownEntry).collect(Collectors.toList()); dataSource.setEntries(entries); } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public Widget asWidget() { return view.asWidget(); } @Override public DropDownEditor dataSource() { return dataSource; } @Override public ValueBoxEditor dbSchema() { return dbSchema; } @Override public ValueBoxEditor dbTable() { return dbTable; } @Override public ValueBoxEditor dbSQL() { return dbSQL; } @Override public void flush() { } @Override public void onPropertyChange(final String... paths) { } @Override public void setValue(final SQLDataSetDef value) { if (value != null && value.getDbTable() != null) { onSelectTable(); } else { onSelectQuery(); } } @Override public void setDelegate(final EditorDelegate delegate) { // No delegation required. } public boolean isUsingQuery() { return this.isQuery; } void onSelectTable() { view.table(); isQuery = false; } void onSelectQuery() { view.query(); isQuery = true; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/sql/SQLDataSetDefAttributesEditorView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.sql; import com.google.gwt.core.client.GWT; import com.google.gwt.editor.client.Editor; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.gwtbootstrap3.client.ui.RadioButton; import javax.enterprise.context.Dependent; /** *

    The SQL Data Set attributes editor view.

    * * @since 0.4.0 */ @Dependent public class SQLDataSetDefAttributesEditorView extends Composite implements SQLDataSetDefAttributesEditor.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } SQLDataSetDefAttributesEditor presenter; @UiField(provided = true) DropDownEditor.View dataSource; @UiField(provided = true) ValueBoxEditor.View dbSchema; @UiField @Editor.Ignore RadioButton tableButton; @UiField @Editor.Ignore RadioButton queryButton; @UiField FlowPanel dbTablePanel; @UiField(provided = true) ValueBoxEditor.View dbTable; @UiField FlowPanel dbSQLPanel; @UiField(provided = true) ValueBoxEditor.View dbSQL; @Override public void init(final SQLDataSetDefAttributesEditor presenter) { this.presenter = presenter; } @Override public void initWidgets(final DropDownEditor.View dataSource, final ValueBoxEditor.View dbSchema, final ValueBoxEditor.View dbTable, final ValueBoxEditor.View dbSQL) { this.dataSource = dataSource; this.dbSchema = dbSchema; this.dbTable = dbTable; this.dbSQL = dbSQL; initWidget(Binder.BINDER.createAndBindUi(this)); } public void table() { dbTablePanel.setVisible(true); dbSQLPanel.setVisible(false); tableButton.setValue(true); queryButton.setValue(false); } public void query() { dbTablePanel.setVisible(false); dbSQLPanel.setVisible(true); tableButton.setValue(false); queryButton.setValue(true); } @UiHandler("tableButton") void handleTableRadioClick(ClickEvent e) { presenter.onSelectTable(); } @UiHandler("queryButton") void handleQueryRadioClick(ClickEvent e) { presenter.onSelectQuery(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/sql/SQLDataSetDefAttributesEditorView.ui.xml ================================================ .sourceSelectorButton { float: left; margin-right: 10px; } .queryBox { height: 200px; } .row { margin-bottom: 5px; } .attr { float: left; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/sql/SQLDataSetEditor.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.sql; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.SQLDataSetDef; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; /** *

    SQL Data Set editor presenter.

    * * @since 0.4.0 */ @Dependent public class SQLDataSetEditor extends DataSetEditor implements org.dashbuilder.dataset.client.editor.SQLDataSetDefEditor { SQLDataSetDefAttributesEditor attributesEditor; @Inject public SQLDataSetEditor(final DataSetDefBasicAttributesEditor basicAttributesEditor, final SQLDataSetDefAttributesEditor attributesEditor, final DataSetDefColumnsFilterEditor columnsAndFilterEditor, final DataSetDefPreviewTable previewTable, final DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor, final DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor, final DataSetDefRefreshAttributesEditor refreshEditor, final DataSetClientServices clientServices, final LoadingBox loadingBox, final Event errorEvent, final Event tabChangedEvent, final View view) { super(basicAttributesEditor, attributesEditor.view, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); this.attributesEditor = attributesEditor; } @PostConstruct public void init() { // Initialize the generic data set editor view. super.init(); } public SQLDataSetDefAttributesEditor getAttributesEditor() { return attributesEditor; } /************************************************************* ** GWT EDITOR CONTRACT METHODS ** *************************************************************/ @Override public DropDownEditor dataSource() { return attributesEditor.dataSource(); } @Override public ValueBoxEditor dbSchema() { return attributesEditor.dbSchema(); } @Override public ValueBoxEditor dbTable() { return attributesEditor.dbTable(); } @Override public ValueBoxEditor dbSQL() { return attributesEditor.dbSQL(); } @Override public boolean isUsingQuery() { return attributesEditor.isUsingQuery(); } @Override public void setValue(SQLDataSetDef value) { super.setValue(value); // As gwt editor inheritance does not work fine, try to reuse SQL attributes editor logic here. attributesEditor.setValue(value); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/DataSetEditorWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetEditorConstants; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.client.DataSetEditHandler; import org.dashbuilder.displayer.client.DataSetHandler; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** *

    Data Set Editor workflow presenter.

    * * @since 0.4.0 */ public abstract class DataSetEditorWorkflow implements IsWidget { public interface View extends UberView { View add(IsWidget widget); View addButton(final String text, final String content, final boolean isPrimary, final Command clickCommand); View clearButtons(); View clearView(); } /** * -------------- CDI Injections -------------- **/ protected SyncBeanManager beanManager; protected DataSetClientServices clientServices; protected DataSetValidatorProvider validatorProvider; protected Event saveRequestEvent; protected Event testDataSetEvent; protected Event cancelRequestEvent; public View view; /** * -------------- Private class members. -------------- **/ protected T dataSetDef; protected Collection> violations = new ArrayList>(); protected Command flushCommand; protected Command stepValidator; @Inject public DataSetEditorWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { this.clientServices = clientServices; this.validatorProvider = validatorProvider; this.beanManager = beanManager; this.saveRequestEvent = saveRequestEvent; this.cancelRequestEvent = cancelRequestEvent; this.testDataSetEvent = testDataSetEvent; this.view = view; } public void init() { view.init(this); } public interface TestDataSetCallback { void onSuccess(DataSet dataSet); void onError(ClientRuntimeError error); } /** *

    Test the data set connection and obtain the preview result.

    * */ public void testDataSet(final TestDataSetCallback testDataSetCallback) { checkDataSetDefNotNull(); // Reset columns and filter configuration. getDataSetDef().setAllColumnsEnabled(true); getDataSetDef().setColumns(null); getDataSetDef().setDataSetFilter(null); DataSetDef editCloneWithoutCacheSettings = getDataSetDef().clone(); editCloneWithoutCacheSettings.setCacheEnabled(false); final DataSetLookup lookup = DataSetFactory.newDataSetLookupBuilder() .dataset(dataSetDef.getUUID()) .rowOffset(0) .rowNumber(6) .buildLookup(); try { DataSetHandler editHandler = new DataSetEditHandler(clientServices, lookup, editCloneWithoutCacheSettings); editHandler.lookupDataSet(new DataSetReadyCallback() { @Override public void callback(final DataSet dataSet) { testDataSetCallback.onSuccess(dataSet); } @Override public void notFound() { testDataSetCallback.onError(new ClientRuntimeError(DataSetEditorConstants.INSTANCE.defNotFound())); } @Override public boolean onError(final ClientRuntimeError error) { testDataSetCallback.onError(error); return false; } }); } catch (final Exception e) { testDataSetCallback.onError(new ClientRuntimeError(e)); } } public DataSetEditorWorkflow flush() { if (DataSetEditorWorkflow.this.flushCommand != null) { DataSetEditorWorkflow.this.flushCommand.execute(); } return this; } public DataSetEditorWorkflow showNextButton() { view.addButton(DataSetEditorConstants.INSTANCE.next(), DataSetEditorConstants.INSTANCE.next_description(), true, saveButtonCommand); return this; } public DataSetEditorWorkflow showTestButton() { view.addButton(DataSetEditorConstants.INSTANCE.test(), DataSetEditorConstants.INSTANCE.test_description(), true, testButtonCommand); return this; } public DataSetEditorWorkflow showBackButton() { view.addButton(DataSetEditorConstants.INSTANCE.back(), DataSetEditorConstants.INSTANCE.back_description(), false, cancelButtonCommand); return this; } public DataSetEditorWorkflow clearButtons() { view.clearButtons(); return this; } public boolean hasErrors() { return !violations.isEmpty(); } public T getDataSetDef() { return this.dataSetDef; } @Override public Widget asWidget() { return view.asWidget(); } public void flush(final SimpleBeanEditorDriver driver) { checkDataSetDefNotNull(); this.violations.clear(); driver.flush(); afterFlush(); // Validations for current step. if (stepValidator != null) { stepValidator.execute(); } } protected void afterFlush() { // Override by typed sub-classes to perform specific data set definition flush constraints that depends on the editor state. } protected void dispose() { } protected void addViolations(final Iterable> _violations) { if (_violations != null) { final Iterator> it = _violations.iterator(); while (it.hasNext()) { final ConstraintViolation _v = it.next(); this.violations.add(_v); } } } public DataSetEditorWorkflow clear() { this.dataSetDef = null; this.flushCommand = null; this.stepValidator = null; violations.clear(); view.clearView(); return this; } protected void checkDataSetDefNotNull() { checkDataSetDefNotNull(dataSetDef); } protected void checkDataSetDefNotNull(final T def) { if (def == null) { throw new RuntimeException("Must call edit() before using the data set definition editor workflow methods."); } } protected final Command testButtonCommand = new Command() { @Override public void execute() { flush(); testDataSetEvent.fire(new TestDataSetRequestEvent(DataSetEditorWorkflow.this)); } }; protected final Command saveButtonCommand = new Command() { @Override public void execute() { flush(); saveRequestEvent.fire(new SaveRequestEvent(DataSetEditorWorkflow.this)); } }; protected final Command cancelButtonCommand = new Command() { @Override public void execute() { cancelRequestEvent.fire(new CancelRequestEvent(DataSetEditorWorkflow.this)); } }; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/DataSetEditorWorkflowFactory.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.BeanDataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.CSVDataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.DataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.DataSetProviderTypeWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.KafkaDataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.PrometheusDataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.create.SQLDataSetBasicAttributesWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.BeanDataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.CSVDataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.DataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.KafkaDataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.PrometheusDataSetEditWorkflow; import org.dashbuilder.client.widgets.dataset.editor.workflow.edit.SQLDataSetEditWorkflow; import org.dashbuilder.dataprovider.DataSetProviderType; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    Main entry point for editing or creating a data set definition instance.

    *

    It provides the workflow beans for each driver & editor.

    * * @since 0.4.0 */ @Dependent public class DataSetEditorWorkflowFactory { SyncBeanManager beanManager; DataSetProviderTypeWorkflow providerTypeWorkflow; ManagedInstance dataSetEditorPlugin; @Inject public DataSetEditorWorkflowFactory(final SyncBeanManager beanManager, final DataSetProviderTypeWorkflow providerTypeWorkflow, final ManagedInstance dataSetEditorPlugin) { this.beanManager = beanManager; this.providerTypeWorkflow = providerTypeWorkflow; this.dataSetEditorPlugin = dataSetEditorPlugin; } /** * Obtain the bean for editing a data set definition for a given type. * @param type The data set definition provider type to edit. * @return The workflow instance. */ public DataSetEditWorkflow edit(final DataSetProviderType type) { final boolean isSQL = type != null && DataSetProviderType.SQL.equals(type); final boolean isBean = type != null && DataSetProviderType.BEAN.equals(type); final boolean isCSV = type != null && DataSetProviderType.CSV.equals(type); final boolean isPrometheus = type != null && DataSetProviderType.PROMETHEUS.equals(type); final boolean isKafka = type != null && DataSetProviderType.KAFKA.equals(type); Class workflowClass = null; if (isSQL) { workflowClass = SQLDataSetEditWorkflow.class; } else if (isCSV) { workflowClass = CSVDataSetEditWorkflow.class; } else if (isBean) { workflowClass = BeanDataSetEditWorkflow.class; } else if (isPrometheus) { workflowClass = PrometheusDataSetEditWorkflow.class; } else if (isKafka) { workflowClass = KafkaDataSetEditWorkflow.class; } else if (!dataSetEditorPlugin.isUnsatisfied()) { for (DataSetEditorPlugin plugin : dataSetEditorPlugin) { if (plugin.getProviderType().equals(type)) { workflowClass = plugin.getWorkflowClass(); break; } } } return (DataSetEditWorkflow) beanManager.lookupBean( workflowClass ).newInstance(); } /** * Dispose the given workflow instance. */ public void dispose(DataSetEditorWorkflow workflow) { workflow.dispose(); beanManager.destroyBean(workflow); } /** * Obtain the bean for editing the data set definition's provider type. * @return The workflow instance. */ public DataSetProviderTypeWorkflow providerType() { return providerTypeWorkflow; } /** * Obtain the bean for creating (editing basic attributes to be able to perform a lookup) a data set definition for a given type. * @param type The data set definition provider type to edit the basic attributes. * @return The workflow instance. */ public DataSetBasicAttributesWorkflow basicAttributes(final DataSetProviderType type) { final boolean isSQL = type != null && DataSetProviderType.SQL.equals(type); final boolean isBean = type != null && DataSetProviderType.BEAN.equals(type); final boolean isCSV = type != null && DataSetProviderType.CSV.equals(type); final boolean isPrometheus = type != null && DataSetProviderType.PROMETHEUS.equals(type); final boolean isKafka = type != null && DataSetProviderType.KAFKA.equals(type); Class workflowClass = null; if (isSQL) { workflowClass = SQLDataSetBasicAttributesWorkflow.class; } else if (isCSV) { workflowClass = CSVDataSetBasicAttributesWorkflow.class; } else if (isBean) { workflowClass = BeanDataSetBasicAttributesWorkflow.class; } else if (isPrometheus) { workflowClass = PrometheusDataSetBasicAttributesWorkflow.class; } else if (isKafka) { workflowClass = KafkaDataSetBasicAttributesWorkflow.class; } else if (!dataSetEditorPlugin.isUnsatisfied()) { for (DataSetEditorPlugin plugin : dataSetEditorPlugin) { if (plugin.getProviderType().equals(type)) { workflowClass = plugin.getBasicAttributesWorkflowClass(); break; } } } return (DataSetBasicAttributesWorkflow) beanManager.lookupBean( workflowClass ).newInstance(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/DataSetEditorWorkflowView.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.Column; import org.gwtbootstrap3.client.ui.Container; import org.gwtbootstrap3.client.ui.Popover; import org.gwtbootstrap3.client.ui.Tooltip; import org.gwtbootstrap3.client.ui.constants.ButtonType; import org.gwtbootstrap3.client.ui.constants.Placement; import org.uberfire.mvp.Command; import javax.enterprise.context.Dependent; /** *

    The Data Set workflow editor view.

    * * @since 0.4.0 */ @Dependent public class DataSetEditorWorkflowView extends Composite implements DataSetEditorWorkflow.View { interface Binder extends UiBinder { Binder BINDER = GWT.create(Binder.class); } @UiField Container container; @UiField Column buttonsPanel; DataSetEditorWorkflow presenter; @Override public void init(final DataSetEditorWorkflow presenter) { this.presenter = presenter; initWidget(Binder.BINDER.createAndBindUi(this)); } @Override public DataSetEditorWorkflow.View add(IsWidget widget) { container.add(widget.asWidget()); return this; } @Override public DataSetEditorWorkflow.View addButton(final String text, final String content, final boolean isPrimary, final Command clickCommand) { final Button button = new Button(text); if (isPrimary) { button.setType(ButtonType.PRIMARY); } final Tooltip tooltip = new Tooltip(button); tooltip.setTitle(content); tooltip.setContainer("body"); tooltip.setPlacement(Placement.BOTTOM); tooltip.setShowDelayMs(500); tooltip.setHideDelayMs(100); buttonsPanel.add(tooltip); button.addClickHandler(e -> { tooltip.hide(); clickCommand.execute(); }); return this; } @Override public DataSetEditorWorkflow.View clearButtons() { buttonsPanel.clear(); return this; } @Override public DataSetEditorWorkflow.View clearView() { container.clear(); clearButtons(); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/DataSetEditorWorkflowView.ui.xml ================================================ .mainPanel { font-size: 11pt; margin: 10px; } .buttonsPanel { margin-top: 10px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/BeanDataSetBasicAttributesWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.BeanDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.BeanDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    Bean Data Set Editor workflow presenter for setting data set definition basic attributes.

    * * @since 0.4.0 */ @Dependent public class BeanDataSetBasicAttributesWorkflow extends DataSetBasicAttributesWorkflow { @Inject public BeanDataSetBasicAttributesWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefBasicAttributesEditor basicAttributesEditor, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return BeanDataSetDefAttributesDriver.class; } @Override protected Class getEditorClass() { return org.dashbuilder.client.widgets.dataset.editor.bean.BeanDataSetDefAttributesEditor.class; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/CSVDataSetBasicAttributesWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.CSVDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.CSVDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    CSV Data Set Editor workflow presenter for setting data set definition basic attributes.

    * @since 0.4.0 */ @Dependent public class CSVDataSetBasicAttributesWorkflow extends DataSetBasicAttributesWorkflow { @Inject public CSVDataSetBasicAttributesWorkflow( final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefBasicAttributesEditor basicAttributesEditor, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view ) { super( clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); } @Override protected Class> getDriverClass() { return CSVDataSetDefAttributesDriver.class; } @Override protected Class getEditorClass() { return org.dashbuilder.client.widgets.dataset.editor.csv.CSVDataSetDefAttributesEditor.class; } @Override protected Iterable> validate() { return validatorProvider.validateAttributes( getDataSetDef(), editor.isUsingFilePath() ); } @Override protected void afterFlush() { super.afterFlush(); if ( !editor.isUsingFilePath() ) { dataSetDef.setFilePath( null ); } else { dataSetDef.setFileURL( null ); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/DataSetBasicAttributesWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.annotation.PostConstruct; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.DataSetDefBasicAttributesDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.mvp.Command; /** *

    Data Set Editor workflow presenter for creating a data set definition instance.

    *

    GWT editors and drivers must be type safe as they're generated during the deferred binding at compile time, so this class must be extended using concretes types for each driver & editor.

    * * @since 0.4.0 */ public abstract class DataSetBasicAttributesWorkflow> extends DataSetEditorWorkflow { DataSetDefBasicAttributesEditor basicAttributesEditor; DataSetDefBasicAttributesDriver dataSetDefBasicAttributesDriver; SimpleBeanEditorDriver driver; E editor; @Inject public DataSetBasicAttributesWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefBasicAttributesEditor basicAttributesEditor, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); this.basicAttributesEditor = basicAttributesEditor; } @PostConstruct public void init() { super.init(); } protected abstract Class> getDriverClass(); protected abstract Class getEditorClass(); protected Iterable> validate() { return validatorProvider.validateAttributes( getDataSetDef() ); } public DataSetBasicAttributesWorkflow edit(final T def) { checkDataSetDefNotNull(def); clear(); this.dataSetDef = def; return this; } public DataSetEditorWorkflow basicAttributesEdition() { checkDataSetDefNotNull(); dataSetDefBasicAttributesDriver = beanManager.lookupBean(DataSetDefBasicAttributesDriver.class).newInstance(); dataSetDefBasicAttributesDriver.initialize(basicAttributesEditor); dataSetDefBasicAttributesDriver.edit(getDataSetDef()); driver = beanManager.lookupBean( getDriverClass() ).newInstance(); editor = beanManager.lookupBean( getEditorClass() ).newInstance(); driver.initialize(editor); driver.edit(getDataSetDef()); this.flushCommand = new Command() { @Override public void execute() { flush(dataSetDefBasicAttributesDriver); flush(driver); } }; this.stepValidator = new Command() { @Override public void execute() { // Data set definition basic attributes validation. Iterable> basicAttsViolations = validatorProvider.validateBasicAttributes(getDataSetDef()); dataSetDefBasicAttributesDriver.setConstraintViolations(basicAttsViolations); addViolations(basicAttsViolations); Iterable> violations = validate(); driver.setConstraintViolations(violations); addViolations(violations); } }; // Show the view. view.clearView(); view.add(basicAttributesEditor.asWidget()); view.add(((IsWidget) editor)); return this; } /** * For unit tests use cases. */ void _setDataSetDef(final T def) { this.dataSetDef = def; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/DataSetProviderTypeWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.validation.ConstraintViolation; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefProviderTypeEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.DataSetDefProviderTypeDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.DataSetDefCreationRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.kie.soup.commons.validation.PortablePreconditions; /** *

    Data Set Editor workflow presenter for creating a data set definition instance by selecting the provider type.

    * * @since 0.4.0 */ @Dependent public class DataSetProviderTypeWorkflow extends DataSetEditorWorkflow { DataSetDefProviderTypeEditor providerTypeEditor; DataSetDefProviderTypeDriver dataSetDefProviderTypeDriver; @Inject public DataSetProviderTypeWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefProviderTypeEditor providerTypeEditor, final Event saveRequestEvent, final Event cancelRequestEvent, final Event testDataSetEvent, final View view) { super(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); this.providerTypeEditor = providerTypeEditor; } @PostConstruct public void init() { super.init(); } public DataSetProviderTypeWorkflow edit(final DataSetDef def) { checkDataSetDefNotNull(def); clear(); this.dataSetDef = def; return this; } public DataSetProviderType getProviderType() { return providerTypeEditor.provider().getValue(); } public DataSetProviderTypeWorkflow providerTypeEdition() { checkDataSetDefNotNull(); // Provider type editor driver edition. dataSetDefProviderTypeDriver = beanManager.lookupBean(DataSetDefProviderTypeDriver.class).newInstance(); dataSetDefProviderTypeDriver.initialize(providerTypeEditor); dataSetDefProviderTypeDriver.edit(getDataSetDef()); this.flushCommand = () -> { flush(dataSetDefProviderTypeDriver); }; this.stepValidator = () -> { Iterable> violations = validatorProvider.validateProviderType(getDataSetDef()); dataSetDefProviderTypeDriver.setConstraintViolations(violations); addViolations(violations); }; // Show provider type editor view. view.clearView(); view.add(providerTypeEditor.asWidget()); return this; } void onProviderTypeSelected(@Observes DataSetDefCreationRequestEvent event) { PortablePreconditions.checkNotNull("CreateDataSetDefRequestEvent", event); if (event.getContext().equals(providerTypeEditor)) { super.saveButtonCommand.execute(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/KafkaDataSetBasicAttributesWorkflow.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.KafkaDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.editor.kafka.KafkaDataSetDefAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.KafkaDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    Kafka Data Set Editor workflow presenter for setting data set definition basic attributes.

    */ @Dependent public class KafkaDataSetBasicAttributesWorkflow extends DataSetBasicAttributesWorkflow { @Inject public KafkaDataSetBasicAttributesWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefBasicAttributesEditor basicAttributesEditor, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return KafkaDataSetDefAttributesDriver.class; } @Override protected Class getEditorClass() { return KafkaDataSetDefAttributesEditor.class; } @Override protected Iterable> validate() { return validatorProvider.validateAttributes(getDataSetDef()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/PrometheusDataSetBasicAttributesWorkflow.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.PrometheusDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.PrometheusDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.PrometheusDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    Prometheus Data Set Editor workflow presenter for setting data set definition basic attributes.

    */ @Dependent public class PrometheusDataSetBasicAttributesWorkflow extends DataSetBasicAttributesWorkflow { @Inject public PrometheusDataSetBasicAttributesWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefBasicAttributesEditor basicAttributesEditor, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return PrometheusDataSetDefAttributesDriver.class; } @Override protected Class getEditorClass() { return PrometheusDataSetDefAttributesEditor.class; } @Override protected Iterable> validate() { return validatorProvider.validateAttributes(getDataSetDef()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/SQLDataSetBasicAttributesWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.SQLDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.SQLDataSetDefAttributesEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    SQL Data Set Editor workflow presenter for setting data set definition basic attributes.

    * @since 0.4.0 */ @Dependent public class SQLDataSetBasicAttributesWorkflow extends DataSetBasicAttributesWorkflow { @Inject public SQLDataSetBasicAttributesWorkflow( final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final DataSetDefBasicAttributesEditor basicAttributesEditor, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view ) { super( clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); } @Override protected Class> getDriverClass() { return SQLDataSetDefAttributesDriver.class; } @Override protected Class getEditorClass() { return org.dashbuilder.client.widgets.dataset.editor.sql.SQLDataSetDefAttributesEditor.class; } @Override protected Iterable> validate() { return validatorProvider.validateAttributes( getDataSetDef(), editor.isUsingQuery() ); } @Override protected void afterFlush() { super.afterFlush(); if ( editor.isUsingQuery() ) { dataSetDef.setDbTable( null ); } else { dataSetDef.setDbSQL( null ); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/BeanDataSetEditWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.driver.BeanDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.BeanDataSetDefEditor; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    Bean Data Set Editor workflow presenter for editing a data set definition instance.

    *

    This class is the main entry point for editing an existing data set definition instance. It links the gwt editors with the given driver to perform flushing and validations.

    * * @since 0.4.0 */ @Dependent public class BeanDataSetEditWorkflow extends DataSetEditWorkflow { @Inject public BeanDataSetEditWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return BeanDataSetDefDriver.class; } @Override protected Class getEditorClass() { return org.dashbuilder.client.widgets.dataset.editor.bean.BeanDataSetEditor.class; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/CSVDataSetEditWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.driver.CSVDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.CSVDataSetDefEditor; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    CSV Data Set Editor workflow presenter for editing a data set definition instance.

    *

    This class is the main entry point for editing an existing data set definition instance. It links the gwt editors with the given driver to perform flushing and validations.

    * * @since 0.4.0 */ @Dependent public class CSVDataSetEditWorkflow extends DataSetEditWorkflow { @Inject public CSVDataSetEditWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return CSVDataSetDefDriver.class; } @Override protected Class getEditorClass() { return org.dashbuilder.client.widgets.dataset.editor.csv.CSVDataSetEditor.class; } @Override protected Iterable> validate( boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled ) { return validatorProvider.validate( dataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, editor.isUsingFilePath() ); } @Override protected void afterFlush() { super.afterFlush(); if (!editor.isUsingFilePath()) { dataSetDef.setFilePath(null); } else { dataSetDef.setFileURL(null); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/DataSetEditWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.DataSetDefEditor; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.mvp.Command; /** *

    Data Set Editor workflow presenter for editing a data set definition instance.

    *

    GWT editors and drivers must be type safe as they're generated during the deferred binding at compile time, so this class must be extended using concretes types for each driver & editor.

    * @since 0.4.0 */ public abstract class DataSetEditWorkflow> extends DataSetEditorWorkflow { protected SimpleBeanEditorDriver driver; protected E editor; @Inject public DataSetEditWorkflow( final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view ) { super( clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); } @PostConstruct public void init() { super.init(); } protected abstract Class> getDriverClass(); protected abstract Class getEditorClass(); protected Iterable> validate( boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled ) { return validatorProvider.validate( dataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled ); } public DataSetEditWorkflow edit( final T definition, List allColumns ) { clear(); this.dataSetDef = definition; checkDataSetDefNotNull(); this.driver = beanManager.lookupBean( getDriverClass() ).newInstance(); this.editor = beanManager.lookupBean( getEditorClass() ).newInstance(); driver.initialize( editor ); editor.setAcceptableValues( allColumns ); driver.edit( definition ); this.flushCommand = () -> flush(DataSetEditWorkflow.this.driver); this.stepValidator = () -> { final boolean isCacheEnabled = definition.isCacheEnabled(); final boolean isPushEnabled = definition.isPushEnabled(); final boolean isRefreshEnabled = definition.getRefreshTime() != null; Iterable> violations = validate( isCacheEnabled, isPushEnabled, isRefreshEnabled ); driver.setConstraintViolations( violations ); addViolations( violations ); }; // Show data set editor view. view.clearView(); view.add( getWidget() ); return this; } @Override public void dispose() { if (driver != null) { beanManager.destroyBean(driver); } if (editor != null) { beanManager.destroyBean(editor); } } public E getEditor() { return editor; } @Override protected void afterFlush() { super.afterFlush(); if ( !getEditor().refreshEditor().isRefreshEnabled() ) { dataSetDef.setRefreshTime( null ); } } protected org.dashbuilder.client.widgets.dataset.editor.DataSetEditor getWidget() { return ( (org.dashbuilder.client.widgets.dataset.editor.DataSetEditor) editor ); } public DataSetEditorWorkflow showConfigurationTab() { getWidget().showConfigurationTab(); return this; } public DataSetEditorWorkflow showPreviewTab() { getWidget().showPreviewTab(); return this; } public DataSetEditorWorkflow showAdvancedTab() { getWidget().showAdvancedTab(); return this; } /** * For unit tests use cases. */ void _setDataSetDef( final T def ) { this.dataSetDef = def; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/KafkaDataSetEditWorkflow.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.driver.KafkaDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.editor.kafka.KafkaDataSetEditor; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.KafkaDataSetDefEditor; import org.dashbuilder.dataset.def.KafkaDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    Kafka Data Set Editor workflow presenter for editing a data set definition instance.

    *

    This class is the main entry point for editing an existing data set definition instance. It links the gwt editors with the given driver to perform flushing and validations.

    * */ @Dependent public class KafkaDataSetEditWorkflow extends DataSetEditWorkflow { @Inject public KafkaDataSetEditWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return KafkaDataSetDefDriver.class; } @Override protected Class getEditorClass() { return KafkaDataSetEditor.class; } @Override protected Iterable> validate(boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled) { return validatorProvider.validate(dataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/PrometheusDataSetEditWorkflow.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.driver.PrometheusDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.editor.prometheus.PrometheusDataSetEditor; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.PrometheusDataSetDefEditor; import org.dashbuilder.dataset.def.PrometheusDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    Prometheus Data Set Editor workflow presenter for editing a data set definition instance.

    *

    This class is the main entry point for editing an existing data set definition instance. It links the gwt editors with the given driver to perform flushing and validations.

    * */ @Dependent public class PrometheusDataSetEditWorkflow extends DataSetEditWorkflow { @Inject public PrometheusDataSetEditWorkflow(final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view) { super(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view); } @Override protected Class> getDriverClass() { return PrometheusDataSetDefDriver.class; } @Override protected Class getEditorClass() { return PrometheusDataSetEditor.class; } @Override protected Iterable> validate(boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled) { return validatorProvider.validate(dataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/SQLDataSetEditWorkflow.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import org.dashbuilder.client.widgets.dataset.editor.driver.SQLDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.SQLDataSetDefEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.validations.DataSetValidatorProvider; import org.jboss.errai.ioc.client.container.SyncBeanManager; /** *

    SQL Data Set Editor workflow presenter for editing a data set definition instance.

    *

    This class is the main entry point for editing an existing data set definition instance. It links the gwt editors with the given driver to perform flushing and validations.

    * @since 0.4.0 */ @Dependent public class SQLDataSetEditWorkflow extends DataSetEditWorkflow { @Inject public SQLDataSetEditWorkflow( final DataSetClientServices clientServices, final DataSetValidatorProvider validatorProvider, final SyncBeanManager beanManager, final Event saveRequestEvent, final Event testDataSetEvent, final Event cancelRequestEvent, final View view ) { super( clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); } @Override protected Class> getDriverClass() { return SQLDataSetDefDriver.class; } @Override protected Class getEditorClass() { return org.dashbuilder.client.widgets.dataset.editor.sql.SQLDataSetEditor.class; } @Override protected Iterable> validate( boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled ) { return validatorProvider.validate( dataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, editor.isUsingQuery() ); } @Override protected void afterFlush() { super.afterFlush(); if ( editor.isUsingQuery() ) { dataSetDef.setDbTable( null ); } else { dataSetDef.setDbSQL( null ); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/CancelRequestEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.event.ContextualEvent; /** *

    CDI event when a cancel operation is requested.

    * * @since 0.4.0 */ public class CancelRequestEvent extends ContextualEvent { public CancelRequestEvent(Object context) { super(context); } @Override public String toString() { return "CancelRequestEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/ColumnsChangedEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.event.ContextualEvent; import org.dashbuilder.dataset.def.DataColumnDef; import java.util.List; /** *

    CDI event when data set definition instance columns have changed.

    * * @since 0.4.0 */ public class ColumnsChangedEvent extends ContextualEvent { private List columns; public ColumnsChangedEvent(Object context, List columns) { super(context); this.columns = columns; } public List getColumns() { return columns; } @Override public String toString() { return "ColumnsChangedEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/DataSetDefCreationRequestEvent.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.event.ContextualEvent; import org.dashbuilder.dataprovider.DataSetProviderType; /** *

    CDI event fired when a data set definition creation request is requested.

    * * @since 0.6.0 */ public class DataSetDefCreationRequestEvent extends ContextualEvent { DataSetProviderType providerType; public DataSetDefCreationRequestEvent(Object context, DataSetProviderType providerType) { super(context); this.providerType = providerType; } public DataSetProviderType getProviderType() { return providerType; } @Override public String toString() { return "DataSetDefCreationRequestEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/EditDataSetEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.dataset.def.DataSetDef; import org.uberfire.workbench.events.UberFireEvent; /** *

    CDI event to request a data set definition edition.

    * * @since 0.4.0 */ public class EditDataSetEvent implements UberFireEvent { private final DataSetDef def; public EditDataSetEvent(final DataSetDef def) { this.def = def; } public DataSetDef getDef() { return def; } @Override public String toString() { return "EditDataSetEvent [UUID=" + def.getUUID() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/ErrorEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.common.client.event.ContextualEvent; /** *

    CDI event when a operation produces an error.

    * * @since 0.4.0 */ public class ErrorEvent extends ContextualEvent { private ClientRuntimeError clientRuntimeError; private String uuid; private String message; public ErrorEvent(final Object context, final ClientRuntimeError clientRuntimeError) { super(context); this.clientRuntimeError = clientRuntimeError; } public ErrorEvent(final Object context, final ClientRuntimeError clientRuntimeError, final String uuid) { this(context, clientRuntimeError); this.uuid = uuid; } public ErrorEvent(final Object context, final String message, final String uuid) { super(context); this.message = message; this.uuid = uuid; } public ErrorEvent(final Object context) { super(context); } public ClientRuntimeError getClientRuntimeError() { return clientRuntimeError; } public String getMessage() { return message; } public String getUUID() { return uuid; } @Override public String toString() { return "ErrorEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/FilterChangedEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.event.ContextualEvent; import org.dashbuilder.dataset.filter.DataSetFilter; /** *

    CDI event when data set definition's filter instance has changed.

    * * @since 0.4.0 */ public class FilterChangedEvent extends ContextualEvent { private DataSetFilter oldFilter; private DataSetFilter filter; public FilterChangedEvent(Object context, DataSetFilter oldFilter, DataSetFilter filter) { super(context); this.oldFilter = oldFilter; this.filter = filter; } public DataSetFilter getFilter() { return filter; } public DataSetFilter getOldFilter() { return oldFilter; } @Override public String toString() { return "FilterChangedEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/SaveRequestEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.event.ContextualEvent; /** *

    CDI event when a save operation is requested.

    * * @since 0.4.0 */ public class SaveRequestEvent extends ContextualEvent { public SaveRequestEvent(Object context) { super(context); } @Override public String toString() { return "SaveRequestEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/TabChangedEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.event.ContextualEvent; /** *

    CDI event when a tab is changed.

    * * @since 0.4.0 */ public class TabChangedEvent extends ContextualEvent { private String tabId; public TabChangedEvent(Object context, String tabId) { super(context); this.tabId = tabId; } public String getTabId() { return tabId; } @Override public String toString() { return "TabChangedEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/event/TestDataSetRequestEvent.java ================================================ package org.dashbuilder.client.widgets.dataset.event; import org.dashbuilder.common.client.event.ContextualEvent; /** *

    CDI event when a test data set operation is requested.

    * * @since 0.4.0 */ public class TestDataSetRequestEvent extends ContextualEvent { public TestDataSetRequestEvent(Object context) { super(context); } @Override public String toString() { return "SaveRequestEvent [Context=" + getContext().toString() + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetExplorer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.enterprise.inject.Instance; import javax.inject.Inject; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.dashbuilder.dataprovider.DataSetProviderType.*; /** *

    Data Set Explorer widget.

    * * @since 0.3.0 */ @Dependent public class DataSetExplorer implements IsWidget { public interface View extends UberView { View addPanel(final DataSetPanel.View panelView); View clear(); } List SUPPORTED_TYPES = Arrays.asList(BEAN, CSV, SQL, PROMETHEUS, KAFKA); Instance panelInstances; DataSetClientServices clientServices; View view; List panels = new LinkedList(); ManagedInstance dataSetEditorPlugin; @Inject public DataSetExplorer(final Instance panelInstances, final DataSetClientServices clientServices, final View view, final ManagedInstance dataSetEditorPlugin) { this.panelInstances = panelInstances; this.clientServices = clientServices; this.view = view; this.dataSetEditorPlugin = dataSetEditorPlugin; } @PostConstruct public void init() { if (!dataSetEditorPlugin.isUnsatisfied()) { List allTypes = new ArrayList(SUPPORTED_TYPES); for (DataSetEditorPlugin plugin : dataSetEditorPlugin) { allTypes.add(plugin.getProviderType()); } SUPPORTED_TYPES = allTypes; } view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void show() { clear(); clientServices.getPublicDataSetDefs(dataSetDefs -> { if (dataSetDefs != null && !dataSetDefs.isEmpty()) { dataSetDefs.stream() .filter(DataSetExplorer.this::isSupported) .sorted((o1, o2) -> o1.getName().compareTo(o2.getName())) .forEach(DataSetExplorer.this::addDataSetDef); } }); } private boolean isSupported(DataSetDef def) { return SUPPORTED_TYPES.contains(def.getProvider()); } private void addDataSetDef(final DataSetDef def) { // Check panel for the given data set does not exists yet and it is supported as well if (getDataSetPanel(def.getUUID()) == null) { final DataSetPanel panel = panelInstances.get(); panels.add(panel); panel.show(def, "dataSetsExplorerPanelGroup"); view.addPanel(panel.view); } } private void updateDataSetDef(final DataSetDef def) { DataSetPanel panel = getDataSetPanel(def.getUUID()); if (panel != null) { panel.show(def, "dataSetsExplorerPanelGroup"); panel.close(); } } private DataSetPanel getDataSetPanel(final String uuid) { if (uuid != null) { for (final DataSetPanel panel : panels) { if (panel.getDataSetDef().getUUID().equals(uuid)) { return panel; } } } return null; } private void clear() { panels.clear(); view.clear(); } // Be aware of data set lifecycle events void onDataSetDefRegisteredEvent(@Observes DataSetDefRegisteredEvent event) { checkNotNull("event", event); final DataSetDef def = event.getDataSetDef(); if (def != null && def.isPublic() && isSupported(def)) { // Reload the whole data set panels list. show(); } } void onDataSetDefModifiedEvent(@Observes DataSetDefModifiedEvent event) { checkNotNull("event", event); final DataSetDef def = event.getNewDataSetDef(); if (def != null && def.isPublic()) { updateDataSetDef(def); } } void onDataSetDefRemovedEvent(@Observes DataSetDefRemovedEvent event) { checkNotNull("event", event); final DataSetDef def = event.getDataSetDef(); if (def != null && def.isPublic()) { // Reload the whole data set panels list. show(); } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetExplorerView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.ui.PanelGroup; import javax.enterprise.context.Dependent; /** *

    Default view for DataSetPanel presenter.

    * * @since 0.3.0 */ @Dependent public class DataSetExplorerView extends Composite implements DataSetExplorer.View { interface DataSetExplorerViewBinder extends UiBinder {} private static DataSetExplorerViewBinder uiBinder = GWT.create(DataSetExplorerViewBinder.class); interface DataSetExplorerViewStyle extends CssResource { } @UiField DataSetExplorerViewStyle style; @UiField com.google.gwt.user.client.ui.Label emptyLabel; @UiField PanelGroup dataSetsPanelGroup; private DataSetExplorer presenter; public DataSetExplorerView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(final DataSetExplorer presenter) { this.presenter = presenter; } @Override public DataSetExplorer.View addPanel(final DataSetPanel.View panelView) { dataSetsPanelGroup.add(panelView); emptyLabel.setVisible(false); dataSetsPanelGroup.setVisible(true); return this; } @Override public DataSetExplorer.View clear() { dataSetsPanelGroup.clear(); dataSetsPanelGroup.setVisible(false); emptyLabel.setVisible(true); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetExplorerView.ui.xml ================================================ .mainPanel { width: 100%; } .errorPanel { margin: 25px; } .errorRow { margin-bottom: 10px; } .errorLabel { font-weight: bold; } .emptyLabel { padding: 10px 20px; text-align: center; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetPanel.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.client.widgets.dataset.event.EditDataSetEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetExplorerConstants; import org.dashbuilder.dataset.client.resources.bundles.DataSetClientResources; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import static org.dashbuilder.dataprovider.DataSetProviderType.*; /** *

    Data Set Panel widget with a collapsed by default summary.

    *

    It displays a panel with a header and a collape panel body.

    * * @since 0.3.0 */ @Dependent public class DataSetPanel implements IsWidget { public interface View extends UberView { View configure(final DataSetSummary.View summaryView); /** *

    Displays the summary header's.

    * @param uuid The data set unique identifier. * @param parentCollapseId The identifier of the parent collage widget to refer for data toggle features. * @param dataSetTypeImageUri The uri for the data set type image. * @param dataSetTypeImageTitle The title for the data set type image. * @param dataSetTitle The title for the data set. * @return The view instance. */ View showHeader(final String uuid, final String parentCollapseId, final SafeUri dataSetTypeImageUri, final String dataSetTypeImageTitle, final String dataSetTitle); View showSummary(); View hideSummary(); View enableActionButton(final String buttonTitle, final ClickHandler clickHandler); View disableActionButton(); } DataSetSummary dataSetSummary; Event editDataSetEvent; View view; ManagedInstance dataSetEditorPlugin; DataSetDef def; @Inject public DataSetPanel(final DataSetSummary dataSetSummary, final Event editDataSetEvent, final View view, final ManagedInstance dataSetEditorPlugin) { this.dataSetSummary = dataSetSummary; this.editDataSetEvent = editDataSetEvent; this.view = view; this.dataSetEditorPlugin = dataSetEditorPlugin; } @PostConstruct public void init() { view.init(this); view.configure(dataSetSummary.view); } @Override public Widget asWidget() { return view.asWidget(); } public void show(final DataSetDef def, final String parentPanelId) { this.def = def; if (def != null) { final String name = def.getName(); final SafeUri typeIconUri = getTypeIconUri(def); final String typeName = getTypeIconTitle(def); view.showHeader(def.getUUID(), parentPanelId, typeIconUri, typeName, name); } } public void close() { view.hideSummary(); } public void disable() { view.disableActionButton(); } public DataSetDef getDataSetDef() { return def; } void open() { dataSetSummary.show(def); view.showSummary(); view.enableActionButton(DataSetExplorerConstants.INSTANCE.edit(), new ClickHandler() { @Override public void onClick(final ClickEvent clickEvent) { editDataSetEvent.fire(new EditDataSetEvent(def)); } });; } SafeUri getTypeIconUri(final DataSetDef dataSetDef) { if (BEAN.equals(dataSetDef.getProvider())) { return DataSetClientResources.INSTANCE.images().javaIcon32().getSafeUri(); } if (CSV.equals(dataSetDef.getProvider())) { return DataSetClientResources.INSTANCE.images().csvIcon32().getSafeUri(); } if (SQL.equals(dataSetDef.getProvider())) { return DataSetClientResources.INSTANCE.images().sqlIcon32().getSafeUri(); } if (PROMETHEUS.equals(dataSetDef.getProvider())) { return DataSetClientResources.INSTANCE.images().prometheusIcon32().getSafeUri(); } if (KAFKA.equals(dataSetDef.getProvider())) { return DataSetClientResources.INSTANCE.images().kafkaIcon32().getSafeUri(); } if (!dataSetEditorPlugin.isUnsatisfied()) { for (DataSetEditorPlugin plugin : dataSetEditorPlugin) { if (plugin.getProviderType().equals(dataSetDef.getProvider())) { return plugin.getTypeSelectorImageUri(); } } } return null; } String getTypeIconTitle(final DataSetDef dataSetDef) { if (BEAN.equals(dataSetDef.getProvider())) { return DataSetExplorerConstants.INSTANCE.bean(); } if (CSV.equals(dataSetDef.getProvider())) { return DataSetExplorerConstants.INSTANCE.csv(); } if (SQL.equals(dataSetDef.getProvider())) { return DataSetExplorerConstants.INSTANCE.sql(); } if (PROMETHEUS.equals(dataSetDef.getProvider())) { return DataSetExplorerConstants.INSTANCE.prometheus(); } if (KAFKA.equals(dataSetDef.getProvider())) { return DataSetExplorerConstants.INSTANCE.kafka(); } if (!dataSetEditorPlugin.isUnsatisfied()) { for (DataSetEditorPlugin plugin : dataSetEditorPlugin) { if (plugin.getProviderType().equals(dataSetDef.getProvider())) { return plugin.getTypeSelectorTitle(); } } } return null; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetPanelView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.resources.client.CssResource; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.gwtbootstrap3.client.shared.event.ShowEvent; import org.gwtbootstrap3.client.shared.event.ShowHandler; import org.gwtbootstrap3.client.ui.*; import org.gwtbootstrap3.client.ui.constants.Toggle; import javax.enterprise.context.Dependent; /** *

    Default view for DataSetPanel presenter.

    * * @since 0.3.0 */ @Dependent public class DataSetPanelView extends Composite implements DataSetPanel.View { interface DataSetPanelViewBinder extends UiBinder {} private static DataSetPanelViewBinder uiBinder = GWT.create(DataSetPanelViewBinder.class); interface DataSetPanelViewStyle extends CssResource { } @UiField DataSetPanelViewStyle style; @UiField PanelHeader headerPanel; @UiField Image typeIcon; @UiField Heading title; @UiField PanelCollapse collapsePanel; @UiField PanelBody bodyPanel; @UiField(provided = true) DataSetSummary.View summaryView; @UiField Button actionButton; private DataSetPanel presenter; private HandlerRegistration actionButtonHandlerRegistration; public DataSetPanelView() { } @Override public void init(final DataSetPanel presenter) { this.presenter = presenter; } @Override public DataSetPanel.View configure(final DataSetSummary.View summaryView) { this.summaryView = summaryView; initWidget(uiBinder.createAndBindUi(this)); return this; } @Override public DataSetPanel.View showHeader(final String uuid, final String parentCollapseId, final SafeUri dataSetTypeImageUri, final String dataSetTypeImageTitle, final String dataSetTitle) { typeIcon.setUrl(dataSetTypeImageUri); typeIcon.setTitle(dataSetTypeImageTitle); typeIcon.setAltText(dataSetTypeImageTitle); title.setText(dataSetTitle); setDynamicToggleId(uuid, parentCollapseId); collapsePanel.addShowHandler(new ShowHandler() { @Override public void onShow(final ShowEvent shownEvent) { presenter.open(); } }); return this; } private void setDynamicToggleId(final String uuid, final String parentCollapseId) { final String tId = "collapsePanel" + uuid; collapsePanel.setId(tId); headerPanel.setDataToggle(Toggle.COLLAPSE); headerPanel.setDataTarget("#" + tId); headerPanel.setDataParent("#" + parentCollapseId); } @Override public DataSetPanel.View showSummary() { return this; } @Override public DataSetPanel.View hideSummary() { collapsePanel.setIn(false); return this; } @Override public DataSetPanel.View enableActionButton(final String buttonTitle, final ClickHandler clickHandler) { actionButton.setText(buttonTitle); actionButton.setEnabled(true); if (actionButtonHandlerRegistration != null) { actionButtonHandlerRegistration.removeHandler(); } actionButtonHandlerRegistration = actionButton.addClickHandler(clickHandler); return this; } @Override public DataSetPanel.View disableActionButton() { actionButton.setEnabled(false); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetPanelView.ui.xml ================================================ .headerPanel { cursor: pointer; } .actionButtonColumn { text-align: center; } .actionButton { margin-bottom: 10px; } .typeIcon { float: left; height: 16px; width: 16px; margin-right: 5px; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetSummary.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.resources.i18n.DataSetExplorerConstants; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetMetadataCallback; import org.dashbuilder.dataset.client.resources.bundles.DataSetClientResources; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.IconType; import org.uberfire.client.mvp.UberView; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; /** *

    Data Set Summary widget

    *

    It displays:

    *
      *
    • The current cache status
    • *
    • Current size on backend / client side
    • *
    * * @since 0.3.0 */ @Dependent public class DataSetSummary implements IsWidget { private final static String ESTIMATIONS_FORMAT = "#,###.0"; private final static String ICON_COLOR_DEFAULT = "black"; private final static String ICON_COLOR_ERROR = "red"; public interface View extends UberView { /** *

    Displays some data set feature's status in a panel.It produces the loading icon in the status panel to be removed from parent.

    * @param backendCacheStatus The status for the backend cache. If null, the widget for the status will be not displayed. * @param pushEnabled The status for the client push feature. If null, the widget for the status will be not displayed. * @param refreshStatus The status for the refresh feature. If null, the widget for the status will be not displayed. * @return The view instance. */ View showStatusPanel(final Boolean backendCacheStatus, final Boolean pushEnabled, final Boolean refreshStatus); /** *

    Displays an icon icon in the size panel such as a loading or error icon.

    * @return The view instance. */ View showSizePanelIcon(final IconType type, final String title, final String color, final boolean spin); /** *

    Displays some data set feature's sizes in a panel.

    * @param backendSizeRow The formatted size value for backend cache (in rows). * @param clientSizeKb The formatted size value for client cache (in KByes). * @return The view instance. */ View showSizePanel(final String backendSizeRow, final String clientSizeKb); } DataSetClientServices clientServices; Event errorEvent; View view; @Inject public DataSetSummary(final DataSetClientServices clientServices, final Event errorEvent, final View view) { this.clientServices = clientServices; this.errorEvent = errorEvent; this.view = view; } @PostConstruct public void init() { view.init(this); } @Override public Widget asWidget() { return view.asWidget(); } public void show(final DataSetDef def) { if (def != null) { // Cache status panel. final boolean isShowBackendCache = def.getProvider() != null && ( !DataSetProviderType.BEAN.equals(def.getProvider()) && !DataSetProviderType.CSV.equals(def.getProvider() )); final Boolean isCacheEnabled = isShowBackendCache ? def.isCacheEnabled() : null; final boolean isPushEnabled = def.isPushEnabled(); final boolean isRefreshEnabled = def.getRefreshTime() != null; view.showStatusPanel(isCacheEnabled, isPushEnabled, isRefreshEnabled); // Show loading icon on size panel while performing the backend request. showLoadingIcon(); getMetadata(def, new DataSetMetadataCallback() { @Override public void callback(final DataSetMetadata metadata) { final int estimatedSize = metadata.getEstimatedSize(); final int rowCount = metadata.getNumberOfRows(); view.showSizePanel(humanReadableRowCount(rowCount) + " " + DataSetExplorerConstants.INSTANCE.rows(), humanReadableByteCount(estimatedSize)); } @Override public void notFound() { showErrorIcon(); showError(def.getUUID(), DataSetExplorerConstants.INSTANCE.notFound()); } @Override public boolean onError(final ClientRuntimeError error) { showErrorIcon(); showError(def.getUUID(), error); return false; } }); } } String humanReadableByteCount(long bytes) { final String _b = " " + DataSetExplorerConstants.INSTANCE.bytes(); int unit = 1024; if (bytes < unit) return Long.toString(bytes) + _b; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = ("KMGTPE").charAt(exp-1) + _b; return NumberFormat.getFormat(ESTIMATIONS_FORMAT).format(bytes / Math.pow(unit, exp)) + pre; } String humanReadableRowCount(long rows) { int unit = 1000; if (rows < unit) return Long.toString(rows); int exp = (int) (Math.log(rows) / Math.log(unit)); String pre = ("KMGTPE" ).charAt(exp-1) + (""); return NumberFormat.getFormat(ESTIMATIONS_FORMAT).format(rows / Math.pow(unit, exp)) + pre; } private void getMetadata(final DataSetDef def, final DataSetMetadataCallback callback) { try { clientServices.fetchMetadata(def.getUUID(), callback); } catch (Exception e) { showError(def.getUUID(), e); } } void showLoadingIcon() { view.showSizePanelIcon(IconType.REFRESH, DataSetExplorerConstants.INSTANCE.loading(), ICON_COLOR_DEFAULT, true); } void showErrorIcon() { view.showSizePanelIcon(IconType.EXCLAMATION_TRIANGLE, DataSetExplorerConstants.INSTANCE.error(), ICON_COLOR_ERROR, false); } void showError(final String uuid, final ClientRuntimeError error) { errorEvent.fire(new ErrorEvent(DataSetSummary.this, error, uuid)); } void showError(final String uuid, final Throwable throwable) { final String msg = throwable != null ? throwable.getMessage() : DataSetExplorerConstants.INSTANCE.error(); errorEvent.fire(new ErrorEvent(DataSetSummary.this, msg, uuid)); } void showError(final String uuid, final String message) { errorEvent.fire(new ErrorEvent(DataSetSummary.this, message, uuid)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetSummaryView.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import org.dashbuilder.client.widgets.resources.i18n.DataSetExplorerConstants; import org.gwtbootstrap3.client.ui.Icon; import org.gwtbootstrap3.client.ui.Row; import org.gwtbootstrap3.client.ui.constants.IconType; import org.gwtbootstrap3.client.ui.html.Span; import javax.enterprise.context.Dependent; /** *

    Default view for DataSetSummary presenter.

    * * @since 0.3.0 */ @Dependent public class DataSetSummaryView extends Composite implements DataSetSummary.View { interface DataSetSummaryViewBinder extends UiBinder {} private static DataSetSummaryViewBinder uiBinder = GWT.create(DataSetSummaryViewBinder.class); interface DataSetSummaryViewStyle extends CssResource { } @UiField DataSetSummaryViewStyle style; @UiField Span backendStatus; @UiField Icon backendStatusIcon; @UiField Span pushStatus; @UiField Icon pushEnabledIcon; @UiField Span refreshStatus; @UiField Icon refreshEnabledIcon; @UiField Icon statusIcon; @UiField HTML estimatedSizeText; @UiField HTML estimatedRowsText; private DataSetSummary presenter; public DataSetSummaryView() { initWidget(uiBinder.createAndBindUi(this)); } @Override public void init(final DataSetSummary presenter) { this.presenter = presenter; } @Override public DataSetSummary.View showStatusPanel(final Boolean backendCacheStatus, final Boolean pushEnabled, final Boolean _refreshStatus) { if (backendCacheStatus != null) { configureStatusIcon(backendStatusIcon, backendCacheStatus); backendStatus.setVisible(true); } else { backendStatus.setVisible(false); } if (pushEnabled != null) { configureStatusIcon(pushEnabledIcon, pushEnabled); pushStatus.setVisible(true); } else { pushStatus.setVisible(false); } if (_refreshStatus != null) { configureStatusIcon(refreshEnabledIcon, _refreshStatus); refreshStatus.setVisible(true); } else { refreshStatus.setVisible(false); } return this; } private void configureStatusIcon(final Icon icon, final boolean value) { final String t = value ? DataSetExplorerConstants.INSTANCE.enabled() : DataSetExplorerConstants.INSTANCE.disabled(); icon.setType(value ? IconType.CHECK : IconType.REMOVE); icon.setTitle(t); } @Override public DataSetSummary.View showSizePanelIcon(final IconType type, final String title, final String color, final boolean spin) { statusIcon.setType(type); statusIcon.setTitle(title != null ? title : ""); statusIcon.setColor(color != null ? color : "black"); statusIcon.setSpin(spin); statusIcon.setVisible(true); return this; } @Override public DataSetSummary.View showSizePanel(final String backendSizeRow, final String clientSizeKb) { estimatedRowsText.setText(backendSizeRow); estimatedSizeText.setText(clientSizeKb); statusIcon.setVisible(false); return this; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetSummaryView.ui.xml ================================================ .panel { font-size: small; margin-top: 10px; padding: 10px; text-align: center; white-space: nowrap; } .statusTextTitle { font-size: small; font-weight: bold; white-space: nowrap; } .statusText { font-size: smaller; text-align: left; white-space: nowrap; } .statusIcon { float: left; margin-right: 5px; } .panelSpan { text-align: center; } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; import com.google.gwt.uibinder.client.UiField; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; /** *

    Data set editor constants.

    * * @since 0.3.0 */ public interface DataSetEditorConstants extends Messages { DataSetEditorConstants INSTANCE = GWT.create( DataSetEditorConstants.class ); String newDataSet(String providerType); String error(); String type(); String message(); String cause(); String ok(); String loading(); String selectType(); String bean(); String csv(); String sql(); String bean_description(); String csv_description(); String sql_description(); String next(); String next_description(); String updateTest_description(); String test(); String test_description(); String save(); String save_description(); String back(); String back_description(); String performance(); String backendCache(); String clientCache(); String none(); String refreshOnStaleData(); String refreshEvery(); String bytes(); String rows(); String attributeId(); String attributeColumnType(); String attributeColumnType_description(); String labelColumnType_description(); String textColumnType_description(); String numberColumnType_description(); String dateColumnType_description(); String attributeUUID(); String attributeUUID_description(); String attributeName(); String attributeName_description(); String attributeMaxBytes(); String attributeMaxBytes_description(); String attributeMaxRows(); String attributeMaxRows_description(); String attributeRefreshInterval(); String attributeRefreshInterval_description(); String on(); String off(); String sql_datasource(); String sql_datasource_description(); String sql_datasource_placeHolder(); String sql_datasource_selectHint(); String sql_schema(); String sql_schema_description(); String sql_schema_placeHolder(); String sql_table(); String sql_table_description(); String sql_table_placeHolder(); String sql_source(); String sql_source_description(); String sql_query(); String sql_query_description(); String sql_query_placeHolder(); String csv_filePath(); String csv_filePath_description(); String csv_URL(); String csv_URL_description(); String csv_URL_placeholder(); String csv_useFilePath(); String csv_useFileURL(); String csv_sepChar(); String csv_sepChar_description(); String csv_sepChar_placeholder(); String csv_quoteChar(); String csv_quoteChar_description(); String csv_quoteChar_placeholder(); String csv_escapeChar(); String csv_escapeChar_description(); String csv_escapeChar_placeholder(); String csv_datePattern(); String csv_datePattern_description(); String csv_datePattern_placeholder(); String csv_numberPattern(); String csv_numberPattern_description(); String csv_numberPattern_placeholder(); String bean_generator_class(); String bean_generator_class_description(); String bean_generator_class_placeholder(); String bean_generator_params(); String bean_generator_params_description(); String tab_configguration(); String tab_preview(); String tab_advancedConfiguration(); String filter(); String dataColumns(); String dataSetMustHaveAtLeastOneColumn(); String columnIsUsedInFilter(); String label(); String text(); String number(); String date(); String showColumnsAndFilter(); String hideColumnsAndFilter(); String defNotFound(); String prometheus_query(); String prometheus_query_description(); String prometheus_server_url(); String prometheus_server_url_description(); String prometheus(); String prometheus_description(); String prometheus_query_placeholder(); String prometheus_server_url_placeholder(); String kafka(); String kafka_description(); String kafka_host(); String kafka_host_description(); String kafka_host_placeholder(); String kafka_port(); String kafka_port_description(); String kafka_port_placeholder(); String kafka_target(); String kafka_target_description(); String kafka_filter(); String kafka_filter_description(); String kafka_clientId(); String kafka_clientId_description(); String kafka_nodeId(); String kafka_nodeId_description(); String kafka_topic(); String kafka_topic_description(); String kafka_partition(); String kafka_partition_description(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/java/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.ConstantsWithLookup; /** *

    Data Set Explorer constants.

    * * @since 0.3.0 */ public interface DataSetExplorerConstants extends ConstantsWithLookup { DataSetExplorerConstants INSTANCE = GWT.create( DataSetExplorerConstants.class ); String title(); String newDataSet(); String noDataSets(); String cache(); String push(); String refresh(); String edit(); String delete(); String bean(); String csv(); String sql(); String enabled(); String disabled(); String bytes(); String rows(); String currentStatus(); String currentSize(); String notFound(); String loading(); String error(); String type(); String message(); String cause(); String ok(); String prometheus(); String kafka(); } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/CommonWidgets.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants.properties ================================================ newDataSet=New {0} Data Set error=An error has occurred type=Type message=Message cause=Cause ok=Ok loading=Loading selectType=Select the provider type bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka bean_description=Bean provider allows to consume data generated by a Java class csv_description=CSV provider allows to consume data present in a CSV file sql_description=SQL provider allows to consume data present in an SQL storage system prometheus_description=Prometheus provider allows you to consume data from a Prometheus Query kafka_description=Kafka provider allows to grab metrics from Kafka broker, consumer or producer next=Next next_description=Go to provider configuration edition updateTest_description=Test your data provider configuration updated parameters by performing a data lookup to the remote system. Attention: the table on preview tab will be updated and you will lose your current columns and filter configurations, if any. test=Test test_description=Test your data provider configuration parameters by performing a data lookup to the remote system. The result of the lookup is displayed on the next screen. save=Save save_description=Save your data set and register it to make it available back=Back back_description=Go back to the type selection screen performance=Performance backendCache=Backend Cache clientCache=Client Cache none=None refreshOnStaleData=Refresh on stale data refreshEvery=Data refresh every bytes=Bytes rows=Rows attributeId=Id attributeColumnType=Column data type attributeColumnType_description=The data type for the data set column labelColumnType_description=Label columns support group operations. A group operation on a Label column generates one row per distinct value. For instance, a pie chart will display as many slices as labels available. textColumnType_description=Text columns do not support group operations (unlike Label columns). So they are usually displayed as raw data in non-categorized visualizations like table reports. numberColumnType_description=Number columns do not support group operations. However, when the dataset is grouped by a label or date column, different aggregation functions can be applied over the Number column: sum, average, min, max, etc. dateColumnType_description=Date columns support group operations. Different time intervals are supported: second, hour, day, week, month, etc. attributeUUID=UUID attributeUUID_description=Data set''s unique identifier. Useful for referencing the data set attributeName=Name attributeName_description=Data set''s name. A descriptive string that describes the data set attributeMaxBytes=Max bytes attributeMaxBytes_description=If client cache is enabled, specify the maximum size (in bytes) allows for pushing data set into client. If data set size is greater than this value, it is not pushed into client attributeMaxRows=Max rows attributeMaxRows_description=If backend cache is enabled, specify the maximum size (in rows) allowed for caching data set in memory. If data set size is greater than this value, it is not cached attributeRefreshInterval=Interval attributeRefreshInterval_description=If data set refresh is enabled, specify the interval for refreshing it. On each refresh, a look up to the external storage system is done on=ON off=OFF sql_datasource=Data Source sql_datasource_description=The connection to the database. It is always provided by the underlying container. sql_datasource_placeHolder=java:jboss/datasources/ExampleDS sql_datasource_selectHint=- Select data source - sql_schema=Schema sql_schema_description=The database schema, if necessary. Can be empty sql_schema_placeHolder=MySchema01 sql_table=Table sql_table_description=The database table to query sql_table_placeHolder=MyTable sql_source=Source sql_source_description=Either the name of an existing database table or a complete SQL sentence sql_query=Query sql_query_description=An ANSI SQL query for fetching the data set sql_query_placeHolder=select * from MyTable csv_filePath=File path csv_filePath_description=The local file system path where the CSV file is located csv_URL=File URL csv_URL_description=The URL to the CSV contents, f.i: http://myhost.com/myreports.csv csv_URL_placeholder=file:///home/dashbuilder/myReports.csv csv_useFilePath=Switch to file selector mode csv_useFileURL=Switch to remote URL mode csv_sepChar= Separator char csv_sepChar_description= The character used to separate values csv_sepChar_placeholder= Separator char (;) csv_quoteChar=Quote char csv_quoteChar_description=The character used for quotes csv_quoteChar_placeholder=Quote char (\\) csv_escapeChar=Escape char csv_escapeChar_description=The character used for escaping values csv_escapeChar_placeholder=Escape char (\\) csv_datePattern=Date pattern csv_datePattern_description=The date pattern for consuming date column values present in the CSV file csv_datePattern_placeholder=Date pattern (MM-dd-yyyy) csv_numberPattern=Number pattern csv_numberPattern_description=The number pattern for consuming number column values present in the CSV file csv_numberPattern_placeholder=Number pattern (#,###.##) bean_generator_class=Generator class bean_generator_class_description=The full qualified class name of the Java class that generates the data set. f.i: org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=Generator parameters bean_generator_params_description=A list of value pair parameters to use as generator''s class arguments tab_configguration=Configuration tab_preview=Preview tab_advancedConfiguration=Advanced filter=Filter dataColumns=Data columns dataSetMustHaveAtLeastOneColumn=Data Set must have at least one column columnIsUsedInFilter=The column is used in the filter label=Label text=Text number=Number date=Date showColumnsAndFilter=Show columns and filter panel hideColumnsAndFilter=Hide columns and filter panel defNotFound=Data Set definition not found or this data set has no definition prometheus_server_url=Server Url prometheus_server_url_description=Prometheus server URL f.i: http://localhost:9090/ prometheus_server_url_placeholder=http://localhost:9090 prometheus_query=Query prometheus_query_description=The query used to retrieve data for this dataset prometheus_query_placeholder=time() kafka_host=Host kafka_host_description=Host where Kafka Broker/Consumer/Producer is running kafka_host_placeholder=127.0.0.1 kafka_port=Port kafka_port_description=JMX Port according to Kafka JMX kafka_port_placeholder=9999 kafka_target=Target kafka_target_description=The target for metric collection. The output changes according to the selected target. kafka_filter=Filter kafka_filter_description=Filter the metrics from data set result. Filter works on domain, type and name columns. kafka_clientId=Client ID kafka_clientId_description=The Client ID. Required for Consumer/Producer metrics. kafka_nodeId=Node ID kafka_nodeId_description=Node ID that can be used with Consumer/Producer metrics kafka_topic=Topic kafka_topic_description=Topic to monitor. Should be used with Consumer/Producer metrics kafka_partition=Partition kafka_partition_description=Partition to monitor. It should be used specifically with Consumer and topic configuration. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants_de.properties ================================================ newDataSet=Neuer {0} Datensatz error=Ein Fehler ist aufgetreten. type=Typ message=Nachricht cause=Ursache ok=Ok loading=Lade selectType=Provider-Typ auswählen bean=Bean csv=CSV sql=SQL bean_description=Bean-Provider erlaubt die Verwendung von durch eine Java-Klasse generierte Daten csv_description=CSV-Provider erlaubt die Verwendung von in einer CSV-Datei vorhandenen Daten sql_description=SQL-Provider erlaubt die Verwendung von in einem SQL-Speichersystem vorhandenen Daten next=Weiter next_description=Zur Provider-Konfigurationsedition test=Test save=Speichern save_description=Speichern und registrieren Sie Ihren Datensatz, damit dieser verfügbar wird back=Zurück performance=Performance backendCache=Backend-Cache clientCache=Client-Cache none=Keine refreshOnStaleData=Veraltete Daten aktualisieren refreshEvery=Datenaktualisierung alle bytes=Bytes rows=Reihen attributeId=Id attributeColumnType=Spalten-Datentyp attributeColumnType_description=Der Datentyp für die Datensatzspalte attributeUUID=UUID attributeUUID_description=Der eindeutige Bezeichner des datensatzes. Nützlich für das Referenzieren des Datensatzes attributeName=Name attributeName_description=Name des Datensatzes. Ein deskriptiver String, der den Datensatz beschreibt attributeMaxBytes=Max. Bytes attributeMaxBytes_description=Ist das Client-Cache aktiviert, so geben Sie die maximal gestattete Größe (in Bytes) für den Push des Datensatzes in den Client an. Überschreitet der Datensatz diesen Wert, so erfolgt kein Push in den Client attributeMaxRows=Max. Reihen attributeMaxRows_description=Ist das Backend-Cache aktiviert, so geben Sie die maximal gestattete Größe (in Reihen) für das Cachen des Datensatzes im Arbeitsspeicher an. Überschreitet der Datensatz diesen Wert, so erfolgt kein Cachen attributeRefreshInterval=Intervall attributeRefreshInterval_description=Ist das Aktualisieren von Datensätzen aktiviert, so muss der Aktualisierungsintervall festgelegt werden. Bei jeder Aktualisierung erfolgt ein Lookup am externen Speichersystem on=AN off=AUS sql_datasource=Datenquelle sql_datasource_placeHolder=java\:jboss/datasources/ExampleDS sql_schema=Schema sql_schema_description=Das Datenbankschema, falls erforderlich. Kann leer sein sql_schema_placeHolder=MySchema01 sql_table=Tabelle sql_table_description=Die abzufragende Datenbanktabelle sql_table_placeHolder=MyTable sql_source=Quelle sql_query=Anfrage sql_query_description=Eine ANSI SQL-Anfrage für den Abruf des Datensatzes sql_query_placeHolder=Wählen Sie * aus MyTable aus csv_filePath=Dateipfad csv_filePath_description=Der lokale Dateisystempfad, auf dem sich die CSV-Datei befindet csv_URL=Datei-URL csv_URL_description=Die URL zu CSV-Inhalten, f.i\: http\://myhost.com/myreports.csv csv_URL_placeholder=file\:///home/dashbuilder/myReports.csv csv_useFilePath=Zum Datei-Selektor Modus wechseln csv_useFileURL=Zum Entfernte URL Modus wechseln csv_sepChar=Separator-Char csv_sepChar_description=Das zum Trennen von Werten verwendete Zeichen csv_sepChar_placeholder=Separator-Char (;) csv_quoteChar=Anführungszeichen-Char csv_quoteChar_description=Das für Anführungszeichen verwendete Zeichen csv_quoteChar_placeholder=Anführungszeichen-Char (\\) csv_escapeChar=Escape-Char csv_escapeChar_description=Das Escape-Zeichen für Werte csv_escapeChar_placeholder=Escape-Zeichen (\\) csv_datePattern=Datumsmuster csv_datePattern_description=Das Datumsmuster für die Verwendung der Datumsspaltenwerte for consuming date column values present in the CSV file csv_datePattern_placeholder=Datumsmuster (MM-tt-jjjj) csv_numberPattern=Zahlenmuster csv_numberPattern_description=Das Zahlenmuster für die Verwendung von in der CSV-Datei vorhandenen Zahlenspaltenwerten csv_numberPattern_placeholder=Zahlenmuster (\#,\#\#\#.\#\#) el_cluster_name=Cluster-Name el_cluster_name_description=Der Name des Clusters. Kann leer sein el_cluster_name_placeholder=my_cluster el_index=Index el_index_placeholder=my_index el_type=Dokument-Typ el_type_description=Der Dokumententyp zur Abfrage des gegebenen Index. Kann mehrere, kommagetrennte Werte enthalten. Falls leer, werden alle Dokumententypen des gegebenen aktuellen Index verwendet el_type_placeholder=my_type bean_generator_class=Generator-Klasse bean_generator_class_description=Der vollqualifizierte Klassenname der Java-Klasse, die den Datensatz generiert. f.i\: org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=Generator-Parameter bean_generator_params_description=Eine Liste von Wertepaarparametern zur Verwendung als Generator-Klassen-Argumente tab_configguration=Konfiguration tab_preview=Vorschau tab_advancedConfiguration=Fortgeschritten filter=Filter dataColumns=Datenspalten dataSetMustHaveAtLeastOneColumn=Datensatz muss mindestens eine Spalte haben columnIsUsedInFilter=Die Spalte wird im Filter verwendet label=Bezeichnung text=Text number=Zahl date=Datum showColumnsAndFilter=Spalten- und Filter-Panel anzeigen hideColumnsAndFilter=Spalten- und Filter-Panel ausblenden defNotFound=Datensatzdefinition nicht gefunden oder dieser Datensatz besitzt keine Definition ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants_es.properties ================================================ newDataSet=Nuevo conjunto de datos {0} error=Se produjo un error type=Tipo message=Mensaje cause=Motivo ok=Aceptar loading=Cargando selectType=Seleccione el tipo de proveedor bean=Bean csv=CSV sql=SQL prometheus=Prometeo kafka=Kafka bean_description=El proveedor Bean permite consumir los datos generados por una clase de Java csv_description=El proveedor CSV permite consumir los datos presentes en un archivo CSV sql_description=El proveedor SQL permite consumir los datos presentes en un sistema de almacenamiento SQL prometheus_description=El proveedor de Prometheus le permite consumir datos de una consulta de Prometheus kafka_description=El proveedor Kafka permite obtener métricas del broker, consumidor o productor Kafka next=Siguiente next_description=Ir a la edición de configuración de proveedores updateTest_description=Pruebe los parámetros actualizados de la configuración de su proveedor de datos realizando una búsqueda de datos en el sistema remoto. Atención: la tabla de la pestaña de vista previa se actualizará y perderá sus columnas y configuraciones de filtro actuales, si las hubiera. test=Prueba test_description=Pruebe los parámetros de configuración de su proveedor de datos realizando una búsqueda de datos en el sistema remoto. El resultado de la búsqueda se muestra en la siguiente pantalla. save=Guardar save_description=Guarde su conjunto de datos y regístrelo para que esté disponible back=Atrás back_description=Volver a la pantalla de selección de tipo performance=Desempeño backendCache=Caché back-end clientCache=Caché cliente none=Ninguno refreshOnStaleData=Actualizar al encontrar datos obsoletos refreshEvery=Los datos se actualizan cada bytes=Bytes rows=Filas attributeId=Id attributeColumnType=Tipo de datos de la columna attributeColumnType_description=El tipo de datos para la columna de conjuntos de datos labelColumnType_description=Las columnas de etiquetas respaldan las operaciones de grupo. Una operación de grupo en una columna de etiquetas genera una fila por cada valor único. Por ejemplo, un gráfico circular mostrará tantos cortes como etiquetas haya disponibles. textColumnType_description=Las columnas de texto no admiten operaciones de grupo (a diferencia de las columnas de etiquetas). Por lo tanto, normalmente se muestran como datos sin formato en visualizaciones no categorizadas como informes de tablas. numberColumnType_description=Las columnas de números no admiten las operaciones de grupo. Sin embargo, cuando el conjunto de datos se agrupa por una columna de fecha o etiqueta, se pueden aplicar diferentes funciones de agregación sobre la columna de número: suma, promedio, mínimo, máximo, etc. dateColumnType_description=Las columnas de fecha admiten las operaciones del grupo. Se admiten diferentes intervalos de tiempo: segundo, hora, día, semana, mes, etc. attributeUUID=UUID attributeUUID_description=El identificador único del conjunto de datos. Es útil para referirse al conjunto de datos attributeName=Nombre attributeName_description=El nombre del conjunto de datos. Una cadena descriptiva que describe el conjunto de datos attributeMaxBytes=Cantidad máxima de bytes attributeMaxBytes_description=Si la caché de clientes está habilitada, especifique el tamaño máximo (en bytes) permitido para la introducción del conjunto de datos en el cliente. Si el tamaño del conjunto de datos es mayor a este valor, no se introduce en el cliente attributeMaxRows=Cantidad máxima de filas attributeMaxRows_description=Si la caché del back-end está habilitada, especifique el tamaño máximo (en filas) permitido para el almacenamiento de los conjuntos de datos en la caché de la memoria . Si el tamaño del conjunto de datos es mayor a este valor, no se almacena en caché attributeRefreshInterval=Intervalo attributeRefreshInterval_description=Si la actualización del conjunto de datos está habilitada, especifique el intervalo para actualizarla. En cada actualización, se realiza una búsqueda en el sistema de almacenamiento externo on=ENCENDIDO off=APAGADO sql_datasource=Fuente de datos sql_datasource_description=La conexión a la base de datos. Siempre la proporciona el contenedor subyacente. sql_datasource_placeHolder=java:jboss/datasources/ExampleDS sql_datasource_selectHint=- Seleccionar la fuente de datos - sql_schema=Esquema sql_schema_description=El esquema de la base de datos, si es necesario. Puede estar vacío sql_schema_placeHolder=MySchema01 sql_table=Tabla sql_table_description=La tabla de la base de datos a consultar sql_table_placeHolder=MyTable sql_source=Fuente sql_source_description=El nombre de una tabla de la base de datos existente o una sentencia de SQL completa sql_query=Consulta sql_query_description=Una consulta ANSI SQL para obtener el conjunto de datos sql_query_placeHolder=seleccionar * de MyTable csv_filePath=Ruta de archivo csv_filePath_description=La ruta del sistema de archivos local donde se encuentra el archivo CSV csv_URL=URL del archivo csv_URL_description=El URL del contenido del CSV, f.i: http://myhost.com/myreports.csv csv_URL_placeholder=file:///home/dashbuilder/myReports.csv csv_useFilePath=Cambiar al modo de selección de archivos csv_useFileURL=Cambiar al modo URL remoto csv_sepChar= Carácter separador csv_sepChar_description= El carácter usado para separar los valores csv_sepChar_placeholder= Carácter separador (;) csv_quoteChar=Carácter de cita csv_quoteChar_description=El carácter usado para citar csv_quoteChar_placeholder=Carácter de cita (\) csv_escapeChar=Carácter de escape csv_escapeChar_description=El carácter usado para valores de escape csv_escapeChar_placeholder=Carácter de escape (\) csv_datePattern=Patrón de fechas csv_datePattern_description=El patrón de fechas para consumir los valores de la columna de fecha presentes en el archivo CSV csv_datePattern_placeholder=Patrón de fechas (MM-dd-aaaa) csv_numberPattern=Patrón de números csv_numberPattern_description=El patrón de números para consumir los valores de las columnas de números presentes en el archivo CSV csv_numberPattern_placeholder=Patrón de números (#,###.##) bean_generator_class=Clase de generador bean_generator_class_description=El nombre completo de la clase calificada de la clase Java que genera el conjunto de datos. f.i: org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=Parámetros del generador bean_generator_params_description=Una lista de parámetros de pares de valores para usar como argumentos de clase del generador tab_configguration=Configuración tab_preview=Vista previa tab_advancedConfiguration=Avanzado filter=Filtro dataColumns=Columnas de datos dataSetMustHaveAtLeastOneColumn=El conjunto de datos debe tener al menos una columna columnIsUsedInFilter=La columna se usa en el filtro label=Etiqueta text=Texto number=Número date=Fecha showColumnsAndFilter=Mostrar las columnas y el panel de filtro hideColumnsAndFilter=Ocultar las columnas y el panel de filtro defNotFound=No se encuentra la definición del conjunto de datos o este conjunto de datos no tiene definición prometheus_server_url=Url del servidor prometheus_server_url_description=URL del servidor Prometheus f.i: http://localhost:9090/ prometheus_server_url_placeholder=http://localhost:9090 prometheus_query=Consulta prometheus_query_description=La consulta utilizada para recuperar los datos de este conjunto de datos prometheus_query_placeholder=tiempo kafka_host=Host kafka_host_description=Host en el que se ejecuta Kafka Broker/Consumer/Producer kafka_host_placeholder=127.0.0.1 kafka_port=Puerto kafka_port_description=Puerto JMX según Kafka JMX kafka_port_placeholder=9999 kafka_target=Destino kafka_target_description=El objetivo de la recogida de métricas. La salida cambia según el objetivo seleccionado. kafka_filter=Filtro kafka_filter_description=Filtrar las métricas del resultado del conjunto de datos. El filtro funciona en las columnas de dominio, tipo y nombre. kafka_clientId=Identificación del cliente kafka_clientId_description=La identificación del cliente. Necesario para las métricas de los consumidores/productores. kafka_nodeId=ID del nodo kafka_nodeId_description=ID de nodo que puede utilizarse con las métricas de consumidor/productor kafka_topic=Tema kafka_topic_description=Tema a vigilar. Debe utilizarse con las métricas del consumidor/productor kafka_partition=Partición kafka_partition_description=Partición a vigilar. Debe utilizarse específicamente con la configuración de los consumidores y los temas. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants_fr.properties ================================================ newDataSet=Nouvel ensemble de données {0} error=Une erreur s''est produite type=Type message=Message cause=Cause ok=OK loading=Chargement selectType=Sélectionner le type de fournisseur bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka bean_description=Le fournisseur Bean permet de consommer des données générées par une classe Java csv_description=Le fournisseur CSV permet de consommer les données présentes dans un fichier CSV sql_description=Le fournisseur SQL permet de consommer les données présentes dans un système de stockage SQL prometheus_description=Le fournisseur Prometheus vous permet de consommer des données à partir d''une requête Prometheus kafka_description=Le fournisseur Kafka permet de récupérer les métriques du courtier, du consommateur ou du producteur Kafka next=Suivant next_description=Aller à l''édition de la configuration du fournisseur updateTest_description=Testez les paramètres mis à jour de la configuration de votre fournisseur de données en effectuant une recherche de données sur le système distant. Attention : le tableau de l''onglet "Aperçu" sera mis à jour, et vous perdrez les configurations de filtrage et de colonnes en cours, le cas échéant. test=Tester test_description=Testez les paramètres de configuration de votre fournisseur de données en effectuant une recherche de données sur le système distant. Le résultat de la recherche est affiché sur l''écran suivant. save=Enregistrer save_description=Enregistrez votre ensemble de données et inscrivez-le pour le rendre disponible back=Retour back_description=Revenir à l''écran de sélection du type performance=Performance backendCache=Cache du backend clientCache=Cache du client none=Aucun refreshOnStaleData=Rafraîchir les données périmées refreshEvery=Rafraîchir les données tous les bytes=Octets rows=Lignes attributeId=ID attributeColumnType=Type de données de la colonne attributeColumnType_description=Type de données de la colonne de l''ensemble de données labelColumnType_description=Les colonnes Étiquette prennent en charge les opérations de groupe. Une opération de groupe sur une colonne Étiquette génère une ligne par valeur distincte. Par exemple, un graphique en secteurs affichera autant de secteurs que d''étiquettes disponibles. textColumnType_description=Les colonnes Texte ne prennent pas en charge les opérations de groupe (contrairement aux colonnes d''étiquettes). Elles sont donc généralement affichées sous la forme de données brutes dans des visualisations non catégorisées comme des rapports de tableaux. numberColumnType_description=Les colonnes Nombre ne prennent pas en charge les opérations de groupe. Cependant, lorsque l''ensemble de données est regroupé en fonction d''une colonne de date ou d''étiquette, différentes fonctions d''agrégation peuvent être appliquées sur la colonne Nombre : somme, moyenne, min, max, etc. dateColumnType_description=Les colonnes Date prennent en charge les opérations de groupe. Différents intervalles de temps sont pris en charge : seconde, heure, jour, semaine, mois, etc. attributeUUID=UUID attributeUUID_description=Identificateur unique de l''ensemble de données. Utile pour référencer l''ensemble des données attributeName=Nom attributeName_description=Nom de l''ensemble de données. Chaîne descriptive qui décrit l''ensemble de données attributeMaxBytes=Nombre maximal d''octets attributeMaxBytes_description=Si le cache du client est activé, indiquez la taille maximale (en octets) permettant d''envoyer l''ensemble de données au client. Si la taille de l''ensemble de données est supérieure à cette valeur, il n''est pas envoyé au client attributeMaxRows=Nombre maximal de lignes attributeMaxRows_description=Si le cache du backend est activé, indiquez la taille maximale (en lignes) autorisée pour la mise en cache de l''ensemble de données en mémoire. Si la taille de l''ensemble de données est supérieure à cette valeur, il n''est pas mis en cache attributeRefreshInterval=Intervalle attributeRefreshInterval_description=Si le rafraîchissement de l''ensemble de données est activé, indiquez l''intervalle de rafraîchissement. À chaque rafraîchissement, une recherche est effectuée dans le système de stockage externe on=ACTIVÉ off=DÉSACTIVÉ sql_datasource=Source de données sql_datasource_description=Connexion à la base de données. Elle est toujours fournie par le conteneur sous-jacent. sql_datasource_placeHolder=java:jboss/datasources/ExampleDS sql_datasource_selectHint=- Sélectionner la source de données - sql_schema=Schéma sql_schema_description=Schéma de la base de données, si nécessaire. Peut être vide sql_schema_placeHolder=MySchema01 sql_table=Tableau sql_table_description=Table de base de données à interroger sql_table_placeHolder=MyTable sql_source=Source sql_source_description=Soit le nom d''une table de base de données existante, soit une phrase SQL complète sql_query=Requête sql_query_description=Requête SQL ANSI pour extraire l''ensemble de données sql_query_placeHolder=sélectionnez * dans MyTable csv_filePath=Chemin d''accès au fichier csv_filePath_description=Chemin d''accès au système de fichiers local où se trouve le fichier CSV csv_URL=URL du fichier csv_URL_description=URL du contenu CSV, par exemple : http://myhost.com/myreports.csv csv_URL_placeholder=file:///home/dashbuilder/myReports.csv csv_useFilePath=Passer en mode sélecteur de fichiers csv_useFileURL=Passer en mode URL distante csv_sepChar= Caractère de séparation csv_sepChar_description= Caractère utilisé pour séparer les valeurs csv_sepChar_placeholder= Caractère de séparation (;) csv_quoteChar=Guillemet csv_quoteChar_description=Caractère utilisé pour les guillemets csv_quoteChar_placeholder=Guillemet (\) csv_escapeChar=Caractère d''échappement csv_escapeChar_description=Le caractère utilisé pour l''échappement des valeurs csv_escapeChar_placeholder=Caractère d''échappement (\) csv_datePattern=Modèle de date csv_datePattern_description=Modèle de date utilisé pour la consommation des valeurs de colonne Date présentes dans le fichier CSV csv_datePattern_placeholder=Modèle de date (MM-jj-aaaa) csv_numberPattern=Modèle de numéro csv_numberPattern_description=Modèle de numéro utilisé pour la consommation des valeurs de colonne Nombre présentes dans le fichier CSV csv_numberPattern_placeholder=Modèle de numéro (#,###.##) bean_generator_class=Classe de générateur bean_generator_class_description=Nom de classe complet de la classe Java qui génère l''ensemble de données, par exemple : org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=Paramètres du générateur bean_generator_params_description=Liste de paramètres de paires de valeurs à utiliser comme arguments de classe du générateur tab_configguration=Configuration tab_preview=Aperçu tab_advancedConfiguration=Avancé filter=Filtrer dataColumns=Colonnes de données dataSetMustHaveAtLeastOneColumn=L''ensemble de données doit comporter au moins une colonne columnIsUsedInFilter=La colonne est utilisée dans le filtre label=Étiquette text=Texte number=Numéro date=Date showColumnsAndFilter=Afficher le panneau de filtre et les colonnes hideColumnsAndFilter=Masquer le panneau de filtre et les colonnes defNotFound=Définition de l''ensemble de données introuvable ou cet ensemble de données ne comporte aucune définition prometheus_server_url=Url du serveur prometheus_server_url_description=URL du serveur Prometheus f.i : http://localhost:9090/ prometheus_server_url_placeholder=http://localhost:9090 prometheus_query=Requête prometheus_query_description=La requête utilisée pour récupérer les données de cet ensemble de données prometheus_query_placeholder=time() kafka_host=Hôte kafka_host_description=Hôte où les Broker/Consommateur/Producteur Kafka sont exécutés kafka_host_placeholder=127.0.0.1 kafka_port=Port kafka_port_description=Port JMX selon Kafka JMX kafka_port_placeholder=9999 kafka_target=Cible kafka_target_description=La cible de la collecte de métriques. La sortie change en fonction de la cible sélectionnée. kafka_filter=Filtrer kafka_filter_description=Filtrer les métriques à partir du résultat de l''ensemble de données. Le filtre fonctionne sur les colonnes domaine, type et nom. kafka_clientId=ID du client kafka_clientId_description=L''ID du client. Requis pour les métriques Consommateur/Producteur. kafka_nodeId=ID du nœud kafka_nodeId_description=ID du nœud qui peut être utilisé avec les métriques du consommateur/producteur kafka_topic=Sujet kafka_topic_description=Sujet à surveiller. Doit être utilisé avec les mesures du consommateur/producteur kafka_partition=Partition kafka_partition_description=Partition à surveiller. Doit être utilisé spécifiquement avec la configuration des consommateurs et des sujets. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants_it.properties ================================================ newDataSet=Nuovo {0} Data Set error=Si è verificato un errore type=Tipo message=Messaggio cause=Causa ok=Ok loading=Caricamento selectType=Seleziona il tipo di provider bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka bean_description=Il provider Bean consente di consumare dati generati da una classe Java csv_description=Il provider CSV consente di consumare dati presenti in un file CSV sql_description=Il provider SQL consente di consumare dati presenti in un sistema di archiviazione SQL prometheus_description=Il provider Prometheus consente di consumare dati da una query Prometheus kafka_description=Il provider Kafka consente di ottenere metriche da un broker, un consumatore o un produttore Kafka next=Avanti next_description=Vai alla configurazione del provider updateTest_description=Testa la configurazione aggiornata del provider eseguendo una ricerca dei dati nel sistema remoto. Attenzione: la tabella nella scheda di anteprima verrà aggiornata e perderai le tue colonne e le configurazioni dei filtri correnti, se presenti. test=Test test_description=Testa i parametri di configurazione del provider eseguendo una ricerca dei dati nel sistema remoto. Il risultato della ricerca viene visualizzato nella schermata successiva. save=Salva save_description=Salva il tuo data set e registrarlo per renderlo disponibile back=Indietro back_description=Torna alla schermata di selezione del tipo performance=Prestazioni backendCache=Cache del backend clientCache=Cache del client none=Nessuno refreshOnStaleData=Aggiorna su dati obsoleti refreshEvery=Aggiorna i dati ogni bytes=Byte rows=Righe attributeId=ID attributeColumnType=Tipo di dati della colonna attributeColumnType_description=Il tipo di dati per la colonna del data set labelColumnType_description=Le colonne delle etichette supportano operazioni di raggruppamento. Un''operazione di raggruppamento su una colonna delle etichette genera una riga per ogni valore distinto. Ad esempio, un grafico a torta visualizzerà tante fette quante sono le etichette disponibili. textColumnType_description=Le colonne di testo non supportano operazioni di raggruppamento (a differenza delle colonne delle etichette). Quindi di solito vengono visualizzate come dati grezzi in visualizzazioni non categorizzate come i report tabellari. numberColumnType_description=Le colonne numeriche non supportano operazioni di raggruppamento. Tuttavia, quando il data set è raggruppato per una colonna di etichetta o data, è possibile applicare diverse funzioni di aggregazione sulla colonna numerica: somma, media, minimo, massimo, ecc. dateColumnType_description=Le colonne delle date supportano operazioni di raggruppamento. Sono supportati diversi intervalli di tempo: secondo, ora, giorno, settimana, mese, ecc. attributeUUID=UUID attributeUUID_description=Identificatore univoco del data set. Utile per fare riferimento al data set attributeName=Nome attributeName_description=Nome del data set. Una stringa descrittiva che descrive il data set attributeMaxBytes=Byte massimi attributeMaxBytes_description=Se la cache del client è abilitata, specifica la dimensione massima (in byte) consentita per l''inserimento del data set nel client. Se la dimensione del data set è maggiore di questo valore, non viene inserito nel client attributeMaxRows=Righe massime attributeMaxRows_description=Se la cache del backend è abilitata, specifica la dimensione massima (in righe) consentita per la memorizzazione nella cache del data set in memoria. Se la dimensione del data set è maggiore di questo valore, non viene memorizzato nella cache attributeRefreshInterval=Intervallo attributeRefreshInterval_description=Se il refresh del data set è abilitato, specifica l''intervallo per l''aggiornamento. Ad ogni aggiornamento viene effettuata una ricerca nel sistema di archiviazione esterno on=ON off=OFF sql_datasource=Origine dati sql_datasource_description=La connessione al database. Viene sempre fornita dal contenitore sottostante. sql_datasource_placeHolder=java:jboss/datasources/ExampleDS sql_datasource_selectHint=- Seleziona origine dati - sql_schema=Schema sql_schema_description=Lo schema del database, se necessario. Può essere vuoto sql_schema_placeHolder=MySchema01 sql_table=Tabella sql_table_description=La tabella del database da interrogare sql_table_placeHolder=MyTable sql_source=Origine sql_source_description=Il nome di una tabella di database esistente o una frase SQL completa sql_query=Query sql_query_description=Una query SQL ANSI per recuperare il data set sql_query_placeHolder=select * from MyTable csv_filePath=Percorso del file csv_filePath_description=Il percorso nel file system locale in cui si trova il file CSV csv_URL=URL del file csv_URL_description=L''URL per il contenuto CSV, ad esempio: http://myhost.com/myreports.csv csv_URL_placeholder=file:///home/dashbuilder/myReports.csv csv_useFilePath=Passa alla modalità selezione file csv_useFileURL=Passa alla modalità URL remoto csv_sepChar=Carattere separatore csv_sepChar_description=Il carattere utilizzato per separare i valori csv_sepChar_placeholder=Carattere separatore (;) csv_quoteChar=Carattere di citazione csv_quoteChar_description=Il carattere utilizzato per le citazioni csv_quoteChar_placeholder=Carattere di citazione (\\) csv_escapeChar=Carattere di escape csv_escapeChar_description=Il carattere utilizzato per l''escape dei valori csv_escapeChar_placeholder=Carattere di escape (\\) csv_datePattern=Pattern data csv_datePattern_description=Il pattern di data per consumare i valori delle colonne di data presenti nel file CSV csv_datePattern_placeholder=Pattern data (MM-dd-yyyy) csv_numberPattern=Pattern numerico csv_numberPattern_description=Il pattern numerico per consumare i valori delle colonne numeriche presenti nel file CSV csv_numberPattern_placeholder=Pattern numerico (#,###.##) bean_generator_class=Classe generatore bean_generator_class_description=Il nome completo della classe Java che genera il data set, ad esempio: org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=Parametri generatore bean_generator_params_description=Un elenco di coppie di valori da utilizzare come argomenti della classe generatore tab_configguration=Configurazione tab_preview=Anteprima tab_advancedConfiguration=Avanzate filter=Filtro dataColumns=Colonne dati dataSetMustHaveAtLeastOneColumn=Il data set deve avere almeno una colonna columnIsUsedInFilter=La colonna è utilizzata nel filtro label=Etichetta text=Testo number=Numero date=Data showColumnsAndFilter=Mostra pannello colonne e filtro hideColumnsAndFilter=Nascondi pannello colonne e filtro defNotFound=Definizione del data set non trovata o questo data set non ha una definizione prometheus_server_url=URL server prometheus_server_url_description=URL del server Prometheus, ad esempio: http://localhost:9090/ prometheus_server_url_placeholder=http://localhost:9090 prometheus_query=Query prometheus_query_description=La query utilizzata per recuperare i dati per questo data set prometheus_query_placeholder=time() kafka_host=Host kafka_host_description=Host in cui è in esecuzione il broker/consumatore/produttore Kafka kafka_host_placeholder=127.0.0.1 kafka_port=Porta kafka_port_description=Porta JMX secondo Kafka JMX kafka_port_placeholder=9999 kafka_target=Destinazione kafka_target_description=La destinazione per la raccolta delle metriche. L''output cambia in base alla destinazione selezionata. kafka_filter=Filtro kafka_filter_description=Filtrare le metriche dal risultato del data set. Il filtro funziona sulle colonne dominio, tipo e nome. kafka_clientId=ID client kafka_clientId_description=L''ID client. Richiesto per le metriche del consumatore/produttore. kafka_nodeId=ID nodo kafka_nodeId_description=ID nodo che può essere utilizzato con le metriche del consumatore/produttore kafka_topic=Argomento kafka_topic_description=Argomento da monitorare. Dovrebbe essere utilizzato con le metriche del consumatore/produttore kafka_partition=Partizione kafka_partition_description=Partizione da monitorare. Dovrebbe essere utilizzata specificamente con la configurazione del consumatore e dell''argomento. ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants_ja.properties ================================================ newDataSet=新しい {0} データセット error=エラーが発生しました type=タイプ message=メッセージ cause=原因 ok=OK loading=ロード中 selectType=プロバイダータイプの選択 bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka bean_description=Bean プロバイダーにより Java クラスで生成されたデータを消費できるようになります csv_description=CSV プロバイダーにより CSV ファイルに含まれるデータを消費できるようになります sql_description=SQL プロバイダーにより SQL ストレージシステムに存在するデータを消費できるようになります prometheus_description=Prometheus プロバイダーを使用すると、Prometheus Query からのデータを使用できます。 kafka_description=Kafka プロバイダーを使用すると、Kafka ブローカー、コンシューマー、またはプロデューサーからメトリクスを取得できます。 next=次へ next_description=プロバイダー設定エディションに移動 updateTest_description=リモートシステムに対してデータルックアップを実行して、データプロバイダー設定の更新パラメーターをテストします。注意: プレビュータブの表が更新されるため、現在の列とフィルター設定がある場合には失われます。 test=テスト test_description=リモートシステムに対してデータルックアップを実行して、データプロバイダー設定パラメーターをテストします。ルックアップの結果は次の画面に表示されます。 save=保存 save_description=データセットを保存および登録して利用可能にする back=戻る back_description=タイプ選択画面に戻る performance=パフォーマンス backendCache=バックエンドキャッシュ clientCache=クライアントキャッシュ none=なし refreshOnStaleData=古いデータの更新 refreshEvery=データ更新間隔 bytes=バイト rows=行 attributeId=Id attributeColumnType=列データタイプ attributeColumnType_description=データセット列のデータタイプ labelColumnType_description=ラベル列はグループ操作をサポートします。ラベル列のグループ操作では、個別の値ごとに 1 行生成します。たとえば、円グラフには、使用可能なラベルと同じ数のスライスが表示されます。 textColumnType_description=テキスト列は (ラベル列とは異なり) グループ操作をサポートしていません 。そのため、通常、テーブルレポートなど、分類されていない視覚化部分にローデータとして表示されます。 numberColumnType_description=数値の列はグループ操作をサポートしません。 ただし、データセットをラベル列または日付列でグループ化すると、数値列に様々な集約関数 (sum、average、min、max など) が適用されます。 dateColumnType_description=日付列はグループ操作をサポートします。様々な時間間隔 (second、hour、day、week、month など) がサポートされます。 attributeUUID=UUID attributeUUID_description=データセットの一意の識別子。データセットの参照に便利 attributeName=名前 attributeName_description=データセットの名前。データセットを表す記述的な文字列にします attributeMaxBytes=最大バイト attributeMaxBytes_description=クライアントキャッシュが有効な場合は、データセットをクライアントにプッシュできる最大サイズ (バイト単位) を指定します。データセットのサイズがこの値より大きい場合には、クライアントにプッシュされません attributeMaxRows=最大行 attributeMaxRows_description=バックエンドキャッシュが有効な場合は、データセットをメモリーでキャッシュするために許可される最大サイズ (行単位) を指定します。データセットサイズがこの値よりも大きい場合は、キャッシュされません attributeRefreshInterval=間隔 attributeRefreshInterval_description=データセットの更新が有効な場合には、更新の間隔を指定します。更新ごとに、外部ストレージシステムのルックアップが行われます on=ON off=OFF sql_datasource=データソース sql_datasource_description=データベースへの接続。常に基本コンテナーによって提供されます。 sql_datasource_placeHolder=java:jboss/datasources/ExampleDS sql_datasource_selectHint=- データソースの選択 - sql_schema=スキーマ sql_schema_description=データベーススキーマ (必要な場合)。空白にすることができます sql_schema_placeHolder=MySchema01 sql_table=テーブル sql_table_description=クエリーを実行するデータベーステーブル sql_table_placeHolder=MyTable sql_source=ソース sql_source_description=既存のデータベーステーブルの名前、または完全な SQL 文 sql_query=クエリー sql_query_description=データセットを取得する ANSI SQL クエリー sql_query_placeHolder=select * from MyTable csv_filePath=ファイルパス csv_filePath_description=CSV ファイルが存在するローカルのファイルシステムパス csv_URL=ファイル URL csv_URL_description=CSV コンテンツへの URL、f.i: http://myhost.com/myreports.csv csv_URL_placeholder=file:///home/dashbuilder/myReports.csv csv_useFilePath=ファイル選択モードに切り替える csv_useFileURL=リモート URL モードに切り替える csv_sepChar= セパレーター文字 csv_sepChar_description= 値を区切るために使用する文字 csv_sepChar_placeholder= セパレーター文字 (;) csv_quoteChar=引用符 csv_quoteChar_description=引用に使用する文字 csv_quoteChar_placeholder=引用符 (\) csv_escapeChar=エスケープ文字 csv_escapeChar_description=値をエスケープするために使用する文字 csv_escapeChar_placeholder=エスケープ文字 (\) csv_datePattern=日付形式 csv_datePattern_description=CSV ファイルに存在する日付列値を消費するための日付形式 csv_datePattern_placeholder=日付形式 (MM-dd-yyyy) csv_numberPattern=数値形式 csv_numberPattern_description=CSV ファイルに存在する数値列値を消費するための数値形式 csv_numberPattern_placeholder=数値形式 (#,###.##) bean_generator_class=ジェネレータークラス bean_generator_class_description=データセットを生成する Java クラスの完全修飾クラス名、f.i: org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=ジェネレーターパラメーター bean_generator_params_description=ジェネレーターのクラス引数として使用する値ペアのパラメーターリスト tab_configguration=設定 tab_preview=プレビュー tab_advancedConfiguration=高度 filter=フィルター dataColumns=データ列 dataSetMustHaveAtLeastOneColumn=データセットに少なくとも 1 列は指定してください columnIsUsedInFilter=列はフィルターで使用されます label=ラベル text=テキスト number=数値 date=日付 showColumnsAndFilter=列とフィルターパネルの表示 hideColumnsAndFilter=列とフィルターパネルを隠す defNotFound=データセット定義が見つからないか、このデータセットに定義がありません prometheus_server_url=サーバー URL prometheus_server_url_description=Prometheus サーバーの URL f.i: http://localhost:9090/ prometheus_server_url_placeholder=http://localhost:9090 prometheus_query=クエリー prometheus_query_description=このデータセットのデータの取得に使用するクエリー。 prometheus_query_placeholder=時間() kafka_host=ホスト kafka_host_description=Kafka ブローカー/コンシューマー/プロデューサーの実行先のホスト kafka_host_placeholder=127.0.0.1 kafka_port=ポート kafka_port_description=Kafka JMX に基づく JMX ポート kafka_port_placeholder=9999 kafka_target=ターゲット kafka_target_description=メトリック収集のターゲット。出力は、選択したターゲットに合わせて変更されます。 kafka_filter=フィルター kafka_filter_description=データセットの結果からメトリクスをフィルタリングします。フィルターはドメイン、タイプ、名前の列で使用できます。 kafka_clientId=クライアント ID kafka_clientId_description=クライアント ID。コンシューマー/プロデューサーメトリクスに必要です。 kafka_nodeId=ノード ID kafka_nodeId_description=コンシューマー/プロデューサーメトリクスと併用できるノード ID kafka_topic=トピック kafka_topic_description=監視するトピック。コンシューマー/プロデューサーメトリクスと合わせて使用する必要があります。 kafka_partition=パーティション kafka_partition_description=監視するパーティション。これは、特にコンシューマーとトピック設定と合わせて使用する必要があります。 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants_pt_BR.properties ================================================ newDataSet=Novo{0} Data Set error=Ocorreu um erro type=Tipo message=Mensagem cause=Causa ok=Ok loading=Carregando selectType=Selecione o tipo de provedor bean=Bean csv=CSV sql=SQL bean_description=O provedor Bean permite consumir dados gerados pela classe do Java csv_description=O provedor CSV permite consumir dados presentes no arquivo CSV sql_description=O provedor SQL permite consumir dados presentes em um sistema de armazenamento de SQL next=Próximo next_description=Vá para a edição da configuração do provedor test=Teste save=Salvar save_description=Salve seus data sets e registre-o para torná-lo disponível back=Retornar performance=Desempenho backendCache=Cache de backend clientCache=Cache de cliente none=Nenhum refreshOnStaleData=Atualizar em dados interrompidos refreshEvery=Atualizar dados a cada bytes=Bytes rows=Linhas attributeId=Id attributeColumnType=O tipo de dados da coluna attributeColumnType_description=O tipo de dados para a coluna do data set attributeUUID=UUID attributeUUID_description=Identificador único do data set. Útil para referenciar o data set attributeName=Nome attributeName_description=Nome do conjunto de dados. Uma sequência de caracteres que descreve o conjunto de dados attributeMaxBytes=Max bytes attributeMaxBytes_description=Se o cache do cliente está ativado, especifique o tamanho máximo (em bytes) permitido para enviar o data set ao cliente. Se o tamanho do conjunto de dados for maior do que este valor, ele não será enviado ao cliente attributeMaxRows=Máximo de Linhas attributeMaxRows_description=Se o cache backend estiver ativado, especifique o tamanho máximo (em linhas) permitidos para agrupar o data set na memória. Se o tamanho do conjunto de dados for maior do que esse valor, ele não foi agrupado attributeRefreshInterval=Intervalo attributeRefreshInterval_description=Caso a atualização do data set esteja habilitada, especifique o intervalo para atualizá-lo. Em cada atualização, será realizada uma busca no sistema de armazenamento. on=LIGADO off=DESLIGADO sql_datasource=Data Source sql_datasource_placeHolder=java\:jboss/datasources/ExampleDS sql_schema=Esquema sql_schema_description=O esquema do banco de dados, se necessário. Pode ser vazio. sql_schema_placeHolder=MySchema01 sql_table=Tabela sql_table_description=A tabela de banco de dados para pesquisa sql_table_placeHolder=Minha Tabela sql_source=Fonte sql_query=Pesquisa sql_query_description=Consulta ANSI SQL para buscar o conjunto de dados sql_query_placeHolder=selecione * a partir de Minha Tabela csv_filePath=Caminho do Arquivo csv_filePath_description=Caminho do sistema do arquivo local onde o arquivo CSV está localizado csv_URL=Arquivar URL csv_URL_description=URL para os conteúdos CSV, f.i\: http\://myhost.com/myreports.csv csv_URL_placeholder=file\:///home/dashbuilder/myReports.csv csv_useFilePath=Altere para o modo seletor do arquivo csv_useFileURL=Altere para o modo do URL remoto csv_sepChar=Carac. Separador csv_sepChar_description=A codificação do caractere usado para valores separados csv_sepChar_placeholder=Carac. Separador (;) csv_quoteChar=Caractere Aspas csv_quoteChar_description=A codificação do caractere usado para cotas csv_quoteChar_placeholder=Carac. de Cotas (\\) csv_escapeChar=Carac Escape csv_escapeChar_description=A codificação do caractere usado para valores de escape csv_escapeChar_placeholder=Carac Escape(\\) csv_datePattern=Modelo da data\: csv_datePattern_description=O modelo de data para o consumo de valores das colunas de data presentes no arquivo CSV csv_datePattern_placeholder=Modelo de data (MM-dd-yyy) csv_numberPattern=Modelo de número csv_numberPattern_description=O modelo de número para valores de coluna de números presente no arquivo CSV csv_numberPattern_placeholder=Modelo de número (\#,\#\#\#.\#\#) el_cluster_name=nome do Cluster el_cluster_name_description=O nome do cluster. Pode ser vazio el_cluster_name_placeholder=my_cluster el_index=Índice el_index_placeholder=my_index el_type=Tipo do Documento el_type_description=Tipo de documento para consulta do índice fornecido. Pode conter vários valores separados por vírgula. Se vazio, o índice atual fornecido será consumido el_type_placeholder=my_type bean_generator_class=Classe geradora bean_generator_class_description=Nome de classe totalmente qualificado da classe em Java que gera o conjunto de dados. f.i\: org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=Parâmetros de geradores bean_generator_params_description=Lista de parâmetros do par valor para uso como argumentos de classe do gerador tab_configguration=Configuração tab_preview=Visualização tab_advancedConfiguration=Avançado filter=Flitro dataColumns=Colunas de dados dataSetMustHaveAtLeastOneColumn=O Conjunto de Dados deve ter pelo menos uma coluna columnIsUsedInFilter=A coluna é usada no filtro label=Rótulo text=Texto number=Número date=Data showColumnsAndFilter=Exibe as colunas e filtra o painel hideColumnsAndFilter=Esconde as colunas e filtra o painel defNotFound=Definição do data set não foi encontrado ou este data set não possui definição ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetEditorConstants_zh_CN.properties ================================================ newDataSet=新建 {0} 数据集 error=发生了错误 type=类型 message=消息 cause=原因 ok=确认 loading=正在加载 selectType=选择供应商类型 bean=Bean csv=CSV sql=SQL bean_description=Bean 供应商允许消费 Java 类生成的数据 csv_description=CSV 供应商允许消费 CSV 文件里的数据 sql_description=SQL 供应商允许消费 SQL 存储系统里的数据 next=下一步 next_description=编辑供应商配置 test=测试 save=保存 save_description=保存您的数据并注册它以使其可用 back=后退 performance=性能 backendCache=后台缓存 clientCache=客户缓存 none=无 refreshOnStaleData=刷新过时数据 refreshEvery=数据刷新频率 bytes=字节 rows=行 attributeId=ID attributeColumnType=列数据类型 attributeColumnType_description=数据集列的数据类型 attributeUUID=UUID attributeUUID_description=数据集的唯一标识符。用于引用数据集。 attributeName=名称 attributeName_description=数据集名称。是一个描述该数据集的描述性字符串。 attributeMaxBytes=最大字节 attributeMaxBytes_description=如果启用了客户缓存,指定推送数据集到客户所允许的最大规格(字节)。如果数据集的大小大于这个值,它不会被推送至客户。 attributeMaxRows=最大行数 attributeMaxRows_description=如果启用了后台缓存,指定内存里缓存数据集所允许的最大规格(行数)。如果数据集的大小大于这个值,它不会被缓存。 attributeRefreshInterval=间隔 attributeRefreshInterval_description=如果启用过了数据集刷新,它指定刷新的时间间隔。每次刷新时都会完成一次对外部存储系统的查找。 on=ON off=OFF sql_datasource=数据源 sql_datasource_placeHolder=java\:jboss/datasources/ExampleDS sql_schema=模式 sql_schema_description=数据库模式。它可以为空。 sql_schema_placeHolder=MySchema01 sql_table=表 sql_table_description=要查询的数据库表 sql_table_placeHolder=MyTable sql_source=源 sql_query=查询 sql_query_description=用于获取数据集的 ANSI SQL 查询 sql_query_placeHolder=select * from MyTable csv_filePath=文件路径 csv_filePath_description=CSV 文件所在的本地文件系统路径 csv_URL=文件 URL csv_URL_description=CSV 内容的 URL,f.i\: http\://myhost.com/myreports.csv csv_URL_placeholder=file\:///home/dashbuilder/myReports.csv csv_useFilePath=切换到文件选择器模式 csv_useFileURL=切换到远程 URL 模式 csv_sepChar=分隔符 csv_sepChar_description=用于分隔值的字符 csv_sepChar_placeholder=分隔符 (;) csv_quoteChar=引用字符 csv_quoteChar_description=用于引用的字符 csv_quoteChar_placeholder=引用字符 (\\) csv_escapeChar=转义字符 csv_escapeChar_description=用于转义的字符 csv_escapeChar_placeholder=转义字符 (\\) csv_datePattern=日期格式 csv_datePattern_description=消费 CSV 文件里日期列的值所使用的模式 csv_datePattern_placeholder=日期格式 (MM-dd-yyyy) csv_numberPattern=数字格式 csv_numberPattern_description=消费 CSV 文件里数字列的值所使用的模式 csv_numberPattern_placeholder=数字格式 (\#,\#\#\#.\#\#) el_cluster_name=群集名称 el_cluster_name_description=群集的名称。它可以为空。 el_cluster_name_placeholder=my_cluster el_index=索引 el_index_placeholder=my_index el_type=文档类型 el_type_description=对给定索引进行查询的文档类型。可包含使用逗号分开的多个值。如果为空,则会消耗给出当前索引的所有文档类型。 el_type_placeholder=my_type bean_generator_class=生成器类 bean_generator_class_description=生成数据集的 Java 类的全限定类名称。 f.i\: org.example.MyDataSetGenerator bean_generator_class_placeholder=org.example.MyDataSetGenerator bean_generator_params=生成器参数 bean_generator_params_description=作为生成器类参数使用的值对参数列表 tab_configguration=配置 tab_preview=预览 tab_advancedConfiguration=高级的 filter=过滤器 dataColumns=数据列 dataSetMustHaveAtLeastOneColumn=数据集中必须至少有一列 columnIsUsedInFilter=将该列作为过滤器使用 label=标签 text=文本 number=数字 date=日期 showColumnsAndFilter=显示列和过滤器面板 hideColumnsAndFilter=隐藏列和过滤器面板 defNotFound=未找到数据集定义或者这个数据集没有定义 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants.properties ================================================ title=Data Set Explorer newDataSet=New Data Set noDataSets=No data sets cache=Backend cache push=Client cache refresh=Refresh edit=Edit delete=Delete bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka enabled=Enabled disabled=Disabled bytes=Bytes rows=Rows currentStatus=Current status currentSize=Current size notFound=Data Set definition not found loading=Loading error=An error has occurred type=Type message=Message cause=Cause ok=Ok ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants_de.properties ================================================ title=Datensatz-Explorer newDataSet=Neuer Datensatz noDataSets=Keine Datensätze cache=Backend-Cache push=Client-Cache refresh=Aktualisieren edit=Bearbeiten delete=Löschen bean=Bean csv=CSV sql=SQL enabled=Aktiviert disabled=Deaktiviert bytes=Bytes rows=Reihen currentStatus=Aktueller Status currentSize=Aktuelle Größe notFound=Datensatzdefinition nicht gefunden loading=Lade error=Ein Fehler ist aufgetreten type=Typ message=Nachricht cause=Ursache ok=Ok ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants_es.properties ================================================ title=Explorador de conjuntos de datos newDataSet=Nuevo conjunto de datos noDataSets=No hay conjuntos de datos cache=Caché back-end push=Caché cliente refresh=Actualizar edit=Editar delete=Eliminar bean=Bean csv=CSV sql=SQL prometheus=Prometeo kafka=Kafka enabled=Habilitado disabled=Deshabilitado bytes=Bytes rows=Filas currentStatus=Estado actual currentSize=Tamaño actual notFound=No se encuentra la definición del conjunto de datos loading=Cargando error=Se produjo un error type=Tipo message=Mensaje cause=Motivo ok=Aceptar ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants_fr.properties ================================================ title=Explorateur d''ensembles de données newDataSet=Nouvel ensemble de données noDataSets=Aucun ensemble de données cache=Cache du backend push=Cache du client refresh=Rafraîchir edit=Modifier delete=Supprimer bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka enabled=Activé disabled=Désactivé bytes=Octets rows=Lignes currentStatus=État actuel currentSize=Taille actuelle notFound=Définition de l''ensemble de données introuvable loading=Chargement error=Une erreur s''est produite type=Type message=Message cause=Cause ok=OK ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants_it.properties ================================================ title=Esploratore di set di dati newDataSet=Nuovo set di dati noDataSets=Nessun set di dati cache=Cache backend push=Cache client refresh=Aggiorna edit=Modifica delete=Elimina bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka enabled=Abilitato disabled=Disabilitato bytes=Byte rows=Righe currentStatus=Stato corrente currentSize=Dimensione corrente notFound=Definizione del set di dati non trovata loading=Caricamento error=Si è verificato un errore type=Tipo message=Messaggio cause=Causa ok=Ok ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants_ja.properties ================================================ title=データセットエクスプローラー newDataSet=新しいデータセット noDataSets=データセットなし cache=バックエンドキャッシュ push=クライアントキャッシュ refresh=更新 edit=編集 delete=削除 bean=Bean csv=CSV sql=SQL prometheus=Prometheus kafka=Kafka enabled=有効 disabled=無効 bytes=バイト rows=行 currentStatus=現在のステータス currentSize=現在のサイズ notFound=データセット定義が見つかりません loading=ロード中 error=エラーが発生しました type=タイプ message=メッセージ cause=原因 ok=OK ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants_pt_BR.properties ================================================ title=Explorador do Data Set newDataSet=Novo Data Set noDataSets=Nenhum Data set cache=Cache de backend push=Cache de cliente refresh=Atualizar edit=Editar delete=Deletar bean=Bean csv=CSV sql=SQL enabled=Ativado disabled=Desativado bytes=Bytes rows=Linhas currentStatus=Status atual currentSize=Tamanho atual notFound=Definição de Data Set não foi encontrada loading=Carregando error=Ocorreu um erro type=Tipo message=Mensagem cause=Causa ok=Ok ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/main/resources/org/dashbuilder/client/widgets/resources/i18n/DataSetExplorerConstants_zh_CN.properties ================================================ title=数据集浏览器 newDataSet=新建数据集 noDataSets=没有数据集 cache=后台缓存 push=客户缓存 refresh=刷新 edit=编辑 delete=删除 bean=Bean csv=CSV sql=SQL enabled=已启用的 disabled=已禁用的 bytes=字节 rows=行 currentStatus=当前状态 currentSize=当前大小 notFound=未找到数据集定义 loading=正在加载 error=出错 type=类型 message=消息 cause=原因 ok=确认 ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/common/ClientRuntimeErrorPopupPresenterTest.java ================================================ package org.dashbuilder.client.widgets.common; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.client.workbench.widgets.common.ErrorPopupPresenter; import org.uberfire.mvp.Command; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class ClientRuntimeErrorPopupPresenterTest { @Mock ErrorPopupPresenter.View view; private ClientRuntimeErrorPopupPresenter presenter; @Before public void setup() { // The presenter instance to test. presenter = new ClientRuntimeErrorPopupPresenter(view); } @Test public void testShowMessage() throws Exception { final ClientRuntimeError error = mock(ClientRuntimeError.class); final String message = "message"; final Throwable cause = mock(Throwable.class); final String localizedMessage = "localizedMessage"; when(cause.getLocalizedMessage()).thenReturn(localizedMessage); when(error.getMessage()).thenReturn(message); when(error.getRootCause()).thenReturn(cause); presenter.showMessage(error); verify(view, times(1)).showMessage(anyString(), any(Command.class), any(Command.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/common/CustomDataSetProviderType.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.common; import org.dashbuilder.dataprovider.AbstractProviderType; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.StaticDataSetDef; public class CustomDataSetProviderType extends AbstractProviderType { @Override public String getName() { return "CUSTOM"; } @Override public StaticDataSetDef createDataSetDef() { StaticDataSetDef custom = new StaticDataSetDef(); custom.setProvider(this); return custom; } @Override public boolean equals(Object obj) { if (! (obj instanceof DataSetProviderType)) { return false; } return getName().equals(((DataSetProviderType) obj).getName()); } @Override public int hashCode() { return getName().hashCode(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/common/LoadingBoxTest.java ================================================ package org.dashbuilder.client.widgets.common; import com.google.gwtmockito.GwtMockitoTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class LoadingBoxTest { @Mock LoadingBox.View view; private LoadingBox presenter; @Before public void setup() { // The presenter instance to test. presenter = new LoadingBox(view); } @Test public void testShow() throws Exception { presenter.show(); verify(view, times(1)).show(anyString()); } @Test public void testHide() throws Exception { presenter.hide(); verify(view, times(1)).close(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefColumnsFilterEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.column.DataSetDefColumnsEditor; import org.dashbuilder.client.widgets.dataset.event.FilterChangedEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.DataSetFilter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import java.util.ArrayList; import java.util.List; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefColumnsFilterEditorTest { @Mock DataSetDefColumnsEditor columnsEditor; @Mock DataSetDefFilterEditor dataSetFilterEditor; @Mock DataSetDefColumnsFilterEditor.View view; @Mock DataSetDef dataSetDef; private DataSetDefColumnsFilterEditor tested; @Before public void setup() throws Exception { when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); tested = new DataSetDefColumnsFilterEditor(columnsEditor, dataSetFilterEditor, view); } @Test public void testInit() throws Exception { tested.init(); verify(view, times(1)).init(tested); verify(view, times(1)).initWidgets(any(), any()); verify(view, times(0)).setMaxHeight(anyString()); } @Test public void testSetMaxHeight() throws Exception { final String maxH = "100px"; tested.setMaxHeight(maxH); verify(view, times(0)).init(tested); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefFilterEditor.View.class)); verify(view, times(1)).setMaxHeight(maxH); } @Test public void testColumnListEditor() throws Exception { assertEquals(columnsEditor, tested.columnListEditor()); } @Test public void testDataSetFilterEditor() throws Exception { assertEquals(dataSetFilterEditor, tested.dataSetFilter()); } @Test public void testSetAcceptableValues() throws Exception { final List l = mock(List.class); tested.setAcceptableValues(l); verify(columnsEditor, times(1)).setAcceptableValues(l); verify(view, times(0)).init(tested); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefFilterEditor.View.class)); verify(view, times(0)).setMaxHeight(anyString()); } @Test public void testSetValue() throws Exception { DataSetFilter newFilter = mock(DataSetFilter.class); List createColumnFilters = createColumnFilters("col1", "col2"); when(newFilter.getColumnFilterList()).thenReturn(createColumnFilters); when(dataSetDef.getDataSetFilter()).thenReturn(newFilter); tested.setValue(dataSetDef); verify(columnsEditor, times(1)).onValueRestricted("col1"); verify(columnsEditor, times(1)).onValueRestricted("col2"); verify(columnsEditor, times(0)).onValueUnRestricted(anyString()); verify(columnsEditor, times(0)).setAcceptableValues(any(List.class)); verify(view, times(0)).init(tested); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefFilterEditor.View.class)); verify(view, times(0)).setMaxHeight(anyString()); } @Test public void testOnFilterChangedEvent() throws Exception { DataSetFilter oldFilter = mock(DataSetFilter.class); List oldCreateColumnFilters = createColumnFilters("col1", "col2", "col3"); when(oldFilter.getColumnFilterList()).thenReturn(oldCreateColumnFilters); DataSetFilter newFilter = mock(DataSetFilter.class); List createColumnFilters = createColumnFilters("col2"); when(newFilter.getColumnFilterList()).thenReturn(createColumnFilters); when(dataSetDef.getDataSetFilter()).thenReturn(newFilter); FilterChangedEvent filterChangedEvent = mock(FilterChangedEvent.class); when(filterChangedEvent.getContext()).thenReturn(dataSetFilterEditor); when(filterChangedEvent.getOldFilter()).thenReturn(oldFilter); when(filterChangedEvent.getFilter()).thenReturn(newFilter); tested.onFilterChangedEvent(filterChangedEvent); verify(columnsEditor, times(1)).onValueRestricted("col2"); verify(columnsEditor, times(1)).onValueUnRestricted("col1"); verify(columnsEditor, times(1)).onValueUnRestricted("col3"); verify(columnsEditor, times(0)).setAcceptableValues(any(List.class)); verify(view, times(0)).init(tested); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefFilterEditor.View.class)); verify(view, times(0)).setMaxHeight(anyString()); } private List createColumnFilters(String... columns) { List result = new ArrayList(); for (String column : columns) { ColumnFilter cf = mock(ColumnFilter.class); when(cf.getColumnId()).thenReturn(column); result.add(cf); } return result; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefFilterEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.event.FilterChangedEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.displayer.client.events.DataSetFilterChangedEvent; import org.dashbuilder.displayer.client.widgets.filter.DataSetFilterEditor; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefFilterEditorTest { @Mock EventSourceMock filterChangedEvent; @Mock DataSetDefFilterEditor.View view; @Mock DataSetDef dataSetDef; @Mock DataSetFilterEditor dataSetFilterEditor; @Mock DataSetMetadata dataSetMetadata = mock(DataSetMetadata.class); @Mock DataSetFilter filter1 = mock(DataSetFilter.class); @Mock DataSetFilter filter2 = mock(DataSetFilter.class); private DataSetDefFilterEditor tested; @Before public void setup() throws Exception { when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); when(filter1.cloneInstance()).thenReturn(filter2); tested = new DataSetDefFilterEditor(view, dataSetFilterEditor, filterChangedEvent); } @Test public void testInit() throws Exception { verify(view).init(tested); } @Test public void testInitFilterEditor() throws Exception { tested.value = filter1; tested.init(dataSetMetadata); verify(view).setWidget(any(IsWidget.class)); verify(dataSetFilterEditor).init(eq(filter2), eq(dataSetMetadata)); } @Test public void testSetValue() throws Exception { tested.setValue(filter1); assertEquals(filter2, tested.value); verify(view, never()).setWidget(any(IsWidget.class)); verify(dataSetFilterEditor, never()).init(any(DataSetFilter.class), any(DataSetMetadata.class)); } @Test public void testOnValueChanged() throws Exception { DataSetFilter filter3 = mock(DataSetFilter.class); when(filter2.cloneInstance()).thenReturn(filter3); tested.value = filter1; tested.onValueChanged(new DataSetFilterChangedEvent(filter2)); assertEquals(filter3, tested.value); verify(view, never()).setWidget(any(IsWidget.class)); verify(dataSetFilterEditor, never()).init(any(DataSetFilter.class), any(DataSetMetadata.class)); verify(filterChangedEvent).fire(any(FilterChangedEvent.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefPreviewTableTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.def.DataSetDefFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.AbstractDisplayerTest; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerListener; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import java.util.Date; import java.util.List; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.Silent.class) public class DataSetDefPreviewTableTest extends AbstractDisplayerTest { @Mock DataSetDefPreviewTable.View view; @Mock DataSetDef dataSetDef; private DataSetDefPreviewTable tested; final List columnDefList = mock(List.class); final Displayer displayer = mock(Displayer.class); final DisplayerListener displayerListener = mock(DisplayerListener.class); final DisplayerSettings displayerSettings = mock(DisplayerSettings.class); @Before public void setup() throws Exception { when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); when(columnDefList.isEmpty()).thenReturn(true); when(dataSetDef.clone()).thenReturn(dataSetDef); tested = new DataSetDefPreviewTable(displayerLocator, clientServices, view); } @Test public void testInit() throws Exception { tested.init(); verify(view, times(1)).init(tested); verify(view, times(0)).setDisplayer(any(IsWidget.class)); verify(view, times(0)).clear(); } @Test public void testClear() throws Exception { tested.tableDisplayer = displayer; tested.clear(); assertNull(tested.tableDisplayer); verify(view, times(0)).init(tested); verify(view, times(0)).setDisplayer(any(IsWidget.class)); verify(view, times(1)).clear(); } // TODO - David: @Test - Do the test after DisplayerLocator#get() removed. public void testShow() throws Exception { when(displayerSettings.getRenderer()).thenReturn("gwtcharts"); tested.show(dataSetDef, columnDefList, displayerListener); assertNotNull(tested.tableDisplayer); verify(view, times(0)).init(tested); verify(view, times(1)).setDisplayer(any(IsWidget.class)); verify(view, times(1)).clear(); } @Test public void testDraw() throws Exception { tested.tableDisplayer = displayer; tested.draw(displayerListener); verify(displayer, times(1)).addListener(displayerListener); verify(displayer, times(1)).draw(); verify(view, times(1)).setDisplayer(any(IsWidget.class)); verify(view, times(0)).init(tested); verify(view, times(0)).clear(); } @Test public void testCSVConfig() throws Exception { DataSetDef dataSetDef = DataSetDefFactory.newCSVDataSetDef() .datePattern("dd/MM/yyyy") .numberPattern("#,###") .allColumns(true) .buildDef(); DataSet dataSet = DataSetFactory.newDataSetBuilder() .date("date") .number("number") .row(new Date(), 1d) .buildDataSet(); when(dataSetLookupServices.lookupDataSet(any(), any())).thenReturn(dataSet); tested.show(dataSetDef, null, displayerListener); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Displayer.class); verify(displayerListener).onDataLoaded(argumentCaptor.capture()); Displayer displayer = argumentCaptor.getValue(); DisplayerSettings settings = displayer.getDisplayerSettings(); assertEquals(settings.getColumnSettings("date").getValuePattern(), "dd/MM/yyyy"); assertEquals(settings.getColumnSettings("number").getValuePattern(), "#,###"); assertEquals(settings.isTableColumnPickerEnabled(), false); } @Test public void testSQLConfig() throws Exception { DataSetDef dataSetDef = DataSetDefFactory.newSQLDataSetDef() .column("date", ColumnType.DATE) .column("number", ColumnType.NUMBER) .buildDef(); DataSet dataSet = DataSetFactory.newDataSetBuilder() .date("date") .number("number") .row(new Date(), 1d) .buildDataSet(); when(dataSetLookupServices.lookupDataSet(any(), any())).thenReturn(dataSet); tested.show(dataSetDef, null, displayerListener); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Displayer.class); verify(displayerListener).onDataLoaded(argumentCaptor.capture()); Displayer displayer = argumentCaptor.getValue(); DisplayerSettings settings = displayer.getDisplayerSettings(); assertFalse(settings.isTableColumnPickerEnabled()); assertEquals(settings.getTablePageSize(), 10); assertTrue(settings.isTableSortEnabled()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/DataSetDefProviderTypeEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.common.CustomDataSetProviderType; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.client.widgets.dataset.event.DataSetDefCreationRequestEvent; import org.dashbuilder.common.client.editor.list.HorizImageListEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.uberfire.mocks.EventSourceMock; import java.util.Arrays; import java.util.Collection; import javax.enterprise.event.Event; import static junit.framework.TestCase.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefProviderTypeEditorTest { @Mock HorizImageListEditor provider; @Mock DataSetDefProviderTypeEditor.View view; @Mock EventSourceMock createEvent; private DataSetDefProviderTypeEditor tested; @Mock ManagedInstance dataSetEditorPlugin; @Mock DataSetEditorPlugin pluginEditor; @Before public void setup() { when(dataSetEditorPlugin.isUnsatisfied()).thenReturn(true); tested = spy(new DataSetDefProviderTypeEditor(provider, createEvent, view, dataSetEditorPlugin)); final String typeTitle = "typeTitle"; doReturn(typeTitle).when(tested).getTypeSelectorTitle(any(DataSetProviderType.class)); final String typeText = "typeText"; doReturn(typeText).when(tested).getTypeSelectorText(any(DataSetProviderType.class)); final SafeUri imageUri = mock(SafeUri.class); doReturn(imageUri).when(tested).getTypeSelectorImageUri(any(DataSetProviderType.class)); } @Test public void testInit() throws Exception { tested.init(); verify(view, times(1)).init(tested); verify(view, times(1)).initWidgets(any()); final ArgumentCaptor actualEntriesCaptor = ArgumentCaptor.forClass(Collection.class); verify(provider, times(1)).setEntries(actualEntriesCaptor.capture()); final Collection actualEntries = actualEntriesCaptor.getValue(); assertEquals(5, actualEntries.size()); } @Test public void testProviderInstance() throws Exception { assertEquals(provider, tested.provider()); } @Test public void testProviderSelected() throws Exception { tested.onItemClicked(new ValueChangeEvent<>(provider, null, DataSetProviderType.BEAN)); verify(createEvent).fire(any()); } @Test public void testInitWithEditorPlugin() throws Exception { when(pluginEditor.getProviderType()).thenReturn(new CustomDataSetProviderType()); when(pluginEditor.getTypeSelectorTitle()).thenReturn("Custom"); when(pluginEditor.getTypeSelectorText()).thenReturn("CustomText"); when(pluginEditor.getTypeSelectorImageUri()).thenReturn(Mockito.mock(SafeUri.class)); when(dataSetEditorPlugin.isUnsatisfied()).thenReturn(false); when(dataSetEditorPlugin.iterator()).thenReturn(Arrays.asList(pluginEditor).iterator(), Arrays.asList(pluginEditor).iterator()); tested.init(); verify(view, times(1)).init(tested); verify(view, times(1)).initWidgets(any()); final ArgumentCaptor actualEntriesCaptor = ArgumentCaptor.forClass(Collection.class); verify(provider, times(1)).setEntries(actualEntriesCaptor.capture()); final Collection actualEntries = actualEntriesCaptor.getValue(); assertEquals(6, actualEntries.size()); verify(pluginEditor, times(1)).getTypeSelectorImageUri(); verify(pluginEditor, times(1)).getTypeSelectorTitle(); verify(pluginEditor, times(1)).getTypeSelectorText(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/DataSetEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.attributes.*; import org.dashbuilder.client.widgets.dataset.event.ColumnsChangedEvent; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.FilterChangedEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.ColumnListEditor; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.displayer.client.DataSetHandler; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerListener; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyDouble; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetEditorTest { @Mock protected DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock protected IsWidget providerAttributesEditorView; @Mock protected DataSetDefColumnsFilterEditor columnsAndFilterEditor; @Mock protected DataSetDefPreviewTable previewTable; @Mock protected DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor; @Mock protected DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor; @Mock protected DataSetDefRefreshAttributesEditor refreshEditor; @Mock protected DataSetClientServices clientServices; @Mock protected LoadingBox loadingBox; @Mock protected EventSourceMock errorEvent; @Mock protected EventSourceMock tabChangedEvent; @Mock protected DataSetEditor.View view; @Mock protected DataSetDefFilterEditor filterEditor; @Mock protected org.dashbuilder.dataset.client.editor.DataSetDefColumnsEditor columnsEditor; @Mock protected ColumnListEditor columnListEditor; @Mock protected DataSetDef dataSetDef; private DataSetEditor presenter; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); IsWidget attributesEditor = mock(IsWidget.class); presenter = new DataSetEditor(basicAttributesEditor, attributesEditor, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view) { @Override public void init() { super.init(); } }; when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); when(columnsAndFilterEditor.dataSetFilter()).thenReturn(filterEditor); when(columnsAndFilterEditor.columnListEditor()).thenReturn(columnsEditor); when(columnsEditor.columns()).thenReturn(columnListEditor); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).initWidgets( any(), any(), any(), any(), any(), any(), any() ); verify(view, times(1)).addConfigurationTabItemClickHandler(any(Command.class)); verify(view, times(1)).addPreviewTabItemClickHandler(any(Command.class)); verify(view, times(1)).addAdvancedTabItemClickHandler(any(Command.class)); verify(columnsAndFilterEditor, times(1)).setMaxHeight(anyString()); verify(backendCacheAttributesEditor, times(1)).setRange(anyDouble(), anyDouble()); verify(clientCacheAttributesEditor, times(1)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).showConfigurationTab(); verify(view, times(0)).showPreviewTab(); verify(view, times(0)).showAdvancedTab(); verify(view, times(0)).openColumnsFilterPanel(anyString()); verify(view, times(0)).closeColumnsFilterPanel(anyString()); verify(view, times(0)).showErrorNotification(any(SafeHtml.class)); verify(view, times(0)).clearErrorNotification(); } @Test public void testShowConfigurationTab() { presenter.showConfigurationTab(); presenter.afterPreviewCommand.execute(); verify(view, times(1)).showConfigurationTab(); verify(view, times(0)).showPreviewTab(); verify(view, times(0)).showAdvancedTab(); } @Test public void testShowPreviewTab() { presenter.showPreviewTab(); presenter.afterPreviewCommand.execute(); verify(view, times(1)).showPreviewTab(); verify(view, times(0)).showConfigurationTab(); verify(view, times(0)).showAdvancedTab(); } @Test public void testShowAdvTab() { presenter.showAdvancedTab(); presenter.afterPreviewCommand.execute(); verify(view, times(1)).showAdvancedTab(); verify(view, times(0)).showConfigurationTab(); verify(view, times(0)).showPreviewTab(); } @Test public void testSetAcceptableValues() { List acceptableValues = mock(List.class); presenter.setAcceptableValues(acceptableValues); verify(columnsAndFilterEditor, times(1)).setAcceptableValues(acceptableValues); assertViewNotUsed(); } @Test public void testBasicAttributesEditor() { assertEquals(basicAttributesEditor, presenter.basicAttributesEditor()); assertViewNotUsed(); } @Test public void testColumnsAndFilterEditor() { assertEquals(columnsAndFilterEditor, presenter.columnsAndFilterEditor()); assertViewNotUsed(); } @Test public void testBackendCacheEditor() { assertEquals(backendCacheAttributesEditor, presenter.backendCacheEditor()); assertViewNotUsed(); } @Test public void testClientCacheEditor() { assertEquals(clientCacheAttributesEditor, presenter.clientCacheEditor()); assertViewNotUsed(); } @Test public void testRefreshEditor() { assertEquals(refreshEditor, presenter.refreshEditor()); assertViewNotUsed(); } @Test public void testOnOpenColumnsFilterPanel() { presenter.onOpenColumnsFilterPanel(); verify(view, times(1)).openColumnsFilterPanel(anyString()); } @Test public void testOnCloseColumnsFilterPanel() { presenter.onCloseColumnsFilterPanel(); verify(view, times(1)).closeColumnsFilterPanel(anyString()); } @Test public void testConfigurationTabItemClickHandler() { presenter.configurationTabItemClickHandler.execute(); final ArgumentCaptor tabChangedEventCaptor = ArgumentCaptor.forClass(TabChangedEvent.class); verify(tabChangedEvent, times(1)).fire(tabChangedEventCaptor.capture()); final TabChangedEvent tabChangedEvent = tabChangedEventCaptor.getValue(); assertEquals(presenter, tabChangedEvent.getContext()); assertEquals(DataSetEditor.TAB_CONFIGURATION, tabChangedEvent.getTabId()); assertViewNotUsed(); } @Test public void testPreviewTabItemClickHandler() { presenter.previewTabItemClickHandler.execute(); final ArgumentCaptor tabChangedEventCaptor = ArgumentCaptor.forClass(TabChangedEvent.class); verify(tabChangedEvent, times(1)).fire(tabChangedEventCaptor.capture()); final TabChangedEvent tabChangedEvent = tabChangedEventCaptor.getValue(); assertEquals(presenter, tabChangedEvent.getContext()); assertEquals(DataSetEditor.TAB_PREVIEW, tabChangedEvent.getTabId()); assertViewNotUsed(); } @Test public void testAdvTabItemClickHandler() { presenter.advancedTabItemClickHandler.execute(); final ArgumentCaptor tabChangedEventCaptor = ArgumentCaptor.forClass(TabChangedEvent.class); verify(tabChangedEvent, times(1)).fire(tabChangedEventCaptor.capture()); final TabChangedEvent tabChangedEvent = tabChangedEventCaptor.getValue(); assertEquals(presenter, tabChangedEvent.getContext()); assertEquals(DataSetEditor.TAB_ADVANCED, tabChangedEvent.getTabId()); assertViewNotUsed(); } @Test public void testShowError() { final ClientRuntimeError error = mock(ClientRuntimeError.class); when(error.getCause()).thenReturn("errorCause"); presenter.afterPreviewCommand = mock(Command.class); presenter.showError(error); verify(loadingBox, times(1)).hide(); verify(view, times(1)).showErrorNotification(any(SafeHtml.class)); verify(errorEvent, times(1)).fire(any(ErrorEvent.class)); verify(presenter.afterPreviewCommand, times(1)).execute(); verify(view, times(0)).addConfigurationTabItemClickHandler(any(Command.class)); verify(view, times(0)).addPreviewTabItemClickHandler(any(Command.class)); verify(view, times(0)).addAdvancedTabItemClickHandler(any(Command.class)); verify(view, times(0)).showConfigurationTab(); verify(view, times(0)).showPreviewTab(); verify(view, times(0)).showAdvancedTab(); verify(view, times(0)).openColumnsFilterPanel(anyString()); verify(view, times(0)).closeColumnsFilterPanel(anyString()); verify(view, times(0)).clearErrorNotification(); } @Test public void testOnColumnsChangedEvent() { final DataColumnDef col1 = mock(DataColumnDef.class); when(col1.getId()).thenReturn("col1"); when(col1.getColumnType()).thenReturn(ColumnType.LABEL); final DataColumnDef col2 = mock(DataColumnDef.class); when(col2.getId()).thenReturn("col2"); when(col2.getColumnType()).thenReturn(ColumnType.NUMBER); final List cols = new ArrayList(); cols.add(col1); cols.add(col2); final ColumnsChangedEvent event = mock(ColumnsChangedEvent.class); when(event.getContext()).thenReturn(columnListEditor); when(event.getColumns()).thenReturn(cols); presenter.dataSetDef = this.dataSetDef; mockPreviewTableCall(); final Command afterPreviewCommand = mock(Command.class); presenter.afterPreviewCommand = afterPreviewCommand; presenter.onColumnsChangedEvent(event); verify(dataSetDef, times(1)).setColumns(cols); verify(loadingBox, times(1)).show(); verify(loadingBox, times(1)).hide(); verify(view, times(1)).clearErrorNotification(); verify(filterEditor, times(1)).init(any()); verify(afterPreviewCommand, times(1)).execute(); verify(view, times(0)).init(any(DataSetEditor.class)); verify(view, times(0)).initWidgets( any(DataSetDefBasicAttributesEditor.View.class), any(IsWidget.class), any(DataSetDefColumnsFilterEditor.View.class), any(DataSetDefPreviewTable.View.class), any(DataSetDefCacheAttributesEditorView.class), any(DataSetDefCacheAttributesEditorView.class), any(DataSetDefRefreshAttributesEditor.View.class) ); verify(view, times(0)).addConfigurationTabItemClickHandler(any(Command.class)); verify(view, times(0)).addPreviewTabItemClickHandler(any(Command.class)); verify(view, times(0)).addAdvancedTabItemClickHandler(any(Command.class)); verify(view, times(0)).showConfigurationTab(); verify(view, times(0)).showPreviewTab(); verify(view, times(0)).showAdvancedTab(); verify(view, times(0)).openColumnsFilterPanel(anyString()); verify(view, times(0)).closeColumnsFilterPanel(anyString()); verify(view, times(0)).showErrorNotification(any(SafeHtml.class)); } @Test public void testOnFilterChangedEvent() { final FilterChangedEvent event = mock(FilterChangedEvent.class); final DataSetFilter filter = mock(DataSetFilter.class); when(event.getContext()).thenReturn(filterEditor); when(event.getFilter()).thenReturn(filter); presenter.dataSetDef = this.dataSetDef; mockPreviewTableCall(); final Command afterPreviewCommand = mock(Command.class); presenter.afterPreviewCommand = afterPreviewCommand; presenter.onFilterChangedEvent(event); verify(dataSetDef, times(1)).setDataSetFilter(filter); verify(loadingBox, times(1)).show(); verify(loadingBox, times(1)).hide(); verify(view, times(1)).clearErrorNotification(); verify(filterEditor, times(0)).init(any(DataSetMetadata.class)); verify(afterPreviewCommand, times(1)).execute(); verify(view, times(0)).init(any(DataSetEditor.class)); verify(view, times(0)).initWidgets( any(DataSetDefBasicAttributesEditor.View.class), any(IsWidget.class), any(DataSetDefColumnsFilterEditor.View.class), any(DataSetDefPreviewTable.View.class), any(DataSetDefCacheAttributesEditorView.class), any(DataSetDefCacheAttributesEditorView.class), any(DataSetDefRefreshAttributesEditor.View.class) ); verify(view, times(0)).addConfigurationTabItemClickHandler(any(Command.class)); verify(view, times(0)).addPreviewTabItemClickHandler(any(Command.class)); verify(view, times(0)).addAdvancedTabItemClickHandler(any(Command.class)); verify(view, times(0)).showConfigurationTab(); verify(view, times(0)).showPreviewTab(); verify(view, times(0)).showAdvancedTab(); verify(view, times(0)).openColumnsFilterPanel(anyString()); verify(view, times(0)).closeColumnsFilterPanel(anyString()); verify(view, times(0)).showErrorNotification(any(SafeHtml.class)); } protected void mockPreviewTableCall() { final Displayer displayer = mock(Displayer.class); final DataSetHandler dataSetHandler = mock(DataSetHandler.class); final DataSet dataSet = mock(DataSet.class); when(displayer.getDataSetHandler()).thenReturn(dataSetHandler); when(dataSetHandler.getLastDataSet()).thenReturn(dataSet); doAnswer(new Answer() { @Override public Void answer(final InvocationOnMock invocationOnMock) throws Throwable { DisplayerListener listener = (DisplayerListener) invocationOnMock.getArguments()[2]; listener.onDraw(displayer); return null; } }).when(previewTable).show(any(DataSetDef.class), any(Collection.class), any(DisplayerListener.class)); } protected void assertViewNotUsed() { verify(view, times(0)).init(any(DataSetEditor.class)); verify(view, times(0)).initWidgets( any(DataSetDefBasicAttributesEditor.View.class), any(IsWidget.class), any(DataSetDefColumnsFilterEditor.View.class), any(DataSetDefPreviewTable.View.class), any(DataSetDefCacheAttributesEditorView.class), any(DataSetDefCacheAttributesEditorView.class), any(DataSetDefRefreshAttributesEditor.View.class) ); verify(view, times(0)).addConfigurationTabItemClickHandler(any(Command.class)); verify(view, times(0)).addPreviewTabItemClickHandler(any(Command.class)); verify(view, times(0)).addAdvancedTabItemClickHandler(any(Command.class)); verify(view, times(0)).showConfigurationTab(); verify(view, times(0)).showPreviewTab(); verify(view, times(0)).showAdvancedTab(); verify(view, times(0)).openColumnsFilterPanel(anyString()); verify(view, times(0)).closeColumnsFilterPanel(anyString()); verify(view, times(0)).showErrorNotification(any(SafeHtml.class)); verify(view, times(0)).clearErrorNotification(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefBackendCacheAttributesEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.ToggleSwitchEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyDouble; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefBackendCacheAttributesEditorTest { @Mock ToggleSwitchEditor cacheEnabled; @Mock ValueBoxEditor cacheMaxRows; @Mock DataSetDefCacheAttributesEditorView view; private DataSetDefBackendCacheAttributesEditor presenter; @Before public void setup() { presenter = new DataSetDefBackendCacheAttributesEditor(cacheEnabled, cacheMaxRows, view); } @Test public void testInit() { presenter.init(); verify(cacheMaxRows, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(1)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(1)).init(anyString(), anyString(), any(), any()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).setValue(anyDouble()); verify(view, times(0)).setEnabled(anyBoolean()); } @Test public void testSetRange() { presenter.setRange(1d, 2d); verify(view, times(1)).setRange(1d, 2d); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); verify(view, times(0)).setEnabled(anyBoolean()); } @Test public void testCacheEnabled() { assertEquals(cacheEnabled, presenter.cacheEnabled()); } @Test public void testCacheMaxRows() { assertEquals(cacheMaxRows, presenter.cacheMaxRows()); } @Test public void testSetValueEnabled() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.isCacheEnabled()).thenReturn(true); presenter.setValue(dataSetDef); verify(view, times(1)).setEnabled(true); verify(view, times(1)).setValue(anyDouble()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); } @Test public void testSetValueDisabled() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.isCacheEnabled()).thenReturn(false); presenter.setValue(dataSetDef); verify(view, times(1)).setEnabled(false); verify(view, times(1)).setValue(anyDouble()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); } @Test public void testViewCallback() { final Double value = 1d; presenter.viewCallback.onValueChange(value); verify(cacheMaxRows, times(1)).setValue(anyInt()); verify(cacheEnabled, times(0)).setValue(anyBoolean()); verify(view, times(0)).setEnabled(anyBoolean()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } @Test public void testViewCallbackNullified() { final Double value = null; presenter.viewCallback.onValueChange(value); verify(cacheMaxRows, times(1)).setValue(100); verify(cacheEnabled, times(0)).setValue(anyBoolean()); verify(view, times(0)).setEnabled(anyBoolean()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } public void testOnEnabledChangedEventUsingTrue() { final ValueChangeEvent event = mock(ValueChangeEvent.class); when(event.getContext()).thenReturn(cacheEnabled); when(event.getValue()).thenReturn(true); presenter.onEnabledChangedEvent(event); verify(view, times(1)).setEnabled(true); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } public void testOnEnabledChangedEventUsingFalse() { final ValueChangeEvent event = mock(ValueChangeEvent.class); when(event.getContext()).thenReturn(cacheEnabled); when(event.getValue()).thenReturn(false); presenter.onEnabledChangedEvent(event); verify(view, times(1)).setEnabled(false); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefBasicAttributesEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefBasicAttributesEditorTest { @Mock ValueBoxEditor uuidEditor; @Mock ValueBoxEditor nameEditor; @Mock DataSetDefBasicAttributesEditor.View view; private DataSetDefBasicAttributesEditor presenter; @Before public void setup() { presenter = new DataSetDefBasicAttributesEditor(uuidEditor, nameEditor, view); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).initWidgets(any(), any()); verify(uuidEditor, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(nameEditor, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); } @Test public void testUUID() { assertEquals(uuidEditor, presenter.UUID()); } @Test public void testName() { assertEquals(nameEditor, presenter.name()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefClientCacheAttributesEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.ToggleSwitchEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyDouble; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefClientCacheAttributesEditorTest { @Mock ToggleSwitchEditor pushEnabled; @Mock ValueBoxEditor pushMaxSize; @Mock DataSetDefCacheAttributesEditorView view; private DataSetDefClientCacheAttributesEditor presenter; @Before public void setup() { presenter = new DataSetDefClientCacheAttributesEditor(pushEnabled, pushMaxSize, view); } @Test public void testInit() { presenter.init(); verify(pushMaxSize, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(1)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(1)).init(anyString(), anyString(), any(), any()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).setValue(anyDouble()); verify(view, times(0)).setEnabled(anyBoolean()); } @Test public void testSetRange() { presenter.setRange(1d, 2d); verify(view, times(1)).setRange(1d, 2d); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); verify(view, times(0)).setEnabled(anyBoolean()); } @Test public void testPushEnabled() { assertEquals(pushEnabled, presenter.pushEnabled()); } @Test public void testPushMaxSize() { assertEquals(pushMaxSize, presenter.pushMaxSize()); } @Test public void testSetValueEnabled() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.isPushEnabled()).thenReturn(true); presenter.setValue(dataSetDef); verify(view, times(1)).setEnabled(true); verify(view, times(1)).setValue(anyDouble()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); } @Test public void testSetValueDisabled() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.isPushEnabled()).thenReturn(false); presenter.setValue(dataSetDef); verify(view, times(1)).setEnabled(false); verify(view, times(1)).setValue(anyDouble()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); } @Test public void testViewCallback() { final Double value = 1d; presenter.viewCallback.onValueChange(value); verify(pushMaxSize, times(1)).setValue(anyInt()); verify(pushEnabled, times(0)).setValue(anyBoolean()); verify(view, times(0)).setEnabled(anyBoolean()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } @Test public void testViewCallbackNullified() { final Double value = null; presenter.viewCallback.onValueChange(value); verify(pushMaxSize, times(1)).setValue(100); verify(pushEnabled, times(0)).setValue(anyBoolean()); verify(view, times(0)).setEnabled(anyBoolean()); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } public void testOnEnabledChangedEventUsingTrue() { final ValueChangeEvent event = mock(ValueChangeEvent.class); when(event.getContext()).thenReturn(pushEnabled); when(event.getValue()).thenReturn(true); presenter.onEnabledChangedEvent(event); verify(view, times(1)).setEnabled(true); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } public void testOnEnabledChangedEventUsingFalse() { final ValueChangeEvent event = mock(ValueChangeEvent.class); when(event.getContext()).thenReturn(pushEnabled); when(event.getValue()).thenReturn(false); presenter.onEnabledChangedEvent(event); verify(view, times(1)).setEnabled(false); verify(view, times(0)).setRange(anyDouble(), anyDouble()); verify(view, times(0)).init(anyString(), anyString(), any(IsWidget.class), any(ValueBoxEditor.View.class)); verify(view, times(0)).init(any(DataSetDefCacheAttributesEditorView.ViewCallback.class)); verify(view, times(0)).setValue(anyDouble()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefRefreshAttributesEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.ToggleSwitchEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mvp.Command; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefRefreshAttributesEditorTest { @Mock ToggleSwitchEditor refreshAlways; @Mock DataSetDefRefreshIntervalEditor refreshTime; @Mock DataSetDefRefreshAttributesEditor.View view; private DataSetDefRefreshAttributesEditor presenter; @Before public void setup() { presenter = new DataSetDefRefreshAttributesEditor(refreshAlways, refreshTime, view); } @Test public void testInit() { presenter.init(); verify(refreshTime, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(1)).init(presenter); verify(view, times(1)).initWidgets(any(), any()); verify(view, times(1)).addRefreshEnabledButtonHandler(any(Command.class)); verify(view, times(0)).setEnabled(anyBoolean()); } @Test public void testRefreshAlways() { assertEquals(refreshAlways, presenter.refreshAlways()); } @Test public void testRefreshTime() { assertEquals(refreshTime, presenter.refreshTime()); } @Test public void testRefreshEnabledButtonHandlerDisabled() { presenter.isRefreshEnabled = false; presenter.refreshEnabledButtonHandler.execute(); assertEquals(true, presenter.isRefreshEnabled()); verify(refreshTime, times(1)).setEnabled(true); verify(refreshAlways, times(1)).setEnabled(true); verify(view, times(1)).setEnabled(true); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefRefreshIntervalEditor.View.class)); verify(view, times(0)).addRefreshEnabledButtonHandler(any(Command.class)); } @Test public void testRefreshEnabledButtonHandlerEnabled() { presenter.isRefreshEnabled = true; presenter.refreshEnabledButtonHandler.execute(); assertEquals(false, presenter.isRefreshEnabled()); verify(refreshTime, times(1)).setEnabled(false); verify(refreshAlways, times(1)).setEnabled(false); verify(view, times(1)).setEnabled(false); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefRefreshIntervalEditor.View.class)); verify(view, times(0)).addRefreshEnabledButtonHandler(any(Command.class)); } @Test public void testSetValueEnabled() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.getRefreshTime()).thenReturn("1 second"); presenter.setValue(dataSetDef); assertEquals(true, presenter.isRefreshEnabled()); verify(refreshTime, times(1)).setEnabled(true); verify(refreshAlways, times(1)).setEnabled(true); verify(view, times(1)).setEnabled(true); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefRefreshIntervalEditor.View.class)); verify(view, times(0)).addRefreshEnabledButtonHandler(any(Command.class)); } @Test public void testSetValueDisabled() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.getRefreshTime()).thenReturn(null); presenter.setValue(dataSetDef); assertEquals(false, presenter.isRefreshEnabled()); verify(refreshTime, times(1)).setEnabled(false); verify(refreshAlways, times(1)).setEnabled(false); verify(view, times(1)).setEnabled(false); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(IsWidget.class), any(DataSetDefRefreshIntervalEditor.View.class)); verify(view, times(0)).addRefreshEnabledButtonHandler(any(Command.class)); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/attributes/DataSetDefRefreshIntervalEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.attributes; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.event.ValueChangeEvent; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyDouble; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetDefRefreshIntervalEditorTest { @Mock EventSourceMock> valueChangeEvent; @Mock DataSetDefRefreshIntervalEditor.View view; private DataSetDefRefreshIntervalEditor presenter; @Before public void setup() { presenter = new DataSetDefRefreshIntervalEditor(view, valueChangeEvent); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(6)).addIntervalTypeItem(anyString()); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).setSelectedIntervalType(anyInt()); verify(view, times(0)).getSelectedIntervalTypeIndex(); verify(view, times(0)).setQuantity(anyDouble()); verify(view, times(0)).getQuantity(); verify(view, times(0)).setEnabled(anyBoolean()); } @Test public void testAddHelpContent() { final Placement p = mock(Placement.class); presenter.addHelpContent("t1", "c1", p); verify(view, times(1)).addHelpContent("t1", "c1", p); verify(view, times(0)).init(presenter); verify(view, times(0)).addIntervalTypeItem(anyString()); verify(view, times(0)).setSelectedIntervalType(anyInt()); verify(view, times(0)).getSelectedIntervalTypeIndex(); verify(view, times(0)).setQuantity(anyDouble()); verify(view, times(0)).getQuantity(); verify(view, times(0)).setEnabled(anyBoolean()); } @Test public void testSetEnabled() { presenter.setEnabled(true); verify(view, times(1)).setEnabled(true); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).addIntervalTypeItem(anyString()); verify(view, times(0)).setSelectedIntervalType(anyInt()); verify(view, times(0)).getSelectedIntervalTypeIndex(); verify(view, times(0)).setQuantity(anyDouble()); verify(view, times(0)).getQuantity(); } @Test public void testSetDisabled() { presenter.setEnabled(false); verify(view, times(1)).setEnabled(false); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).addIntervalTypeItem(anyString()); verify(view, times(0)).setSelectedIntervalType(anyInt()); verify(view, times(0)).getSelectedIntervalTypeIndex(); verify(view, times(0)).setQuantity(anyDouble()); verify(view, times(0)).getQuantity(); } @Test public void testSetValue() { final String value = "1second"; presenter.setValue(value); verify(view, times(1)).setQuantity(1d); verify(view, times(1)).setSelectedIntervalType(anyInt()); verify(view, times(0)).setEnabled(anyBoolean()); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).addIntervalTypeItem(anyString()); verify(view, times(0)).getSelectedIntervalTypeIndex(); verify(view, times(0)).getQuantity(); } @Test public void testSetAnotherValue() { final String value = "10minute"; presenter.setValue(value); verify(view, times(1)).setQuantity(10d); verify(view, times(1)).setSelectedIntervalType(anyInt()); verify(view, times(0)).setEnabled(anyBoolean()); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).addIntervalTypeItem(anyString()); verify(view, times(0)).getSelectedIntervalTypeIndex(); verify(view, times(0)).getQuantity(); } @Test public void testGetValue() { when(view.getQuantity()).thenReturn(1d); when(view.getSelectedIntervalTypeIndex()).thenReturn(0); final String value = presenter.getValue(); assertEquals("1 second", value); verify(view, times(1)).getQuantity(); verify(view, times(1)).getSelectedIntervalTypeIndex(); verify(view, times(0)).setQuantity(10d); verify(view, times(0)).setSelectedIntervalType(anyInt()); verify(view, times(0)).setEnabled(anyBoolean()); verify(view, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).addIntervalTypeItem(anyString()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/bean/BeanDataSetDefAttributesEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.bean; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.map.MapEditor; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class BeanDataSetDefAttributesEditorTest { @Mock ValueBoxEditor generatorClass; @Mock MapEditor paramaterMap; @Mock BeanDataSetDefAttributesEditor.View view; private BeanDataSetDefAttributesEditor presenter; @Before public void setup() { presenter = new BeanDataSetDefAttributesEditor(generatorClass, paramaterMap, view); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).initWidgets(any(), any()); verify(generatorClass, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); } @Test public void testGeneratorClass() { assertEquals(generatorClass, presenter.generatorClass()); } @Test public void testParameterMap() { assertEquals(paramaterMap, presenter.paramaterMap()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/bean/BeanDataSetEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.bean; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class BeanDataSetEditorTest { @Mock protected DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock protected DataSetDefColumnsFilterEditor columnsAndFilterEditor; @Mock protected DataSetDefPreviewTable previewTable; @Mock protected DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor; @Mock protected DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor; @Mock protected DataSetDefRefreshAttributesEditor refreshEditor; @Mock protected DataSetClientServices clientServices; @Mock protected LoadingBox loadingBox; @Mock protected EventSourceMock errorEvent; @Mock protected EventSourceMock tabChangedEvent; @Mock protected DataSetEditor.View view; @Mock protected BeanDataSetDef dataSetDef; @Mock BeanDataSetDefAttributesEditor attributesEditor; BeanDataSetEditor presenter; @Before public void setup() throws Exception { this.presenter = new BeanDataSetEditor(basicAttributesEditor, attributesEditor, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); } @Test public void testGeneratorClass() { assertEquals(attributesEditor.generatorClass, presenter.generatorClass()); } @Test public void testParameterMap() { assertEquals(attributesEditor.paramaterMap, presenter.paramaterMap()); } /* Bean types does not support backend cache attributes edition. */ @Test public void testSetValue() { presenter.setValue(dataSetDef); assertNull(presenter.backendCacheEditor()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/column/ColumnListEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.editor.client.CompositeEditor; import com.google.gwt.editor.client.EditorDelegate; import com.google.gwt.editor.client.adapters.ListEditor; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.driver.DataColumnDefDriver; import org.dashbuilder.client.widgets.dataset.event.ColumnsChangedEvent; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.def.DataColumnDef; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.mocks.EventSourceMock; import java.util.ArrayList; import java.util.List; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class ColumnListEditorTest { @Mock SyncBeanManager beanManager; @Mock DataColumnDefDriver dataColumnDefDriver; @Mock EventSourceMock columnsChangedEvent; @Mock ColumnListEditor.View view; @Mock SyncBeanDef columnDefEditorSyncBeanDef; @Mock DataColumnDefEditor dataColumnDefEditor; private ColumnListEditor presenter; final ListEditor listEditor = mock(ListEditor.class); @Mock DataColumnDef col1; @Before public void setup() { presenter = new ColumnListEditor(beanManager, dataColumnDefDriver, columnsChangedEvent, view); // Bean instantiation mocks. when(beanManager.lookupBean(DataColumnDefEditor.class)).thenReturn(columnDefEditorSyncBeanDef); when( columnDefEditorSyncBeanDef.newInstance() ).thenAnswer( new Answer() { @Override public DataColumnDefEditor answer( InvocationOnMock invocationOnMock ) throws Throwable { return dataColumnDefEditor; } } ); // Acceptable values. when(col1.getId()).thenReturn("col1"); when(col1.getColumnType()).thenReturn(ColumnType.LABEL); final List acceptableValues = buildAcceptableValues(); presenter.acceptableColumns = acceptableValues; // Column Editors. final ValueBoxEditor id = mock(ValueBoxEditor.class); when(id.getValue()).thenReturn("col1"); when(dataColumnDefEditor.id()).thenReturn(id); final List editors = new ArrayList(); final List columns = new ArrayList(); columns.add(col1); editors.add(dataColumnDefEditor); when(listEditor.getEditors()).thenReturn(editors); when(listEditor.getList()).thenReturn(columns); presenter.listEditor = listEditor; } @Test public void testInit() { presenter.init(); assertNotNull(presenter.listEditor); verify(view, times(1)).init(presenter); verify(view, times(0)).insert(anyInt(), any(DataColumnDefEditor.View.class), anyBoolean(), anyBoolean(), anyString()); verify(view, times(0)).remove(anyInt()); verify(view, times(0)).clear(); } @Test public void testClear() { presenter.clear(); assertNull(presenter.acceptableColumns); verify(view, times(1)).clear(); verify(view, times(0)).init(presenter); verify(view, times(0)).insert(anyInt(), any(DataColumnDefEditor.View.class), anyBoolean(), anyBoolean(), anyString()); verify(view, times(0)).remove(anyInt()); } @Test public void testSetAcceptableValues() { final List acceptableValues = buildAcceptableValues(); presenter.setAcceptableValues(acceptableValues); verify(dataColumnDefEditor, times(1)).isEditMode(false); verify(dataColumnDefDriver, times(1)).initialize(dataColumnDefEditor); verify(dataColumnDefDriver, times(1)).edit(col1); verify(view, times(1)).clear(); verify(view, times(1)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), any()); verify(view, times(0)).init(presenter); verify(view, times(0)).remove(anyInt()); } @Test public void testOnValueRestricted() { final String value = "col1"; presenter.restrictedColumns.clear(); presenter.onValueRestricted(value); assertEquals(1, presenter.restrictedColumns.size()); assertEquals("col1", presenter.restrictedColumns.get(0)); verify(dataColumnDefEditor, times(1)).isEditMode(false); verify(view, times(1)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), anyString()); verify(view, times(1)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } /** * Column editor editMode set to false, as only one column present in the dset definition, so it cannot be unselected. */ @Test public void testOnValueUnRestrictedSingleColumn() { final String value = "col1"; presenter.restrictedColumns.add("col1"); presenter.onValueUnRestricted(value); assertTrue(presenter.restrictedColumns.isEmpty()); verify(dataColumnDefEditor, times(1)).isEditMode(false); verify(view, times(1)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), anyString()); verify(view, times(1)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } /** * Column editor editMode set to true, as more than one column present in the dset definition, so it can be selected/unselected. */ @Test public void testOnValueUnRestricted() { final String value = "col1"; presenter.restrictedColumns.add("col1"); final DataColumnDef col2 = mock(DataColumnDef.class); when(col2.getId()).thenReturn("col2"); when(col2.getColumnType()).thenReturn(ColumnType.LABEL); presenter.listEditor.getList().add(col2); presenter.onValueUnRestricted(value); assertTrue(presenter.restrictedColumns.isEmpty()); verify(dataColumnDefEditor, times(1)).isEditMode(true); verify(view, times(1)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), any()); verify(view, times(1)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } @Test public void testCreateEditorForTraversal() { presenter.createEditorForTraversal(); verify(listEditor, times(1)).createEditorForTraversal(); verify(listEditor, times(0)).getPathElement(any(DataColumnDefEditor.class)); verify(listEditor, times(0)).setEditorChain(any(CompositeEditor.EditorChain.class)); verify(listEditor, times(0)).setDelegate(any(EditorDelegate.class)); verify(listEditor, times(0)).flush(); verify(listEditor, times(0)).onPropertyChange(anyString()); verify(listEditor, times(0)).setValue(any(List.class)); } @Test public void testGetPathElement() { presenter.getPathElement(dataColumnDefEditor); verify(listEditor, times(1)).getPathElement(dataColumnDefEditor); verify(listEditor, times(0)).createEditorForTraversal(); verify(listEditor, times(0)).setEditorChain(any(CompositeEditor.EditorChain.class)); verify(listEditor, times(0)).setDelegate(any(EditorDelegate.class)); verify(listEditor, times(0)).flush(); verify(listEditor, times(0)).onPropertyChange(anyString()); verify(listEditor, times(0)).setValue(any(List.class)); } @Test public void testSetEditorChain() { final CompositeEditor.EditorChain chain = mock(CompositeEditor.EditorChain.class); presenter.setEditorChain(chain); verify(listEditor, times(1)).setEditorChain(chain); verify(listEditor, times(0)).createEditorForTraversal(); verify(listEditor, times(0)).getPathElement(any(DataColumnDefEditor.class)); verify(listEditor, times(0)).setDelegate(any(EditorDelegate.class)); verify(listEditor, times(0)).flush(); verify(listEditor, times(0)).onPropertyChange(anyString()); verify(listEditor, times(0)).setValue(any(List.class)); } @Test public void testSetDelegate() { final EditorDelegate> delegate = mock(EditorDelegate.class); presenter.setDelegate(delegate); verify(listEditor, times(1)).setDelegate(delegate); verify(listEditor, times(0)).createEditorForTraversal(); verify(listEditor, times(0)).getPathElement(any(DataColumnDefEditor.class)); verify(listEditor, times(0)).setEditorChain(any(CompositeEditor.EditorChain.class)); verify(listEditor, times(0)).flush(); verify(listEditor, times(0)).onPropertyChange(anyString()); verify(listEditor, times(0)).setValue(any(List.class)); } @Test public void testFlush() { presenter.flush(); verify(listEditor, times(1)).flush(); verify(listEditor, times(0)).createEditorForTraversal(); verify(listEditor, times(0)).getPathElement(any(DataColumnDefEditor.class)); verify(listEditor, times(0)).setEditorChain(any(CompositeEditor.EditorChain.class)); verify(listEditor, times(0)).setDelegate(any(EditorDelegate.class)); verify(listEditor, times(0)).onPropertyChange(anyString()); verify(listEditor, times(0)).setValue(any(List.class)); } @Test public void testOnPropertyChange() { final String s = "prop1"; presenter.onPropertyChange(s); verify(listEditor, times(1)).onPropertyChange(s); verify(listEditor, times(0)).createEditorForTraversal(); verify(listEditor, times(0)).getPathElement(any(DataColumnDefEditor.class)); verify(listEditor, times(0)).setEditorChain(any(CompositeEditor.EditorChain.class)); verify(listEditor, times(0)).setDelegate(any(EditorDelegate.class)); verify(listEditor, times(0)).flush(); verify(listEditor, times(0)).setValue(any(List.class)); } @Test public void testSetValue() { final List value = mock(List.class); presenter.setValue(value); verify(listEditor, times(1)).setValue(value); verify(listEditor, times(0)).createEditorForTraversal(); verify(listEditor, times(0)).getPathElement(any(DataColumnDefEditor.class)); verify(listEditor, times(0)).setEditorChain(any(CompositeEditor.EditorChain.class)); verify(listEditor, times(0)).setDelegate(any(EditorDelegate.class)); verify(listEditor, times(0)).flush(); verify(listEditor, times(0)).onPropertyChange(anyString()); } @Test public void testSetProviderType() { DataSetProviderType type = mock(DataSetProviderType.class); presenter.setProviderType(type); assertEquals(type, presenter.providerType); } @Test public void testOnColumnSelected() { listEditor.getList().clear(); when(col1.clone()).thenReturn(col1); presenter.onColumnSelect(0, true); assertEquals(1, listEditor.getList().size()); assertEquals(col1, listEditor.getList().get(0)); verify(columnsChangedEvent, times(1)).fire(any(ColumnsChangedEvent.class)); } @Test public void testOnColumnUnSelected() { when(col1.clone()).thenReturn(col1); presenter.onColumnSelect(0, false); assertTrue(listEditor.getList().isEmpty()); verify(columnsChangedEvent, times(1)).fire(any(ColumnsChangedEvent.class)); } /** * Column editor created with editMode set to false, as only one column present in the dset definition, so it cannot be unselected. */ @Test public void testDataColumnDefEditorSource_Create() { ColumnListEditor.DataColumnDefEditorSource source = presenter.createDataColumnDefEditorSource(); org.dashbuilder.dataset.client.editor.DataColumnDefEditor e = source.create(0); verify(dataColumnDefEditor, times(2)).isEditMode(false); verify(dataColumnDefEditor, times(1)).setProviderType(any()); verify(dataColumnDefEditor, times(1)).setOriginalColumnType(any(ColumnType.class)); verify(view, times(2)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), anyString()); verify(view, times(2)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } /** * Column editor created with editMode set to true, as more than one column present in the dset definition. First column enabled too, as it was disabled as was the unique one before this creation. */ @Test public void testDataColumnDefEditorSource_CreateMultiple() { final DataColumnDef col2 = mock(DataColumnDef.class); when(col2.getId()).thenReturn("col2"); when(col2.getColumnType()).thenReturn(ColumnType.LABEL); presenter.acceptableColumns.add(col2); presenter.listEditor.getList().add(col2); presenter.restrictedColumns.clear(); ColumnListEditor.DataColumnDefEditorSource source = presenter.createDataColumnDefEditorSource(); org.dashbuilder.dataset.client.editor.DataColumnDefEditor e = source.create(0); verify(dataColumnDefEditor, times(2)).isEditMode(true); verify(dataColumnDefEditor, times(1)).setOriginalColumnType(any(ColumnType.class)); verify(dataColumnDefEditor, times(1)).setProviderType(any()); verify(view, times(2)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), any()); verify(view, times(2)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } /** * See https://issues.jboss.org/browse/DASHBUILDE-79 */ @Test public void testDataColumnDefEditorSource_Create_DASHBUILDE79_A() { final DataColumnDef col2 = mock(DataColumnDef.class); when(col2.getId()).thenReturn("col2"); when(col2.getColumnType()).thenReturn(ColumnType.LABEL); presenter.acceptableColumns.add(col2); presenter.listEditor.getList().add(col2); presenter.listEditor.getEditors().clear(); presenter.restrictedColumns.clear(); ColumnListEditor.DataColumnDefEditorSource source = presenter.createDataColumnDefEditorSource(); org.dashbuilder.dataset.client.editor.DataColumnDefEditor e = source.create(0); verify(dataColumnDefEditor, times(1)).isEditMode(true); verify(dataColumnDefEditor, times(1)).setOriginalColumnType(any(ColumnType.class)); verify(dataColumnDefEditor, times(1)).setProviderType(any()); verify(view, times(1)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), any()); verify(view, times(1)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } /** * See https://issues.jboss.org/browse/DASHBUILDE-79 (re-opened) */ @Test public void testDataColumnDefEditorSource_Create_DASHBUILDE79_B() { final DataColumnDef col2 = mock(DataColumnDef.class); when(col2.getId()).thenReturn("col2"); when(col2.getColumnType()).thenReturn(ColumnType.LABEL); presenter.acceptableColumns.add(col2); presenter.listEditor.getList().clear(); presenter.listEditor.getList().add(col2); presenter.listEditor.getEditors().clear(); presenter.restrictedColumns.clear(); ColumnListEditor.DataColumnDefEditorSource source = presenter.createDataColumnDefEditorSource(); org.dashbuilder.dataset.client.editor.DataColumnDefEditor e = source.create(0); verify(dataColumnDefEditor, times(1)).isEditMode(false); verify(dataColumnDefEditor, times(1)).setOriginalColumnType(any(ColumnType.class)); verify(dataColumnDefEditor, times(1)).setProviderType(any()); verify(view, times(1)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), anyString()); verify(view, times(1)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } /** * Ensure create a dummy not editable column when disposing the only one present from the definition. */ @Test public void testDataColumnDefEditorSource_Dispose() { ColumnListEditor.DataColumnDefEditorSource source = presenter.createDataColumnDefEditorSource(); source.dispose(dataColumnDefEditor); verify(dataColumnDefEditor, times(1)).removeFromParent(); verify(dataColumnDefEditor, times(3)).isEditMode(false); verify(dataColumnDefDriver, times(1)).initialize(dataColumnDefEditor); verify(dataColumnDefDriver, times(1)).edit(col1); verify(view, times(2)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), any()); verify(view, times(2)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } /** * Ensure create a dummy not editable column when disposing the only one present from the definition and ensure first column is set to editMode=false, as will be the only one column in the definition. */ @Test public void testDataColumnDefEditorSource_Dispose_UniqueColumn() { final DataColumnDef col2 = mock(DataColumnDef.class); when(col2.getId()).thenReturn("col2"); when(col2.getColumnType()).thenReturn(ColumnType.LABEL); final DataColumnDefEditor col2Editor = mock(DataColumnDefEditor.class); final ValueBoxEditor id2 = mock(ValueBoxEditor.class); when(id2.getValue()).thenReturn("col2"); when(col2Editor.id()).thenReturn(id2); presenter.acceptableColumns.add(col2); presenter.listEditor.getList().add(col2); presenter.listEditor.getEditors().add(col2Editor); when( columnDefEditorSyncBeanDef.newInstance() ).thenAnswer( new Answer() { @Override public DataColumnDefEditor answer( InvocationOnMock invocationOnMock ) throws Throwable { return col2Editor; } } ); ColumnListEditor.DataColumnDefEditorSource source = presenter.createDataColumnDefEditorSource(); source.dispose(col2Editor); verify(dataColumnDefEditor, times(0)).removeFromParent(); verify(dataColumnDefEditor, times(0)).isEditMode(false); verify(col2Editor, times(1)).removeFromParent(); verify(col2Editor, times(2)).isEditMode(false); verify(dataColumnDefDriver, times(1)).initialize(col2Editor); verify(dataColumnDefDriver, times(1)).edit(col2); verify(view, times(1)).insert(anyInt(), any(), anyBoolean(), anyBoolean(), any()); verify(view, times(1)).remove(anyInt()); verify(view, times(0)).init(presenter); verify(view, times(0)).clear(); } protected List buildAcceptableValues() { final List acceptableValues = new ArrayList(); acceptableValues.add(col1); return acceptableValues; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/column/ColumnTypeEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.Widget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.list.DropDownImageListEditor; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.def.DataColumnDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import java.util.Collection; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class ColumnTypeEditorTest { @Mock DropDownImageListEditor columnType; @Mock Widget columnTypeWidget; private ColumnTypeEditor presenter; @Before public void setup() { presenter = spy(new ColumnTypeEditor(columnType)); final SafeUri uri = mock(SafeUri.class); doReturn(uri).when(presenter).getImageUri(any(ColumnType.class)); when(columnType.asWidget()).thenReturn(columnTypeWidget); } @Test public void testAsWidget() { assertEquals(columnTypeWidget, presenter.asWidget()); } @Test public void testInit() { presenter.init(); verify(columnType, times(1)).setImageSize(anyString(), anyString()); verify(columnType, times(1)).setEntries(any(Collection.class)); verify(columnType, times(0)).setHelpContent(anyString(), anyString(), any(Placement.class)); verify(columnType, times(0)).isEditMode(anyBoolean()); } @Test public void testAddHelpContent() { final Placement p = mock(Placement.class); presenter.addHelpContent("t1", "c1", p); verify(columnType, times(1)).setHelpContent("t1", "c1", p); verify(columnType, times(0)).setImageSize(anyString(), anyString()); verify(columnType, times(0)).setEntries(any(Collection.class)); verify(columnType, times(0)).isEditMode(anyBoolean()); } @Test public void testColumnType() { assertEquals(columnType, presenter.columnType()); } @Test public void testEnableEditMode() { presenter.isEditMode(true); verify(columnType, times(1)).isEditMode(true); verify(columnType, times(0)).setHelpContent(anyString(), anyString(), any(Placement.class)); verify(columnType, times(0)).setImageSize(anyString(), anyString()); verify(columnType, times(0)).setEntries(any(Collection.class)); } @Test public void testDisableEditMode() { presenter.isEditMode(false); verify(columnType, times(1)).isEditMode(false); verify(columnType, times(0)).setHelpContent(anyString(), anyString(), any(Placement.class)); verify(columnType, times(0)).setImageSize(anyString(), anyString()); verify(columnType, times(0)).setEntries(any(Collection.class)); } @Test public void testSetValue() { final DataColumnDef col1 = mock(DataColumnDef.class); when(col1.getId()).thenReturn("col1"); when(col1.getColumnType()).thenReturn(ColumnType.LABEL); presenter.setValue(col1); verify(columnType, times(1)).setEntries(any(Collection.class)); verify(columnType, times(0)).isEditMode(anyBoolean()); verify(columnType, times(1)).setHelpContent(anyString(), anyString(), any(Placement.class)); verify(columnType, times(0)).setImageSize(anyString(), anyString()); } @Test public void testSetOriginalColumnType() { ColumnType type = mock(ColumnType.class); presenter.setOriginalColumnType(type); verify(columnType, times(1)).setEntries(any(Collection.class)); verify(columnType, times(0)).isEditMode(anyBoolean()); verify(columnType, times(0)).setHelpContent(anyString(), anyString(), any(Placement.class)); verify(columnType, times(0)).setImageSize(anyString(), anyString()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/column/DataColumnDefEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.column; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataColumnDefEditorTest { @Mock ValueBoxEditor id; @Mock ColumnTypeEditor columnType; @Mock DataColumnDefEditor.View view; @Mock Widget idWidget; private DataColumnDefEditor presenter; @Before public void setup() { presenter = new DataColumnDefEditor(id, columnType, view); presenter.providerType = DataSetProviderType.SQL; when(id.asWidget()).thenReturn(idWidget); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).initWidgets(any(), any()); verify(columnType, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); } @Test public void testRemoveFromParent() { presenter.removeFromParent(); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class)); verify(idWidget, times(1)).removeFromParent(); } @Test public void testEnableEditMode() { presenter.isEditMode(true); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class)); verify(columnType, times(1)).isEditMode(true); } @Test public void testEnableEditModeSpecificForBeanTypes() { presenter.providerType = DataSetProviderType.BEAN; presenter.isEditMode(true); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class)); verify(columnType, times(1)).isEditMode(false); } @Test public void testDisableEditMode() { presenter.isEditMode(false); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class)); verify(columnType, times(1)).isEditMode(false); } @Test public void testSetOriginalColumnType() { ColumnType type = mock(ColumnType.class); presenter.setOriginalColumnType(type); verify(columnType, times(1)).setOriginalColumnType(type); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class)); verify(columnType, times(0)).isEditMode(anyBoolean()); } @Test public void testId() { assertEquals(id, presenter.id()); } @Test public void testColumnType() { assertEquals(columnType, presenter.columnType()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/column/DataSetDefColumnsEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.column; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import java.util.ArrayList; import java.util.List; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DataSetDefColumnsEditorTest { @Mock ColumnListEditor columnListEditor; private DataSetDefColumnsEditor presenter; @Before public void setup() { presenter = new DataSetDefColumnsEditor(columnListEditor); } @Test public void testSetAcceptableValues() { final List acceptableValues = mock(List.class); presenter.setAcceptableValues(acceptableValues); assertEquals(acceptableValues, presenter.acceptableValues); verify(columnListEditor, times(1)).setAcceptableValues(acceptableValues); verify(columnListEditor, times(0)).onValueRestricted(anyString()); verify(columnListEditor, times(0)).onValueUnRestricted(anyString()); verify(columnListEditor, times(0)).setProviderType(any(DataSetProviderType.class)); } @Test public void testOnValueRestricted() { final String v = "value"; presenter.onValueRestricted(v); verify(columnListEditor, times(1)).onValueRestricted(v); verify(columnListEditor, times(0)).onValueUnRestricted(anyString()); verify(columnListEditor, times(0)).setAcceptableValues(any(List.class)); verify(columnListEditor, times(0)).setProviderType(any(DataSetProviderType.class)); } @Test public void testOnValueUnRestricted() { final String v = "value"; presenter.onValueUnRestricted(v); verify(columnListEditor, times(1)).onValueUnRestricted(v); verify(columnListEditor, times(0)).onValueRestricted(anyString()); verify(columnListEditor, times(0)).setAcceptableValues(any(List.class)); verify(columnListEditor, times(0)).setProviderType(any(DataSetProviderType.class)); } @Test public void testSetValueBeanType() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); when(dataSetDef.isAllColumnsEnabled()).thenReturn(false); presenter.acceptableValues = buildAcceptableValues(); presenter.setValue(dataSetDef); verify(dataSetDef, times(0)).setColumns(any(List.class)); verify(dataSetDef, times(0)).setAllColumnsEnabled(anyBoolean()); verify(columnListEditor, times(1)).setProviderType(DataSetProviderType.BEAN); verify(columnListEditor, times(0)).onValueUnRestricted(anyString()); verify(columnListEditor, times(0)).onValueRestricted(anyString()); verify(columnListEditor, times(0)).setAcceptableValues(any(List.class)); } @Test public void testSetValueWithNotAllColumns() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.isAllColumnsEnabled()).thenReturn(false); presenter.acceptableValues = buildAcceptableValues(); presenter.setValue(dataSetDef); verify(dataSetDef, times(0)).setColumns(any(List.class)); verify(dataSetDef, times(0)).setAllColumnsEnabled(anyBoolean()); verify(columnListEditor, times(1)).setProviderType(any(DataSetProviderType.class)); verify(columnListEditor, times(0)).onValueUnRestricted(anyString()); verify(columnListEditor, times(0)).onValueRestricted(anyString()); verify(columnListEditor, times(0)).setAcceptableValues(any(List.class)); } @Test public void testSetValueWithAllColumns() { final DataSetDef dataSetDef = mock(DataSetDef.class); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.isAllColumnsEnabled()).thenReturn(true); presenter.acceptableValues = buildAcceptableValues(); presenter.setValue(dataSetDef); verify(dataSetDef, times(1)).setColumns(any(List.class)); verify(dataSetDef, times(1)).setAllColumnsEnabled(false); verify(columnListEditor, times(1)).setProviderType(any(DataSetProviderType.class)); verify(columnListEditor, times(0)).onValueUnRestricted(anyString()); verify(columnListEditor, times(0)).onValueRestricted(anyString()); verify(columnListEditor, times(0)).setAcceptableValues(any(List.class)); } private List buildAcceptableValues() { final DataColumnDef col1 = mock(DataColumnDef.class); final List acceptableValues = new ArrayList(); acceptableValues.add(col1); return acceptableValues; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/csv/CSVDataSetDefAttributesEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.csv; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.sql.SQLDataSetDefAttributesEditor; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.file.FileUploadEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.dataset.def.DataSetDefFactory; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.gwtbootstrap3.client.ui.constants.Placement; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class CSVDataSetDefAttributesEditorTest { @Mock DataSetClientServices dataSetClientServices; @Mock ValueBoxEditor fileURL; @Mock FileUploadEditor filePath; @Mock ValueBoxEditor separatorChar; @Mock ValueBoxEditor quoteChar; @Mock ValueBoxEditor escapeChar; @Mock ValueBoxEditor datePattern; @Mock ValueBoxEditor numberPattern; @Mock CSVDataSetDefAttributesEditor.View view; private CSVDataSetDefAttributesEditor presenter; @Before public void setup() { doAnswer(args -> args.getArguments()[0]) .when(dataSetClientServices) .getUploadFileUrl(anyString()); presenter = new CSVDataSetDefAttributesEditor(dataSetClientServices, fileURL, filePath, separatorChar, quoteChar, escapeChar, datePattern, numberPattern, view); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).initWidgets(any(), any(),any(), any(), any(), any(), any()); verify(fileURL, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(filePath, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(separatorChar, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(quoteChar, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(escapeChar, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(datePattern, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(numberPattern, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(filePath, times(1)).configure(anyString(), any(FileUploadEditor.FileUploadEditorCallback.class)); verify(view, times(1)).showFilePathInput(); verify(view, times(0)).showFileURLInput(); ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(FileUploadEditor.FileUploadEditorCallback.class); verify(filePath).configure(anyString(), callbackCaptor.capture()); CSVDataSetDef dataSetDef = (CSVDataSetDef) DataSetDefFactory.newCSVDataSetDef().uuid("test").buildDef(); presenter.setValue(dataSetDef); FileUploadEditor.FileUploadEditorCallback fileCallback = callbackCaptor.getValue(); String fileUrl = fileCallback.getUploadFileUrl(); assertEquals(fileUrl, "default://master@dashbuilder/datasets/tmp/test.csv"); } @Test public void testFileUrl() { assertEquals(fileURL, presenter.fileURL()); } @Test public void testFilePath() { assertEquals(filePath, presenter.filePath()); } @Test public void testSepChar() { assertEquals(separatorChar, presenter.separatorChar()); } @Test public void testQuoteChar() { assertEquals(quoteChar, presenter.quoteChar()); } @Test public void testEscapeChar() { assertEquals(escapeChar, presenter.escapeChar()); } @Test public void testDatePattern() { assertEquals(datePattern, presenter.datePattern()); } @Test public void testNumberPattern() { assertEquals(numberPattern, presenter.numberPattern()); } @Test public void testSetValueUsingFileUrl() { final CSVDataSetDef dataSetDef = mock(CSVDataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.CSV); when(dataSetDef.getFileURL()).thenReturn("fileUrl"); when(dataSetDef.getFilePath()).thenReturn(null); presenter.setValue(dataSetDef); assertEquals(false, presenter.isUsingFilePath()); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class),any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class)); verify(view, times(1)).showFileURLInput(); verify(view, times(0)).showFilePathInput(); } @Test public void testSetValueUsingFilePath() { final CSVDataSetDef dataSetDef = mock(CSVDataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.CSV); when(dataSetDef.getFileURL()).thenReturn(null); when(dataSetDef.getFilePath()).thenReturn("filePath"); presenter.setValue(dataSetDef); assertEquals(true, presenter.isUsingFilePath()); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class),any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class)); verify(view, times(1)).showFilePathInput(); verify(view, times(0)).showFileURLInput(); } public void testCallbackUseFileUrl() { presenter.onUseFileURLButtonClick(); assertEquals(false, presenter.isUsingFilePath()); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class),any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class)); verify(view, times(1)).showFileURLInput(); verify(view, times(0)).showFilePathInput(); } public void testCallbackUseFilePath() { presenter.onUseFilePathButtonClick(); assertEquals(true, presenter.isUsingFilePath()); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(ValueBoxEditor.View.class), any(IsWidget.class),any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class)); verify(view, times(1)).showFilePathInput(); verify(view, times(0)).showFileURLInput(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/csv/CSVDataSetEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.csv; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class CSVDataSetEditorTest { @Mock protected DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock protected DataSetDefColumnsFilterEditor columnsAndFilterEditor; @Mock protected DataSetDefPreviewTable previewTable; @Mock protected DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor; @Mock protected DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor; @Mock protected DataSetDefRefreshAttributesEditor refreshEditor; @Mock protected DataSetClientServices clientServices; @Mock protected LoadingBox loadingBox; @Mock protected EventSourceMock errorEvent; @Mock protected EventSourceMock tabChangedEvent; @Mock protected DataSetEditor.View view; @Mock protected CSVDataSetDef dataSetDef; @Mock CSVDataSetDefAttributesEditor attributesEditor; CSVDataSetEditor presenter; @Before public void setup() throws Exception { this.presenter = new CSVDataSetEditor(basicAttributesEditor, attributesEditor, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.CSV); } @Test public void testFileUrl() { assertEquals(attributesEditor.fileURL, presenter.fileURL()); } @Test public void testFilePath() { assertEquals(attributesEditor.filePath, presenter.filePath()); } @Test public void testSepChar() { assertEquals(attributesEditor.separatorChar, presenter.separatorChar()); } @Test public void testQuoteChar() { assertEquals(attributesEditor.quoteChar, presenter.quoteChar()); } @Test public void testEscapeChar() { assertEquals(attributesEditor.escapeChar, presenter.escapeChar()); } @Test public void testDatePattern() { assertEquals(attributesEditor.datePattern, presenter.datePattern()); } @Test public void testNumberPattern() { assertEquals(attributesEditor.numberPattern, presenter.numberPattern()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/sql/SQLDataSetDefAttributesEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.sql; import java.util.Arrays; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.common.client.editor.ValueBoxEditor; import org.dashbuilder.common.client.editor.list.DropDownEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.def.SQLDataSourceDef; import org.dashbuilder.dataset.service.SQLProviderServices; import org.gwtbootstrap3.client.ui.constants.Placement; import org.jboss.errai.common.client.api.Caller; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.CallerMock; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class SQLDataSetDefAttributesEditorTest { @Mock DropDownEditor dataSource; @Mock ValueBoxEditor dbSchema; @Mock ValueBoxEditor dbTable; @Mock ValueBoxEditor dbSQL; @Mock SQLProviderServices sqlProviderServices; @Mock SQLDataSetDefAttributesEditor.View view; Caller sqlProviderServicesCaller; SQLDataSetDefAttributesEditor presenter; SQLDataSourceDef dataSourceDef = new SQLDataSourceDef("test", "test"); @Before public void setup() { when(sqlProviderServices.getDataSourceDefs()).thenReturn(Arrays.asList(dataSourceDef)); sqlProviderServicesCaller = new CallerMock<>(sqlProviderServices); presenter = new SQLDataSetDefAttributesEditor(dataSource, dbSchema, dbTable, dbSQL, sqlProviderServicesCaller, view); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).initWidgets(any(), any(), any() ,any()); verify(dataSource, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbSchema, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbTable, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbSQL, times(1)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(1)).query(); verify(view, times(0)).table(); verify(sqlProviderServices).getDataSourceDefs(); verify(dataSource).setEntries(any()); verify(dataSource).setSelectHint(anyString()); } @Test public void testDataSource() { assertEquals(dataSource, presenter.dataSource()); } @Test public void testDbSchema() { assertEquals(dbSchema, presenter.dbSchema()); } @Test public void testDbTable() { assertEquals(dbTable, presenter.dbTable()); } @Test public void testDbSQL() { assertEquals(dbSQL, presenter.dbSQL()); } @Test public void testSetValueUsingTable() { final SQLDataSetDef dataSetDef = mock(SQLDataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.getDbTable()).thenReturn("table1"); when(dataSetDef.getDbSQL()).thenReturn(null); presenter.setValue(dataSetDef); assertEquals(false, presenter.isUsingQuery()); verify(view, times(1)).table(); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(DropDownEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class) ,any(ValueBoxEditor.View.class)); verify(dataSource, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbSchema, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbTable, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbSQL, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).query(); } @Test public void testSetValueUsingQuery() { final SQLDataSetDef dataSetDef = mock(SQLDataSetDef.class); when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.getDbTable()).thenReturn(null); when(dataSetDef.getDbSQL()).thenReturn("query1"); presenter.setValue(dataSetDef); assertEquals(true, presenter.isUsingQuery()); verify(view, times(1)).query(); verify(view, times(0)).init(presenter); verify(view, times(0)).initWidgets(any(DropDownEditor.View.class), any(ValueBoxEditor.View.class), any(ValueBoxEditor.View.class) ,any(ValueBoxEditor.View.class)); verify(dataSource, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbSchema, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbTable, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(dbSQL, times(0)).addHelpContent(anyString(), anyString(), any(Placement.class)); verify(view, times(0)).table(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/sql/SQLDataSetEditorTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.sql; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.common.LoadingBox; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefColumnsFilterEditor; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefPreviewTable; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBackendCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefClientCacheAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefRefreshAttributesEditor; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.client.widgets.dataset.event.TabChangedEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class SQLDataSetEditorTest { @Mock protected DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock protected DataSetDefColumnsFilterEditor columnsAndFilterEditor; @Mock protected DataSetDefPreviewTable previewTable; @Mock protected DataSetDefBackendCacheAttributesEditor backendCacheAttributesEditor; @Mock protected DataSetDefClientCacheAttributesEditor clientCacheAttributesEditor; @Mock protected DataSetDefRefreshAttributesEditor refreshEditor; @Mock protected DataSetClientServices clientServices; @Mock protected LoadingBox loadingBox; @Mock protected EventSourceMock errorEvent; @Mock protected EventSourceMock tabChangedEvent; @Mock protected DataSetEditor.View view; @Mock protected SQLDataSetDef dataSetDef; @Mock SQLDataSetDefAttributesEditor attributesEditor; SQLDataSetEditor presenter; @Before public void setup() throws Exception { this.presenter = new SQLDataSetEditor(basicAttributesEditor, attributesEditor, columnsAndFilterEditor, previewTable, backendCacheAttributesEditor, clientCacheAttributesEditor, refreshEditor, clientServices, loadingBox, errorEvent, tabChangedEvent, view); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); } @Test public void testDataSource() { Assert.assertEquals(attributesEditor.dataSource, presenter.dataSource()); } @Test public void testDbSchema() { Assert.assertEquals(attributesEditor.dbSchema, presenter.dbSchema()); } @Test public void testDbTable() { Assert.assertEquals(attributesEditor.dbTable, presenter.dbTable()); } @Test public void testDbSQL() { Assert.assertEquals(attributesEditor.dbSQL, presenter.dbSQL()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/AbstractDataSetWorkflowTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.dataset.editor.workflow; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.validations.DataSetValidatorProvider; import org.dashbuilder.validations.dataset.BeanDataSetDefValidator; import org.dashbuilder.validations.dataset.CSVDataSetDefValidator; import org.dashbuilder.validations.dataset.SQLDataSetDefValidator; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.mockito.Mock; import static org.mockito.Mockito.*; public abstract class AbstractDataSetWorkflowTest { @Mock protected BeanDataSetDefValidator beanDataSetDefValidator; @Mock protected CSVDataSetDefValidator csvDataSetDefValidator; @Mock protected SQLDataSetDefValidator sqlDataSetDefValidator; protected DataSetValidatorProvider validatorProvider; protected void setup() throws Exception { when( beanDataSetDefValidator.getSupportedProvider() ).thenReturn( DataSetProviderType.BEAN ); when( csvDataSetDefValidator.getSupportedProvider() ).thenReturn( DataSetProviderType.CSV ); when( sqlDataSetDefValidator.getSupportedProvider() ).thenReturn( DataSetProviderType.SQL ); validatorProvider = new DataSetValidatorProvider( mock( ManagedInstance.class ) ) { { registerValidator( beanDataSetDefValidator ); registerValidator( csvDataSetDefValidator ); registerValidator( sqlDataSetDefValidator ); } }; } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/DataSetEditorWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.validation.client.impl.ConstraintViolationImpl; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetEditorWorkflowTest extends AbstractDataSetWorkflowTest { public static final String UUID = "uuid1"; public static final String NAME = "name1"; @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock DataSetDef dataSetDef; @Mock DataSet dataSet; @Mock SimpleBeanEditorDriver driver; @Mock DataSetEditorWorkflow.View view; private DataSetEditorWorkflow presenter; @Before public void setup() throws Exception { super.setup(); presenter = new DataSetEditorWorkflow(clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view) { }; presenter.dataSetDef = this.dataSetDef; when(dataSetDef.getUUID()).thenReturn(UUID); when(dataSetDef.getName()).thenReturn(NAME); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); when(dataSet.getUUID()).thenReturn(UUID); when(dataSet.getRowCount()).thenReturn(0); when(dataSetDef.clone()).thenReturn(dataSetDef); doAnswer(new Answer() { @Override public Void answer(final InvocationOnMock invocationOnMock) throws Throwable { DataSetReadyCallback callback = (DataSetReadyCallback) invocationOnMock.getArguments()[2]; callback.callback(dataSet); return null; } }).when(clientServices).lookupDataSet(any(dataSetDef.getClass()), any(DataSetLookup.class), any(DataSetReadyCallback.class)); } @Test public void testInit() { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).clearButtons(); verify(view, times(0)).clearView(); } @Test public void testClear() { presenter.dataSetDef = this.dataSetDef; final Command c = mock(Command.class); presenter.flushCommand = c; presenter.stepValidator = c; presenter.clear(); assertNull(presenter.getDataSetDef()); assertNull(presenter.flushCommand); assertNull(presenter.stepValidator); assertTrue(presenter.violations.isEmpty()); verify(view, times(1)).clearView(); verify(view, times(0)).init(presenter); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).clearButtons(); } // Expect RuntimeException!!! @Test(expected = RuntimeException.class) public void testDoTestDataSetNotEdited() { presenter.dataSetDef = null; final DataSetEditorWorkflow.TestDataSetCallback testDataSetCallback = mock(DataSetEditorWorkflow.TestDataSetCallback.class); presenter.testDataSet(testDataSetCallback); } @Test public void testDoTestDataSet() throws Exception { final DataSetEditorWorkflow.TestDataSetCallback testDataSetCallback = mock(DataSetEditorWorkflow.TestDataSetCallback.class); presenter.testDataSet(testDataSetCallback); verify(dataSetDef, times(1)).setAllColumnsEnabled(true); verify(dataSetDef, times(1)).setColumns(null); verify(dataSetDef, times(1)).setDataSetFilter(null); verify(dataSetDef, times(1)).clone(); verify(dataSetDef, times(1)).setCacheEnabled(false); verify(testDataSetCallback, times(1)).onSuccess(dataSet); verify(testDataSetCallback, times(0)).onError(any(ClientRuntimeError.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).clearButtons(); verify(view, times(0)).clearView(); } @Test public void testFlush() { final Command c = mock(Command.class); presenter.flushCommand = c; presenter.flush(); verify(c, times(1)).execute(); verify(view, times(0)).init(presenter); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).clearButtons(); verify(view, times(0)).clearView(); } @Test public void testShowNextButton() { presenter.showNextButton(); verify(view, times(1)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearButtons(); verify(view, times(0)).clearView(); } @Test public void testShowTestButton() { presenter.showTestButton(); verify(view, times(1)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearButtons(); verify(view, times(0)).clearView(); } @Test public void testShowBackButton() { presenter.showBackButton(); verify(view, times(1)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearButtons(); verify(view, times(0)).clearView(); } @Test public void testClearButtons() { presenter.clearButtons(); verify(view, times(1)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } @Test public void testNoHasErrors() { final Collection violations = mock(Collection.class); when(violations.isEmpty()).thenReturn(true); presenter.violations = violations; assertFalse(presenter.hasErrors()); verify(view, times(0)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } @Test public void testHasErrors() { final Collection violations = mock(Collection.class); when(violations.isEmpty()).thenReturn(false); presenter.violations = violations; assertTrue(presenter.hasErrors()); verify(view, times(0)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } @Test public void testFlushDriver() { final Collection violations = mock(Collection.class); when(violations.isEmpty()).thenReturn(true); presenter.violations = violations; final Command c = mock(Command.class); presenter.stepValidator = c; presenter.flush(driver); verify(driver, times(1)).flush(); verify(c, times(1)).execute(); assertFalse(presenter.hasErrors()); verify(view, times(0)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } @Test public void testAddViolations() { presenter.violations.clear(); ConstraintViolationImpl v1 = mock(ConstraintViolationImpl.class); List _violations = new ArrayList(); _violations.add(v1); presenter.addViolations(_violations); assertTrue(presenter.hasErrors()); verify(view, times(0)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } @Test public void testButtonCommand() { final Command c = mock(Command.class); presenter.flushCommand = c; presenter.testButtonCommand.execute(); verify(c, times(1)).execute(); verify(testDataSetEvent, times(1)).fire(any(TestDataSetRequestEvent.class)); verify(saveRequestEvent, times(0)).fire(any(SaveRequestEvent.class)); verify(cancelRequestEvent, times(0)).fire(any(CancelRequestEvent.class)); verify(view, times(0)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } @Test public void testSaveButtonCommand() { final Command c = mock(Command.class); presenter.flushCommand = c; presenter.saveButtonCommand.execute(); verify(c, times(1)).execute(); verify(saveRequestEvent, times(1)).fire(any(SaveRequestEvent.class)); verify(testDataSetEvent, times(0)).fire(any(TestDataSetRequestEvent.class)); verify(cancelRequestEvent, times(0)).fire(any(CancelRequestEvent.class)); verify(view, times(0)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } @Test public void testCancelButtonCommand() { presenter.cancelButtonCommand.execute(); verify(cancelRequestEvent, times(1)).fire(any(CancelRequestEvent.class)); verify(saveRequestEvent, times(0)).fire(any(SaveRequestEvent.class)); verify(testDataSetEvent, times(0)).fire(any(TestDataSetRequestEvent.class)); verify(view, times(0)).clearButtons(); verify(view, times(0)).addButton(anyString(), anyString(), anyBoolean(), any(Command.class)); verify(view, times(0)).add(any(IsWidget.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).clearView(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/BeanDataSetBasicAttributesWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.BeanDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class BeanDataSetBasicAttributesWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock BeanDataSetDef dataSetDef; @Mock DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock org.dashbuilder.client.widgets.dataset.editor.bean.BeanDataSetDefAttributesEditor beanDataSetDefAttributesEditor; @Mock DataSetEditorWorkflow.View view; private BeanDataSetBasicAttributesWorkflow presenter; @Before public void setup() throws Exception { super.setup(); presenter = new BeanDataSetBasicAttributesWorkflow( clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); when( dataSetDef.getProvider() ).thenReturn( DataSetProviderType.BEAN ); } @Test public void testGetDriverClass() { assertEquals( BeanDataSetDefAttributesDriver.class, presenter.getDriverClass() ); } @Test public void testGetEditorClass() { assertEquals( org.dashbuilder.client.widgets.dataset.editor.bean.BeanDataSetDefAttributesEditor.class, presenter.getEditorClass() ); } @Test public void testValidate() { presenter._setDataSetDef( dataSetDef ); presenter.validate(); verify( beanDataSetDefValidator, times( 1 ) ).validateCustomAttributes( any( BeanDataSetDef.class ) ); verify( beanDataSetDefValidator, times( 0 ) ).validate( any( BeanDataSetDef.class ), anyBoolean(), anyBoolean(), anyBoolean() ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/CSVDataSetBasicAttributesWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.CSVDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class CSVDataSetBasicAttributesWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock CSVDataSetDef dataSetDef; @Mock DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock org.dashbuilder.client.widgets.dataset.editor.csv.CSVDataSetDefAttributesEditor csvDataSetDefAttributesEditor; @Mock DataSetEditorWorkflow.View view; private CSVDataSetBasicAttributesWorkflow presenter; @Before public void setup() throws Exception { super.setup(); presenter = new CSVDataSetBasicAttributesWorkflow( clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); when( dataSetDef.getProvider() ).thenReturn( DataSetProviderType.CSV ); } @Test public void testGetDriverClass() { assertEquals( CSVDataSetDefAttributesDriver.class, presenter.getDriverClass() ); } @Test public void testGetEditorClass() { assertEquals( org.dashbuilder.client.widgets.dataset.editor.csv.CSVDataSetDefAttributesEditor.class, presenter.getEditorClass() ); } @Test public void testValidateUsingFilePath() { presenter._setDataSetDef( dataSetDef ); presenter.editor = csvDataSetDefAttributesEditor; when( csvDataSetDefAttributesEditor.isUsingFilePath() ).thenReturn( true ); presenter.validate(); verify( csvDataSetDefValidator, times( 1 ) ).validateCustomAttributes( dataSetDef, true ); verify( csvDataSetDefValidator, times( 0 ) ).validate( any( CSVDataSetDef.class ), anyBoolean(), anyBoolean(), anyBoolean() ); } @Test public void testValidateUsingFileUrl() { presenter._setDataSetDef( dataSetDef ); presenter.editor = csvDataSetDefAttributesEditor; when( csvDataSetDefAttributesEditor.isUsingFilePath() ).thenReturn( false ); presenter.validate(); verify( csvDataSetDefValidator, times( 1 ) ).validateCustomAttributes( dataSetDef, false ); verify( csvDataSetDefValidator, times( 0 ) ).validate( any( CSVDataSetDef.class ), anyBoolean(), anyBoolean(), anyBoolean() ); } @Test public void testFlushDriverUsingFilePath() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.editor = csvDataSetDefAttributesEditor; when( csvDataSetDefAttributesEditor.isUsingFilePath() ).thenReturn( true ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setFileURL( null ); verify( dataSetDef, times( 0 ) ).setFilePath( null ); } @Test public void testFlushDriverUsingFileUrl() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.editor = csvDataSetDefAttributesEditor; when( csvDataSetDefAttributesEditor.isUsingFilePath() ).thenReturn( false ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setFilePath( null ); verify( dataSetDef, times( 0 ) ).setFileURL( null ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/DataSetBasicAttributesWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.DataSetDefBasicAttributesDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class DataSetBasicAttributesWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock DataSetDefBasicAttributesDriver dataSetDefBasicAttributesDriver; @Mock SyncBeanDef simpleBeanEditorDriverSyncBeanDef; @Mock SyncBeanDef simpleEditorSyncBeanDef; @Mock DataSetEditorWorkflow.View view; private DataSetBasicAttributesWorkflow presenter; @Before public void setup() throws Exception { super.setup(); // Bean instantiation mocks. when( beanManager.lookupBean( DataSetDefBasicAttributesDriver.class ) ).thenReturn( simpleBeanEditorDriverSyncBeanDef ); when( simpleBeanEditorDriverSyncBeanDef.newInstance() ).thenAnswer( new Answer() { @Override public DataSetDefBasicAttributesDriver answer( InvocationOnMock invocationOnMock ) throws Throwable { return dataSetDefBasicAttributesDriver; } } ); when( beanManager.lookupBean( DataSetDefBasicAttributesEditor.class ) ).thenReturn( simpleEditorSyncBeanDef ); when( simpleEditorSyncBeanDef.newInstance() ).thenAnswer( new Answer() { @Override public DataSetDefBasicAttributesEditor answer( InvocationOnMock invocationOnMock ) throws Throwable { return basicAttributesEditor; } } ); presenter = new DataSetBasicAttributesWorkflow( clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ) { @Override protected Class getDriverClass() { return DataSetDefBasicAttributesDriver.class; } @Override protected Class getEditorClass() { return DataSetDefBasicAttributesEditor.class; } @Override protected Iterable> validate() { return null; } }; } @Test public void testBasicAttributesEdition() { DataSetDef def = mock( DataSetDef.class ); presenter.edit( def ).basicAttributesEdition(); verify( beanManager, times( 2 ) ).lookupBean( DataSetDefBasicAttributesDriver.class ); verify( dataSetDefBasicAttributesDriver, times( 2 ) ).initialize( basicAttributesEditor ); verify( dataSetDefBasicAttributesDriver, times( 2 ) ).edit( def ); verify( view, times( 2 ) ).clearView(); verify( view, times( 2 ) ).add( any() ); verify( view, times( 0 ) ).init( presenter ); verify( view, times( 0 ) ).addButton( anyString(), anyString(), anyBoolean(), any( Command.class ) ); verify( view, times( 0 ) ).clearButtons(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/DataSetProviderTypeWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.DataSetDefProviderTypeEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.DataSetDefProviderTypeDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.DataSetDefCreationRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.common.client.editor.list.HorizImageListEditor; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import static org.jgroups.util.Util.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class DataSetProviderTypeWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock DataSetDefProviderTypeEditor providerTypeEditor; @Mock DataSetDefProviderTypeDriver dataSetDefProviderTypeDriver; @Mock SyncBeanDef simpleBeanEditorDriverSyncBeanDef; @Mock HorizImageListEditor provider; @Mock DataSetEditorWorkflow.View view; private DataSetProviderTypeWorkflow presenter; @Before public void setup() throws Exception { // Bean instantiation mocks. when( beanManager.lookupBean( DataSetDefProviderTypeDriver.class ) ).thenReturn( simpleBeanEditorDriverSyncBeanDef ); when( simpleBeanEditorDriverSyncBeanDef.newInstance() ).thenAnswer( new Answer() { @Override public SimpleBeanEditorDriver answer( InvocationOnMock invocationOnMock ) throws Throwable { return dataSetDefProviderTypeDriver; } } ); presenter = new DataSetProviderTypeWorkflow( clientServices, validatorProvider, beanManager, providerTypeEditor, saveRequestEvent, cancelRequestEvent, testDataSetEvent, view ); when( providerTypeEditor.provider() ).thenReturn( provider ); } @Test public void testProviderTypeValue() { when( provider.getValue() ).thenReturn( DataSetProviderType.SQL ); assertEquals( DataSetProviderType.SQL, presenter.getProviderType() ); } @Test public void testProviderTypeEdition() { DataSetDef def = mock( DataSetDef.class ); presenter.edit( def ).providerTypeEdition(); verify( beanManager, times( 1 ) ).lookupBean( DataSetDefProviderTypeDriver.class ); verify( dataSetDefProviderTypeDriver, times( 1 ) ).initialize( providerTypeEditor ); verify( dataSetDefProviderTypeDriver, times( 1 ) ).edit( any( DataSetDef.class ) ); verify( view, times( 2 ) ).clearView(); verify( view, times( 1 ) ).add( any() ); verify( view, times( 0 ) ).init( presenter ); verify( view, times( 0 ) ).addButton( anyString(), anyString(), anyBoolean(), any( Command.class ) ); verify( view, times( 0 ) ).clearButtons(); } @Test public void testProviderTypeSelected() { DataSetDefCreationRequestEvent createEvent = new DataSetDefCreationRequestEvent(providerTypeEditor, DataSetProviderType.BEAN); presenter.onProviderTypeSelected(createEvent); verify(saveRequestEvent).fire(any()); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/create/SQLDataSetBasicAttributesWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.create; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.attributes.DataSetDefBasicAttributesEditor; import org.dashbuilder.client.widgets.dataset.editor.driver.SQLDataSetDefAttributesDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class SQLDataSetBasicAttributesWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock SQLDataSetDef dataSetDef; @Mock DataSetDefBasicAttributesEditor basicAttributesEditor; @Mock org.dashbuilder.client.widgets.dataset.editor.sql.SQLDataSetDefAttributesEditor sqlDataSetDefAttributesEditor; @Mock DataSetEditorWorkflow.View view; private SQLDataSetBasicAttributesWorkflow presenter; @Before public void setup() throws Exception { super.setup(); presenter = new SQLDataSetBasicAttributesWorkflow( clientServices, validatorProvider, beanManager, basicAttributesEditor, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); when( dataSetDef.getProvider() ).thenReturn( DataSetProviderType.SQL ); } @Test public void testGetDriverClass() { assertEquals( SQLDataSetDefAttributesDriver.class, presenter.getDriverClass() ); } @Test public void testGetEditorClass() { assertEquals( org.dashbuilder.client.widgets.dataset.editor.sql.SQLDataSetDefAttributesEditor.class, presenter.getEditorClass() ); } @Test public void testValidateUsingQuery() { presenter._setDataSetDef( dataSetDef ); presenter.editor = sqlDataSetDefAttributesEditor; when( sqlDataSetDefAttributesEditor.isUsingQuery() ).thenReturn( true ); presenter.validate(); verify( sqlDataSetDefValidator, times( 1 ) ).validateCustomAttributes( any( SQLDataSetDef.class ), eq( true ) ); verify( sqlDataSetDefValidator, times( 0 ) ).validate( any( SQLDataSetDef.class ), anyBoolean(), anyBoolean(), anyBoolean() ); } @Test public void testValidateUsingTable() { presenter._setDataSetDef( dataSetDef ); presenter.editor = sqlDataSetDefAttributesEditor; when( sqlDataSetDefAttributesEditor.isUsingQuery() ).thenReturn( false ); presenter.validate(); verify( sqlDataSetDefValidator, times( 1 ) ).validateCustomAttributes( any( SQLDataSetDef.class ), eq( false ) ); verify( sqlDataSetDefValidator, times( 0 ) ).validate( any( SQLDataSetDef.class ), anyBoolean(), anyBoolean(), anyBoolean() ); } @Test public void testFlushDriverUsingQuery() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.editor = sqlDataSetDefAttributesEditor; when( sqlDataSetDefAttributesEditor.isUsingQuery() ).thenReturn( true ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setDbTable( null ); verify( dataSetDef, times( 0 ) ).setDbSQL( null ); } @Test public void testFlushDriverUsingTable() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.editor = sqlDataSetDefAttributesEditor; when( sqlDataSetDefAttributesEditor.isUsingQuery() ).thenReturn( false ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setDbSQL( null ); verify( dataSetDef, times( 0 ) ).setDbTable( null ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/BeanDataSetEditWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.driver.BeanDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.DataSetDefRefreshAttributesEditor; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class BeanDataSetEditWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock DataSet dataSet; @Mock DataSetEditorWorkflow.View view; @Mock org.dashbuilder.client.widgets.dataset.editor.bean.BeanDataSetEditor beanEditor; @Mock BeanDataSetDef dataSetDef; @Mock DataSetDefRefreshAttributesEditor refreshEditor; private BeanDataSetEditWorkflow presenter; @Before public void setup() throws Exception { super.setup(); presenter = new BeanDataSetEditWorkflow( clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); when( dataSetDef.getProvider() ).thenReturn( DataSetProviderType.BEAN ); when( beanEditor.refreshEditor() ).thenReturn( refreshEditor ); when( refreshEditor.isRefreshEnabled() ).thenReturn( true ); } @Test public void testGetDriverClass() { assertEquals( BeanDataSetDefDriver.class, presenter.getDriverClass() ); } @Test public void testGetEditorClass() { assertEquals( org.dashbuilder.client.widgets.dataset.editor.bean.BeanDataSetEditor.class, presenter.getEditorClass() ); } @Test public void testValidate() { presenter._setDataSetDef( dataSetDef ); presenter.validate( true, true, true ); verify( beanDataSetDefValidator, times( 1 ) ).validate( dataSetDef, true, true, true ); verify( beanDataSetDefValidator, times( 0 ) ).validateCustomAttributes( dataSetDef, true ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/CSVDataSetEditWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.driver.CSVDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.CSVDataSetDefEditor; import org.dashbuilder.dataset.client.editor.DataSetDefRefreshAttributesEditor; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class CSVDataSetEditWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock DataSet dataSet; @Mock DataSetEditorWorkflow.View view; @Mock SimpleBeanEditorDriver driver; @Mock org.dashbuilder.client.widgets.dataset.editor.csv.CSVDataSetEditor csvEditor; @Mock CSVDataSetDef dataSetDef; @Mock DataSetDefRefreshAttributesEditor refreshEditor; private CSVDataSetEditWorkflow presenter; @Before public void setup() throws Exception { super.setup(); presenter = new CSVDataSetEditWorkflow( clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); when( dataSetDef.getProvider() ).thenReturn( DataSetProviderType.CSV ); when( csvEditor.refreshEditor() ).thenReturn( refreshEditor ); when( refreshEditor.isRefreshEnabled() ).thenReturn( true ); } @Test public void testGetDriverClass() { assertEquals( CSVDataSetDefDriver.class, presenter.getDriverClass() ); } @Test public void testGetEditorClass() { assertEquals( org.dashbuilder.client.widgets.dataset.editor.csv.CSVDataSetEditor.class, presenter.getEditorClass() ); } @Test public void testValidateUsingFilePath() { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = csvEditor; when( csvEditor.isUsingFilePath() ).thenReturn( true ); presenter.validate( true, true, true ); verify( csvDataSetDefValidator, times( 1 ) ).validate( dataSetDef, true, true, true, true ); verify( csvDataSetDefValidator, times( 0 ) ).validateCustomAttributes( dataSetDef, true ); } @Test public void testValidateUsingFileUrl() { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = csvEditor; when( csvEditor.isUsingFilePath() ).thenReturn( false ); presenter.validate( true, true, true ); verify( csvDataSetDefValidator, times( 1 ) ).validate( dataSetDef, true, true, true, false ); verify( csvDataSetDefValidator, times( 0 ) ).validateCustomAttributes( dataSetDef, false ); } @Test public void testFlushDriverUsingFileUrl() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = csvEditor; when( csvEditor.isUsingFilePath() ).thenReturn( false ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setFilePath( null ); verify( dataSetDef, times( 0 ) ).setFileURL( null ); } @Test public void testFlushUsingFilePath() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = csvEditor; when( csvEditor.isUsingFilePath() ).thenReturn( true ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setFileURL( null ); verify( dataSetDef, times( 0 ) ).setFilePath( null ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/DataSetEditWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import java.util.List; import javax.validation.ConstraintViolation; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.DataSetEditor; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetReadyCallback; import org.dashbuilder.dataset.client.editor.DataSetDefRefreshAttributesEditor; import org.dashbuilder.dataset.def.DataColumnDef; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.mocks.EventSourceMock; import org.uberfire.mvp.Command; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class DataSetEditWorkflowTest extends AbstractDataSetWorkflowTest { public static final String UUID = "uuid1"; public static final String NAME = "name1"; @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock DataSetDef dataSetDef; @Mock DataSet dataSet; @Mock DataSetEditorWorkflow.View view; @Mock DataSetDefRefreshAttributesEditor refreshEditor; @Mock SyncBeanDef simpleBeanEditorDriverSyncBeanDef; @Mock SyncBeanDef dataSetEditorSyncBeanDef; @Mock SimpleBeanEditorDriver driver; @Mock DataSetEditor editor; DataSetEditWorkflow presenter; @Before public void setup() throws Exception { super.setup(); when( dataSetDef.getUUID() ).thenReturn( UUID ); when( dataSetDef.getName() ).thenReturn( NAME ); when( dataSet.getUUID() ).thenReturn( UUID ); when( dataSet.getRowCount() ).thenReturn( 0 ); when( dataSetDef.clone() ).thenReturn( dataSetDef ); when( editor.refreshEditor() ).thenReturn( refreshEditor ); // Bean instantiation mocks. when( beanManager.lookupBean( SimpleBeanEditorDriver.class ) ).thenReturn( simpleBeanEditorDriverSyncBeanDef ); when( simpleBeanEditorDriverSyncBeanDef.newInstance() ).thenAnswer( new Answer() { @Override public SimpleBeanEditorDriver answer( InvocationOnMock invocationOnMock ) throws Throwable { return driver; } } ); when( beanManager.lookupBean( DataSetEditor.class ) ).thenReturn( dataSetEditorSyncBeanDef ); when( dataSetEditorSyncBeanDef.newInstance() ).thenAnswer( new Answer() { @Override public DataSetEditor answer( InvocationOnMock invocationOnMock ) throws Throwable { return editor; } } ); doAnswer( new Answer() { @Override public Void answer( final InvocationOnMock invocationOnMock ) throws Throwable { DataSetReadyCallback callback = (DataSetReadyCallback) invocationOnMock.getArguments()[2]; callback.callback( dataSet ); return null; } } ).when( clientServices ).lookupDataSet( any( dataSetDef.getClass() ), any( DataSetLookup.class ), any( DataSetReadyCallback.class ) ); presenter = new DataSetEditWorkflow( clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ) { @Override protected Class getDriverClass() { return SimpleBeanEditorDriver.class; } @Override protected Class getEditorClass() { return DataSetEditor.class; } @Override protected Iterable> validate( boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled ) { return null; } }; } @Test public void testEdit() { List columnDefs = mock( List.class ); presenter.edit( dataSetDef, columnDefs ); assertEquals( editor, presenter.getEditor() ); verify( driver, times( 1 ) ).initialize( editor ); verify( editor, times( 1 ) ).setAcceptableValues( columnDefs ); verify( driver, times( 1 ) ).edit( dataSetDef ); verify( view, times( 2 ) ).clearView(); verify( view, times( 1 ) ).add( any( IsWidget.class ) ); verify( view, times( 0 ) ).init( presenter ); verify( view, times( 0 ) ).addButton( anyString(), anyString(), anyBoolean(), any( Command.class ) ); verify( view, times( 0 ) ).clearButtons(); } @Test public void testShowConfigurationTab() { presenter.editor = editor; presenter.showConfigurationTab(); verify( editor, times( 1 ) ).showConfigurationTab(); verify( editor, times( 0 ) ).showPreviewTab(); verify( editor, times( 0 ) ).showAdvancedTab(); verify( view, times( 0 ) ).clearView(); verify( view, times( 0 ) ).add( any( IsWidget.class ) ); verify( view, times( 0 ) ).init( presenter ); verify( view, times( 0 ) ).addButton( anyString(), anyString(), anyBoolean(), any( Command.class ) ); verify( view, times( 0 ) ).clearButtons(); } @Test public void testShowPreviewTab() { presenter.editor = editor; presenter.showPreviewTab(); verify( editor, times( 1 ) ).showPreviewTab(); verify( editor, times( 0 ) ).showConfigurationTab(); verify( editor, times( 0 ) ).showAdvancedTab(); verify( view, times( 0 ) ).clearView(); verify( view, times( 0 ) ).add( any( IsWidget.class ) ); verify( view, times( 0 ) ).init( presenter ); verify( view, times( 0 ) ).addButton( anyString(), anyString(), anyBoolean(), any( Command.class ) ); verify( view, times( 0 ) ).clearButtons(); } @Test public void testShowAdvancedTab() { presenter.editor = editor; presenter.showAdvancedTab(); verify( editor, times( 1 ) ).showAdvancedTab(); verify( editor, times( 0 ) ).showPreviewTab(); verify( editor, times( 0 ) ).showConfigurationTab(); verify( view, times( 0 ) ).clearView(); verify( view, times( 0 ) ).add( any( IsWidget.class ) ); verify( view, times( 0 ) ).init( presenter ); verify( view, times( 0 ) ).addButton( anyString(), anyString(), anyBoolean(), any( Command.class ) ); verify( view, times( 0 ) ).clearButtons(); } @Test public void testFlushDriverRefreshEnabled() throws Exception { presenter.editor = editor; when( refreshEditor.isRefreshEnabled() ).thenReturn( true ); presenter.afterFlush(); verify( dataSetDef, times( 0 ) ).setRefreshTime( null ); } @Test public void testFlushDriverRefreshDisabled() throws Exception { presenter.editor = editor; presenter._setDataSetDef( dataSetDef ); when( refreshEditor.isRefreshEnabled() ).thenReturn( false ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setRefreshTime( null ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/editor/workflow/edit/SQLDataSetEditWorkflowTest.java ================================================ package org.dashbuilder.client.widgets.dataset.editor.workflow.edit; import com.google.gwt.editor.client.SimpleBeanEditorDriver; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.editor.driver.SQLDataSetDefDriver; import org.dashbuilder.client.widgets.dataset.editor.workflow.AbstractDataSetWorkflowTest; import org.dashbuilder.client.widgets.dataset.editor.workflow.DataSetEditorWorkflow; import org.dashbuilder.client.widgets.dataset.event.CancelRequestEvent; import org.dashbuilder.client.widgets.dataset.event.SaveRequestEvent; import org.dashbuilder.client.widgets.dataset.event.TestDataSetRequestEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.editor.DataSetDefRefreshAttributesEditor; import org.dashbuilder.dataset.client.editor.SQLDataSetDefEditor; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.mocks.EventSourceMock; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith( GwtMockitoTestRunner.class ) public class SQLDataSetEditWorkflowTest extends AbstractDataSetWorkflowTest { @Mock SyncBeanManager beanManager; @Mock EventSourceMock saveRequestEvent; @Mock EventSourceMock testDataSetEvent; @Mock EventSourceMock cancelRequestEvent; @Mock DataSetClientServices clientServices; @Mock DataSet dataSet; @Mock DataSetEditorWorkflow.View view; @Mock SimpleBeanEditorDriver driver; @Mock org.dashbuilder.client.widgets.dataset.editor.sql.SQLDataSetEditor sqlEditor; @Mock SQLDataSetDef dataSetDef; @Mock DataSetDefRefreshAttributesEditor refreshEditor; private SQLDataSetEditWorkflow presenter; @Before public void setup() throws Exception { super.setup(); presenter = new SQLDataSetEditWorkflow( clientServices, validatorProvider, beanManager, saveRequestEvent, testDataSetEvent, cancelRequestEvent, view ); when( dataSetDef.getProvider() ).thenReturn( DataSetProviderType.SQL ); when( sqlEditor.refreshEditor() ).thenReturn( refreshEditor ); when( refreshEditor.isRefreshEnabled() ).thenReturn( true ); } @Test public void testGetDriverClass() { assertEquals( SQLDataSetDefDriver.class, presenter.getDriverClass() ); } @Test public void testGetEditorClass() { assertEquals( org.dashbuilder.client.widgets.dataset.editor.sql.SQLDataSetEditor.class, presenter.getEditorClass() ); } @Test public void testValidateUsingQuery() { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = sqlEditor; when( sqlEditor.isUsingQuery() ).thenReturn( true ); presenter.validate( true, true, true ); verify( sqlDataSetDefValidator, times( 1 ) ).validate( dataSetDef, true, true, true, true ); verify( sqlDataSetDefValidator, times( 0 ) ).validateCustomAttributes( dataSetDef, true ); } @Test public void testValidateUsingTable() { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = sqlEditor; when( sqlEditor.isUsingQuery() ).thenReturn( false ); presenter.validate( true, true, true ); verify( sqlDataSetDefValidator, times( 1 ) ).validate( dataSetDef, true, true, true, false ); verify( sqlDataSetDefValidator, times( 0 ) ).validateCustomAttributes( dataSetDef, false ); } @Test public void testFlushDriverUsingQuery() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = sqlEditor; when( sqlEditor.isUsingQuery() ).thenReturn( true ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setDbTable( null ); verify( dataSetDef, times( 0 ) ).setDbSQL( null ); } @Test public void testFlushDriverUsingTable() throws Exception { presenter._setDataSetDef( dataSetDef ); presenter.driver = driver; presenter.editor = sqlEditor; when( sqlEditor.isUsingQuery() ).thenReturn( false ); presenter.afterFlush(); verify( dataSetDef, times( 1 ) ).setDbSQL( null ); verify( dataSetDef, times( 0 ) ).setDbTable( null ); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetExplorerTest.java ================================================ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.Widget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.common.CustomDataSetProviderType; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetDefModifiedEvent; import org.dashbuilder.dataset.events.DataSetDefRegisteredEvent; import org.dashbuilder.dataset.events.DataSetDefRemovedEvent; import org.jboss.errai.common.client.api.RemoteCallback; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import javax.enterprise.inject.Instance; import javax.enterprise.util.TypeLiteral; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetExplorerTest { @Mock DataSetExplorer.View view; @Mock DataSetPanel dataSetPanel; @Mock DataSetDef dataSetDef; @Mock DataSetDef dataSetDefCustom; @Mock DataSetClientServices dataSetClientServices; Instance panelInstances; private DataSetExplorer presenter; final List dataSetDefList = new ArrayList(); @Mock ManagedInstance dataSetEditorPlugin; @Mock DataSetEditorPlugin pluginEditor; @Before public void setup() throws Exception { when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.isPublic()).thenReturn(true); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); when(dataSetDefCustom.getUUID()).thenReturn("uuid2"); when(dataSetDefCustom.getName()).thenReturn("name2"); when(dataSetDefCustom.isPublic()).thenReturn(true); when(dataSetDefCustom.getProvider()).thenReturn(() -> "CUSTOM"); dataSetDefList.add(dataSetDef); dataSetDefList.add(dataSetDefCustom); final Widget widget = mock(Widget.class); when(view.asWidget()).thenReturn(widget); panelInstances = new MockInstance(); // Client services method mocks. when(dataSetPanel.getDataSetDef()).thenReturn(dataSetDef); doAnswer(new Answer() { @Override public Void answer(InvocationOnMock invocationOnMock) throws Throwable { RemoteCallback> callback = (RemoteCallback>) invocationOnMock.getArguments()[0]; callback.callback(dataSetDefList); return null; } }).when(dataSetClientServices).getPublicDataSetDefs(any(RemoteCallback.class)); when(dataSetEditorPlugin.isUnsatisfied()).thenReturn(true); // The presenter instance to test. presenter = new DataSetExplorer(panelInstances, dataSetClientServices, view, dataSetEditorPlugin); } @Test public void testInit() throws Exception { presenter.init(); verify(view, times(1)).init(presenter); } @Test public void testAsWidget() throws Exception { assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testShow() throws Exception { presenter.show(); assertEquals(1, presenter.panels.size()); assertEquals(dataSetPanel, presenter.panels.get(0)); verify(view, times(1)).clear(); verify(view, times(1)).addPanel(any()); verify(dataSetPanel, times(1)).show(dataSetDef, "dataSetsExplorerPanelGroup"); } @Test public void testShowTwice() throws Exception { // Add same data set def again, but only one panel must be visible. dataSetDefList.add(dataSetDef); presenter.show(); assertEquals(1, presenter.panels.size()); assertEquals(dataSetPanel, presenter.panels.get(0)); verify(view, times(1)).clear(); verify(view, times(1)).addPanel(any()); verify(dataSetPanel, times(1)).show(dataSetDef, "dataSetsExplorerPanelGroup"); } @Test public void testOnDataSetDefRegisteredEvent() { final DataSetDefRegisteredEvent event = mock(DataSetDefRegisteredEvent.class); when(event.getDataSetDef()).thenReturn(dataSetDef); presenter.onDataSetDefRegisteredEvent(event); assertEquals(1, presenter.panels.size()); assertEquals(dataSetPanel, presenter.panels.get(0)); verify(view).clear(); verify(view).addPanel(any()); verify(dataSetPanel).show(dataSetDef, "dataSetsExplorerPanelGroup"); } @Test public void testOnDataSetDefModifiedEvent() { final DataSetDefModifiedEvent event = mock(DataSetDefModifiedEvent.class); when(event.getOldDataSetDef()).thenReturn(dataSetDef); when(event.getNewDataSetDef()).thenReturn(dataSetDef); presenter.panels.add(dataSetPanel); presenter.onDataSetDefModifiedEvent(event); assertEquals(1, presenter.panels.size()); assertEquals(dataSetPanel, presenter.panels.get(0)); verify(view, times(0)).clear(); verify(view, times(0)).addPanel(any(DataSetPanel.View.class)); verify(dataSetPanel, times(1)).show(dataSetDef, "dataSetsExplorerPanelGroup"); verify(dataSetPanel, times(1)).close(); } @Test public void testOnDataSetDefRemovedEvent() { final DataSetDef removedDataSetDef = mock(DataSetDef.class); when(removedDataSetDef.getUUID()).thenReturn("removed"); when(removedDataSetDef.getName()).thenReturn("removedDef"); when(removedDataSetDef.isPublic()).thenReturn(true); when(removedDataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); final DataSetDefRemovedEvent event = mock(DataSetDefRemovedEvent.class); when(event.getDataSetDef()).thenReturn(removedDataSetDef); presenter.onDataSetDefRemovedEvent(event); assertEquals(1, presenter.panels.size()); assertEquals(dataSetPanel, presenter.panels.get(0)); verify(view, times(1)).clear(); verify(view, times(1)).addPanel(any()); verify(dataSetPanel, times(1)).show(dataSetDef, "dataSetsExplorerPanelGroup"); } @Test public void testInitWithEditorPlugin() throws Exception { when(pluginEditor.getProviderType()).thenReturn(new CustomDataSetProviderType()); when(pluginEditor.getTypeSelectorTitle()).thenReturn("Custom"); when(pluginEditor.getTypeSelectorImageUri()).thenReturn(Mockito.mock(SafeUri.class)); when(dataSetEditorPlugin.isUnsatisfied()).thenReturn(false); when(dataSetEditorPlugin.iterator()).thenReturn(Arrays.asList(pluginEditor).iterator(), Arrays.asList(pluginEditor).iterator()); when(dataSetDef.getProvider()).thenReturn(new CustomDataSetProviderType()); presenter.init(); verify(view, times(1)).init(presenter); verify(dataSetEditorPlugin, times(1)).isUnsatisfied(); verify(dataSetEditorPlugin, times(1)).iterator(); assertEquals(5, presenter.SUPPORTED_TYPES.size()); } // Mockito complains when mocking Instance, so let's create an empty implementation for it. It returns a single mocked DataSetPanel instance. private class MockInstance implements Instance { @Override public Instance select(Annotation... annotations) { return null; } @Override public Instance select(Class aClass, Annotation... annotations) { return (Instance) dataSetPanel; } @Override public boolean isUnsatisfied() { return false; } @Override public boolean isAmbiguous() { return false; } @Override public void destroy(DataSetPanel dataSetPanel) { } @Override public Iterator iterator() { return null; } @Override public DataSetPanel get() { return dataSetPanel; } @Override public Instance select(TypeLiteral subtype, Annotation... qualifiers) { return (Instance) dataSetPanel; } } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetPanelTest.java ================================================ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.safehtml.shared.SafeUri; import com.google.gwt.user.client.ui.Widget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.common.CustomDataSetProviderType; import org.dashbuilder.client.widgets.common.DataSetEditorPlugin; import org.dashbuilder.client.widgets.dataset.event.EditDataSetEvent; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.uberfire.mocks.EventSourceMock; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; import java.util.Arrays; @RunWith(GwtMockitoTestRunner.class) public class DataSetPanelTest { @Mock DataSetSummary dataSetSummary; @Mock EventSourceMock editDataSetEvent; @Mock DataSetPanel.View view; @Mock DataSetDef dataSetDef; @Mock ManagedInstance dataSetEditorPlugin; @Mock DataSetEditorPlugin pluginEditor; private DataSetPanel presenter; @Before public void setup() throws Exception { when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.BEAN); // The presenter instance to test. final Widget widget = mock(Widget.class); when(view.asWidget()).thenReturn(widget); presenter = spy(new DataSetPanel(dataSetSummary, editDataSetEvent, view, dataSetEditorPlugin)); } @Test public void testInit() throws Exception { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(1)).configure(any()); verify(view, times(0)).showHeader(anyString(), anyString(), any(SafeUri.class), anyString(), anyString()); verify(view, times(0)).showSummary(); verify(view, times(0)).hideSummary(); verify(view, times(0)).enableActionButton(anyString(), any(ClickHandler.class)); verify(view, times(0)).disableActionButton(); } @Test public void testAsWidget() throws Exception { assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testClose() throws Exception { presenter.close(); verify(view, times(0)).init(presenter); verify(view, times(0)).configure(any(DataSetSummary.View.class)); verify(view, times(0)).showHeader(anyString(), anyString(), any(SafeUri.class), anyString(), anyString()); verify(view, times(0)).showSummary(); verify(view, times(1)).hideSummary(); verify(view, times(0)).enableActionButton(anyString(), any(ClickHandler.class)); verify(view, times(0)).disableActionButton(); } @Test public void testDisable() throws Exception { presenter.disable(); verify(view, times(0)).init(presenter); verify(view, times(0)).configure(any(DataSetSummary.View.class)); verify(view, times(0)).showHeader(anyString(), anyString(), any(SafeUri.class), anyString(), anyString()); verify(view, times(0)).showSummary(); verify(view, times(0)).hideSummary(); verify(view, times(0)).enableActionButton(anyString(), any(ClickHandler.class)); verify(view, times(1)).disableActionButton(); } @Test public void testShow() throws Exception { final String iconTitle = "iconTitle"; doReturn(iconTitle).when(presenter).getTypeIconTitle(dataSetDef); final SafeUri iconUri = mock(SafeUri.class); doReturn(iconUri).when(presenter).getTypeIconUri(dataSetDef); final String parentPanelId = "parentPanel"; presenter.show(dataSetDef, parentPanelId); assertEquals(dataSetDef, presenter.getDataSetDef()); verify(view, times(0)).init(presenter); verify(view, times(0)).configure(any(DataSetSummary.View.class)); verify(view, times(1)).showHeader("uuid1", parentPanelId, iconUri, iconTitle, "name1"); verify(view, times(0)).showSummary(); verify(view, times(0)).hideSummary(); verify(view, times(0)).enableActionButton(anyString(), any(ClickHandler.class)); verify(view, times(0)).disableActionButton(); } @Test public void testOpen() throws Exception { presenter.def = dataSetDef; presenter.open(); verify(dataSetSummary, times(1)).show(dataSetDef); verify(view, times(0)).init(presenter); verify(view, times(0)).configure(any(DataSetSummary.View.class)); verify(view, times(0)).showHeader(anyString(), anyString(), any(SafeUri.class), anyString(), anyString()); verify(view, times(1)).showSummary(); verify(view, times(0)).hideSummary(); verify(view, times(1)).enableActionButton(anyString(), any(ClickHandler.class)); verify(view, times(0)).disableActionButton(); } @Test public void testEditorPlugin() throws Exception { when(pluginEditor.getProviderType()).thenReturn(new CustomDataSetProviderType()); when(pluginEditor.getTypeSelectorTitle()).thenReturn("Custom"); when(pluginEditor.getTypeSelectorImageUri()).thenReturn(Mockito.mock(SafeUri.class)); when(dataSetEditorPlugin.isUnsatisfied()).thenReturn(false); when(dataSetEditorPlugin.iterator()).thenReturn(Arrays.asList(pluginEditor).iterator(), Arrays.asList(pluginEditor).iterator()); when(dataSetDef.getProvider()).thenReturn(new CustomDataSetProviderType()); presenter.def = dataSetDef; final String parentPanelId = "parentPanel"; presenter.show(dataSetDef, parentPanelId); verify(dataSetEditorPlugin, times(2)).isUnsatisfied(); verify(dataSetEditorPlugin, times(2)).iterator(); verify(pluginEditor, times(1)).getTypeSelectorImageUri(); verify(pluginEditor, times(1)).getTypeSelectorTitle(); } } ================================================ FILE: dashbuilder/dashbuilder-client/dashbuilder-widgets/src/test/java/org/dashbuilder/client/widgets/dataset/explorer/DataSetSummaryTest.java ================================================ package org.dashbuilder.client.widgets.dataset.explorer; import com.google.gwt.user.client.ui.Widget; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.widgets.dataset.event.ErrorEvent; import org.dashbuilder.common.client.error.ClientRuntimeError; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.client.ClientDataSetManager; import org.dashbuilder.dataset.client.DataSetClientServices; import org.dashbuilder.dataset.client.DataSetMetadataCallback; import org.dashbuilder.dataset.def.DataSetDef; import org.gwtbootstrap3.client.ui.constants.IconType; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.uberfire.mocks.EventSourceMock; import static org.jgroups.util.Util.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class DataSetSummaryTest { @Mock DataSetClientServices dataSetClientServices; @Mock ClientDataSetManager clientDataSetManager; @Mock EventSourceMock errorEvent; @Mock DataSetDef dataSetDef; @Mock DataSetSummary.View view; private DataSetSummary presenter; final DataSetMetadata dataSetMetadata = mock(DataSetMetadata.class); @Before public void setup() throws Exception { when(dataSetDef.getUUID()).thenReturn("uuid1"); when(dataSetDef.getName()).thenReturn("name1"); when(dataSetDef.getProvider()).thenReturn(DataSetProviderType.SQL); when(dataSetDef.isCacheEnabled()).thenReturn(true); when(dataSetDef.isPushEnabled()).thenReturn(true); when(dataSetDef.isRefreshAlways()).thenReturn(true); when(dataSetDef.getRefreshTime()).thenReturn("1second"); doAnswer(new Answer() { @Override public Void answer(InvocationOnMock invocationOnMock) throws Throwable { DataSetMetadataCallback callback = (DataSetMetadataCallback) invocationOnMock.getArguments()[1]; callback.callback(dataSetMetadata); return null; } }).when(dataSetClientServices).fetchMetadata(anyString(), any(DataSetMetadataCallback.class)); // The presenter instance to test. final Widget widget = mock(Widget.class); when(view.asWidget()).thenReturn(widget); presenter = new DataSetSummary(dataSetClientServices, errorEvent, view); } @Test public void testInit() throws Exception { presenter.init(); verify(view, times(1)).init(presenter); verify(view, times(0)).showStatusPanel(anyBoolean(), anyBoolean(), anyBoolean()); verify(view, times(0)).showSizePanelIcon(any(IconType.class), anyString(), anyString(), anyBoolean()); verify(view, times(0)).showSizePanel(anyString(), anyString()); } @Test public void testAsWidget() throws Exception { assertEquals(view.asWidget(), presenter.asWidget()); } @Test public void testShow() throws Exception { final int estimatedSize = 100; final int rowCount = 10; when(dataSetMetadata.getEstimatedSize()).thenReturn(estimatedSize); when(dataSetMetadata.getNumberOfRows()).thenReturn(rowCount); presenter.show(dataSetDef); verify(view, times(0)).init(presenter); verify(view, times(1)).showStatusPanel(true, true, true); verify(view, times(1)).showSizePanelIcon(any(IconType.class), anyString(), anyString(), anyBoolean()); verify(view, times(1)).showSizePanel(anyString(), anyString()); } // TODO: @Test - Mock NumberFormat public void testHumanReadableByteCount() throws Exception { long estimatedSize = (long) 2024.2; String s = presenter.humanReadableByteCount(estimatedSize); // assertEquals("", s); } // TODO: @Test - Mock NumberFormat public void testHumanReadableRowCount() throws Exception { long rows = (long) 1000; String s = presenter.humanReadableRowCount(rows); // assertEquals("", s); } @Test public void testShowLoadingIcon() { presenter.showLoadingIcon(); verify(view, times(0)).init(presenter); verify(view, times(0)).showStatusPanel(anyBoolean(), anyBoolean(), anyBoolean()); verify(view, times(1)).showSizePanelIcon(any(IconType.class), anyString(), anyString(), anyBoolean()); verify(view, times(0)).showSizePanel(anyString(), anyString()); } @Test public void testShowErrorIcon() { presenter.showErrorIcon(); verify(view, times(0)).init(presenter); verify(view, times(0)).showStatusPanel(anyBoolean(), anyBoolean(), anyBoolean()); verify(view, times(1)).showSizePanelIcon(any(IconType.class), anyString(), anyString(), anyBoolean()); verify(view, times(0)).showSizePanel(anyString(), anyString()); } @Test public void testShowClientRuntimeError() { final ClientRuntimeError error = mock(ClientRuntimeError.class); presenter.showError("uuid1", error); verify(errorEvent, times(1)).fire(any(ErrorEvent.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).showStatusPanel(anyBoolean(), anyBoolean(), anyBoolean()); verify(view, times(0)).showSizePanelIcon(any(IconType.class), anyString(), anyString(), anyBoolean()); verify(view, times(0)).showSizePanel(anyString(), anyString()); } @Test public void testShowThrowable() { final Throwable error = mock(Throwable.class); presenter.showError("uuid1", error); verify(errorEvent, times(1)).fire(any(ErrorEvent.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).showStatusPanel(anyBoolean(), anyBoolean(), anyBoolean()); verify(view, times(0)).showSizePanelIcon(any(IconType.class), anyString(), anyString(), anyBoolean()); verify(view, times(0)).showSizePanel(anyString(), anyString()); } @Test public void testShowErrorMessage() { presenter.showError("uuid1", "errorMessage"); verify(errorEvent, times(1)).fire(any(ErrorEvent.class)); verify(view, times(0)).init(presenter); verify(view, times(0)).showStatusPanel(anyBoolean(), anyBoolean(), anyBoolean()); verify(view, times(0)).showSizePanelIcon(any(IconType.class), anyString(), anyString(), anyBoolean()); verify(view, times(0)).showSizePanel(anyString(), anyString()); } } ================================================ FILE: dashbuilder/dashbuilder-client/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT ../pom.xml dashbuilder-client pom Dashbuilder Client modules dashbuilder-common-client dashbuilder-dataset-client dashbuilder-displayer-client dashbuilder-widgets dashbuilder-dataset-editor dashbuilder-displayer-screen dashbuilder-displayer-editor dashbuilder-renderers dashbuilder-navigation-client dashbuilder-cms-client dashbuilder-kie-server-client jakarta.inject jakarta.inject-api provided ================================================ FILE: dashbuilder/dashbuilder-distros/README.md ================================================ UF Dashbuilder - Distributions Builder ======================================= This module generates the product distribution for different applications servers. Usage ----- This module is not build by default. You can build it in two ways: *Run the maven build on this module path `dashbuilder-distros`: $ cd dashbuilder/dashbuilder-distros/ $ mvn clean install -DskipTests *Run the maven build on the root path for the project and use the `full` Maven profile: $ cd dashbuilder/ $ mvn clean install -DskipTests -Dfull Distributions ------------- Currently, the following artifact is generated: * **dashbuilder-wildfly10.war:** Product distribution for the JBoss WildFly 10.x application server. Detailed installation instructions [here](./src/main/wildfly10/README.md). ================================================ FILE: dashbuilder/dashbuilder-distros/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT ../pom.xml dashbuilder-distros pom Dashbuilder Distribution WARs This module builds the download wars for different application servers. org.apache.maven.plugins maven-assembly-plugin package single dashbuilder-${project.version} src/main/assembly/assembly-wildfly-10.xml false org.dashbuilder dashbuilder-webapp war jakarta.enterprise jakarta.enterprise.cdi-api com.sun.xml.bind jaxb-impl com.sun.xml.bind jaxb-xjc jakarta.inject jakarta.inject-api jakarta.ejb jakarta.ejb-api jakarta.servlet.jsp.jstl jakarta.servlet.jsp.jstl-api jakarta.annotation jakarta.annotation-api org.jboss.resteasy resteasy-cdi jakarta.ws.rs jakarta.ws.rs-api org.slf4j slf4j-api org.jboss.logging jboss-logging jakarta.persistence jakarta.persistence-api jakarta.activation jakarta.activation-api org.scannotation scannotation javassist javassist org.jboss.errai errai-cdi-server org.jboss.weld weld-api javax.enterprise cdi-api org.jboss.weld.servlet weld-servlet-core org.jboss.weld.se weld-se-core ================================================ FILE: dashbuilder/dashbuilder-distros/src/main/assembly/assembly-wildfly-10.xml ================================================ wildfly10 war dir false org.dashbuilder:dashbuilder-webapp:war . true WEB-INF/classes/application-roles.properties WEB-INF/classes/application-users.properties WEB-INF/jboss-web.xml WEB-INF/beans.xml **/*devmode.js ${project.basedir}/src/main/wildfly10/ . ================================================ FILE: dashbuilder/dashbuilder-distros/src/main/wildfly10/README.md ================================================ Deployment into JBoss WidlFly 10.X ================================== Please follow the next steps in order to deploy the application. Deploy ------ Run your JBoss WildFly instance using the `full` server profile as: $JBOSS_HOME/bin/standalone.sh --server-config=standalone-full.xml Once server is up and running, get the proper WAR file (e.g. `dashbuilder--wildfly10.war`) and execute the following command to deploy the application into your JBoss Wildfly instance: $ cd $JBOSS_HOME/bin $ ./jboss-cli.sh --connect --command="deploy " NOTES: - : is the local path to the application war file. - e.g. $ ./jboss-cli.sh --connect --command="deploy /home/myuser/myfiles/dashbuilder-0.5.0-SNAPSHOT-wildfly10.war" ) User Authentication -------------------- Once started, open a browser and type the following URL: http://localhost:8080/dashbuilder # A login screen should be displayed. However, some extra configuration is needed before you can sign in: * The application is based on the J2EE container managed authentication mechanism. This means that the login itself is delegated to the application server. * To create users and define the roles use the command line utility provided by JBoss WildFly at `$JBOSS_HOME/bin/add-user.sh`. * The application roles are defined at [web.xml](./WEB-INF/web.xml) file. Roles can be used to create access profiles and define custom authorization policies. There exist a single application role named `admin`. In order to use the application, create a user with role `admin`. * The application uses the JBoss' default security domain as you can see [here](./WEB-INF/jboss-web.xml). Alternatively, you can define your own security domain and use, for instance, an LDAP, a database, or whatever mechanism you want to use as your credential storage. There are plenty of examples in the JBoss WildFly documentation about. Feel free to change any settings regarding the application security and, once finished, to generate a distribution war that fits your needs. File System provider --------------------- Dashbuilder stores all the internal artifacts (such as the data set definition files, the uploaded files, etc) into a GIT repository. You can clone the repository and noddle around with it if you need to. By default, the GIT repository is created when the application starts for first time at `$WORKING_DIR/.niogit`, considering `$WORKING_DIR` as the current directory where the application server is started. You can specify a custom repository location by setting the following Java system property to your target file system directory: -Dorg.uberfire.nio.git.dir=/home/youruser/some/path If necessary you can make GIT repositories available from outside localhost using the following Java system property: -org.uberfire.nio.git.ssh.host=0.0.0.0 You can set this Java system properties permanent by adding the following lines in your `standalone-full.xml` file as: ================================================ FILE: dashbuilder/dashbuilder-distros/src/main/wildfly10/WEB-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-distros/src/main/wildfly10/WEB-INF/jboss-web.xml ================================================ other ================================================ FILE: dashbuilder/dashbuilder-packaging/dashbuilder-all/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-packaging 7.75.0-SNAPSHOT dashbuilder-all pom Dashbuilder All Libraries org.dashbuilder dashbuilder-client-all org.dashbuilder dashbuilder-server-all ================================================ FILE: dashbuilder/dashbuilder-packaging/dashbuilder-client-all/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-packaging 7.75.0-SNAPSHOT dashbuilder-client-all jar Dashbuilder All Client Libraries org.dashbuilder dashbuilder-common-client org.dashbuilder dashbuilder-common-client sources org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-dataset-client sources org.kie.soup kie-soup-dataset-shared org.kie.soup kie-soup-dataset-shared sources org.dashbuilder dashbuilder-displayer-client org.dashbuilder dashbuilder-displayer-client sources org.dashbuilder dashbuilder-widgets org.dashbuilder dashbuilder-widgets sources org.dashbuilder dashbuilder-displayer-screen org.dashbuilder dashbuilder-displayer-screen sources org.dashbuilder dashbuilder-dataset-editor org.dashbuilder dashbuilder-dataset-editor sources org.dashbuilder dashbuilder-renderer-default org.dashbuilder dashbuilder-renderer-default sources org.dashbuilder dashbuilder-navigation-client org.dashbuilder dashbuilder-navigation-client sources org.dashbuilder dashbuilder-cms-client org.dashbuilder dashbuilder-cms-client sources ================================================ FILE: dashbuilder/dashbuilder-packaging/dashbuilder-client-all/src/main/resources/META-INF/ErraiApp.properties ================================================ # # Copyright 2012 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-packaging/dashbuilder-client-all/src/main/resources/org/dashbuilder/DashbuilderClientAll.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-packaging/dashbuilder-server-all/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-packaging 7.75.0-SNAPSHOT dashbuilder-server-all jar Dashbuilder All Server Libraries org.kie.soup kie-soup-dataset-core org.kie.soup kie-soup-dataset-sql org.kie.soup kie-soup-dataset-csv org.dashbuilder dashbuilder-dataset-cdi org.dashbuilder dashbuilder-navigation-backend org.dashbuilder dashbuilder-services org.dashbuilder dashbuilder-external-backend ================================================ FILE: dashbuilder/dashbuilder-packaging/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT ../pom.xml dashbuilder-packaging pom Dashbuilder Packaging dashbuilder-client-all dashbuilder-server-all dashbuilder-all ================================================ FILE: dashbuilder/dashbuilder-runtime/.gitignore ================================================ *.deploy /src/main/gwt-unitCache /src/main/webapp/WEB-INF/classes/ /src/main/webapp/WEB-INF/lib /src/main/webapp/org.dashbuilder.DashbuilderRuntime/ ================================================ FILE: dashbuilder/dashbuilder-runtime/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT ../pom.xml dashbuilder-runtime war Dashbuilder Runtime Dashbuilder Runtime for running standalone dashboards ${project.build.directory}/wildfly-${version.org.wildfly} false 4 org.jboss.resteasy resteasy-multipart-provider provided org.jboss.resteasy resteasy-jaxrs com.sun.mail javax.mail org.jboss.resteasy resteasy-jaxb-provider org.apache.james apache-mime4j org.jboss.resteasy resteasy-client com.google.code.gson gson org.jboss.xnio xnio-api jakarta.xml.bind jakarta.xml.bind-api provided jakarta.security.jacc jakarta.security.jacc-api provided jakarta.enterprise.concurrent jakarta.enterprise.concurrent-api provided org.apache.commons commons-lang3 org.kie.soup kie-soup-dataset-core org.kie.soup kie-soup-dataset-csv org.kie.soup kie-soup-dataset-sql org.kie.soup kie-soup-dataset-prometheus org.kie.soup kie-soup-dataset-kafka org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-client-all provided org.jboss.errai errai-security-server org.dashbuilder dashbuilder-cms-client org.dashbuilder dashbuilder-common-client provided org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-client provided org.dashbuilder dashbuilder-displayer-screen provided org.dashbuilder dashbuilder-displayer-editor provided org.dashbuilder dashbuilder-renderer-default provided org.dashbuilder dashbuilder-renderer-c3 provided org.dashbuilder dashbuilder-navigation-api org.jboss.errai errai-security-server org.dashbuilder dashbuilder-navigation-client provided org.uberfire uberfire-widgets-security-management provided org.uberfire uberfire-security-management-client provided org.uberfire uberfire-security-management-api provided org.dashbuilder dashbuilder-services-api org.dashbuilder dashbuilder-kie-server-api org.dashbuilder dashbuilder-kie-server-backend org.dashbuilder dashbuilder-external-backend org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-commons-editor-api org.jboss.errai errai-security-server org.uberfire uberfire-commons-editor-client provided org.jboss.errai errai-security-server org.uberfire appformer-js-bridge provided org.uberfire uberfire-backend-cdi org.uberfire uberfire-api org.uberfire uberfire-js org.uberfire uberfire-client-api provided org.uberfire uberfire-io org.uberfire uberfire-backend-api org.uberfire uberfire-workbench-client provided org.jboss.errai errai-security-server org.uberfire uberfire-workbench-processors provided org.uberfire uberfire-preferences-processors provided org.uberfire uberfire-runtime-plugins-api org.uberfire uberfire-runtime-plugins-client provided org.jboss.errai errai-security-server org.uberfire uberfire-layout-editor-client provided org.uberfire uberfire-layout-editor-api org.uberfire uberfire-widgets-service-api org.uberfire uberfire-widgets-properties-editor-api org.uberfire uberfire-widgets-properties-editor-client provided org.uberfire uberfire-workbench-client-views-patternfly provided org.jboss.errai errai-security-server org.uberfire uberfire-widgets-commons provided org.jboss.errai errai-security-server org.uberfire uberfire-widgets-table provided org.uberfire uberfire-simple-docks-client provided org.jboss.errai errai-security-server org.uberfire uberfire-preferences-api org.uberfire uberfire-preferences-client-backend provided org.jboss.errai errai-security-server org.uberfire uberfire-preferences-ui-client provided org.uberfire uberfire-preferences-client provided org.jboss.errai errai-security-server org.uberfire uberfire-security-api org.jboss.errai errai-security-server org.uberfire uberfire-security-client provided org.jboss.errai errai-security-server org.slf4j slf4j-api provided org.slf4j log4j-over-slf4j org.jboss.errai errai-common org.jboss.errai errai-marshalling de.benediktmeurer.gwt-slf4j gwt-slf4j provided org.jboss.errai errai-ui provided org.jboss.errai errai-ioc org.jboss.errai errai-jboss-as-support org.jboss.errai errai-cdi-server org.jboss.errai errai-javax-enterprise provided org.owasp.encoder encoder org.jboss.errai errai-codegen-gwt provided org.uberfire uberfire-experimental-api javax.validation validation-api provided org.hibernate hibernate-validator provided jakarta.enterprise jakarta.enterprise.cdi-api provided jakarta.inject jakarta.inject-api provided org.jboss.errai errai-cdi-jboss provided xml-apis xml-apis provided com.sun.xml.bind jaxb-impl provided org.jboss.resteasy resteasy-cdi provided org.jboss.resteasy resteasy-jaxrs provided com.google.gwt gwt-user provided javax.servlet javax.servlet-api org.gwtbootstrap3 gwtbootstrap3 provided org.gwtbootstrap3 gwtbootstrap3-extras provided org.uberfire uberfire-ssh-api org.jboss.errai errai-security-server org.uberfire uberfire-ssh-client com.google.inject guice org.jboss.errai errai-data-binding org.jboss.errai errai-cdi-shared org.mockito mockito-core test com.google.gwt.gwtmockito gwtmockito test org.mockito mockito-core org.uberfire uberfire-testing-utils test org.mockito mockito-core ${project.artifactId} src/main/webapp/WEB-INF/classes org.codehaus.mojo gwt-maven-plugin ${project.build.directory}/gwt-symbols-deploy ${gwt.compiler.localWorkers} org.dashbuilder.FastCompiledDashbuilderRuntime true INFO true org.hibernate:hibernate-validator org.kie.soup:kie-soup-json org.dashbuilder:dashbuilder-widgets org.dashbuilder:dashbuilder-validations org.dashbuilder:dashbuilder-common-client org.dashbuilder:dashbuilder-services-api org.kie.soup:kie-soup-dataset-api org.kie.soup:kie-soup-dataset-shared org.dashbuilder:dashbuilder-displayer-api org.dashbuilder:dashbuilder-displayer-client org.dashbuilder:dashbuilder-displayer-screen org.dashbuilder:dashbuilder-displayer-editor org.dashbuilder:dashbuilder-renderer-default org.dashbuilder:dashbuilder-renderer-c3 org.dashbuilder:dashbuilder-navigation-api org.dashbuilder:dashbuilder-navigation-client org.dashbuilder:dashbuilder-kie-server-api org.uberfire:uberfire-runtime-plugins-api org.uberfire:uberfire-runtime-plugins-client org.uberfire:uberfire-layout-editor-api org.uberfire:uberfire-layout-editor-client org.uberfire:uberfire-commons-editor-api org.uberfire:uberfire-commons-editor-client org.uberfire:uberfire-widgets-service-api org.uberfire:uberfire-widgets-commons org.uberfire:uberfire-widgets-table org.uberfire:uberfire-widgets-properties-editor-api org.uberfire:uberfire-widgets-properties-editor-client org.uberfire:uberfire-simple-docks-client org.uberfire:uberfire-preferences-api org.uberfire:uberfire-preferences-client org.uberfire:uberfire-preferences-ui-client org.kie.soup:kie-soup-commons org.uberfire:uberfire-commons org.uberfire:uberfire-nio2-model org.uberfire:uberfire-io org.uberfire:uberfire-api org.uberfire:uberfire-js org.uberfire:appformer-js-bridge org.uberfire:uberfire-security-api org.uberfire:uberfire-security-client org.uberfire:uberfire-client-api org.uberfire:uberfire-workbench-client org.uberfire:uberfire-workbench-client-backend org.uberfire:uberfire-workbench-client-views-patternfly org.uberfire:uberfire-backend-api org.uberfire:uberfire-ssh-client org.uberfire:uberfire-ssh-api org.uberfire:uberfire-widgets-security-management org.uberfire:uberfire-security-management-client org.uberfire:uberfire-security-management-api org.uberfire:uberfire-experimental-api org.uberfire:uberfire-experimental-client dashbuilder.html -Xmx4024m -XX:CompileThreshold=7000 -Derrai.jboss.home=${errai.jboss.home} -Derrai.dynamic_validation.enabled=true -Ddashbuilder.runtime.multi=true -Ddashbuilder.components.enable=true -Ddashbuilder.removeModelFile=true -Ddashbuilder.kieserver.serverTemplate.sample-server.location=http://localhost:8080/kie-server/services/rest/server -Ddashbuilder.kieserver.serverTemplate.sample-server.user=kieserver -Ddashbuilder.kieserver.serverTemplate.sample-server.password=kieserver1! -Ddashbuilder.kieserver.defaultServerTemplate=default -Ddashbuilder.kieserver.serverTemplate.sample-server.replace_query=true -Ddashbuilder.dev=true false org.jboss.errai.cdi.server.gwt.EmbeddedWildFlyLauncher src/main/webapp ${project.build.directory}/${project.build.finalName} true gwt-clean clean clean gwt-compile resources compile maven-war-plugin **/javax/**/*.*,**/client/**/*.class,**/*.symbolMap false maven-clean-plugin ${basedir} src/main/webapp/org.dashbuilder.DashbuilderRuntime/ src/main/webapp/WEB-INF/classes/ src/main/webapp/WEB-INF/deploy/ src/main/webapp/WEB-INF/lib/ **/gwt-unitCache/** .errai/ .niogit/** .index/** org.apache.maven.plugins maven-dependency-plugin unpack process-resources unpack org.jboss.errai wildfly-dist ${version.org.jboss.errai.wildfly} zip false ${project.build.directory} ${gwt.compiler.skip} fullProfile full org.codehaus.mojo gwt-maven-plugin org.dashbuilder.DashbuilderRuntime false true no-showcase org.codehaus.mojo gwt-maven-plugin true ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/DataSetContentListener.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.backend.helper.PartitionHelper; import org.dashbuilder.backend.services.dataset.RuntimeCSVFileStorage; import org.dashbuilder.backend.services.dataset.provider.RuntimeDataSetProviderRegistry; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.def.DataSetDefRegistry; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; import org.dashbuilder.kieserver.RemoteDataSetDef; import org.dashbuilder.shared.event.NewDataSetContentEvent; import org.dashbuilder.shared.event.RemovedRuntimeModelEvent; import org.dashbuilder.shared.model.DataSetContent; import org.dashbuilder.shared.model.DataSetContentType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Listen for new dataset contents and register it accordingly. * */ @ApplicationScoped public class DataSetContentListener { private final Logger logger = LoggerFactory.getLogger(DataSetContentListener.class); @Inject DataSetDefRegistry registry; @Inject RuntimeCSVFileStorage storage; @Inject RuntimeDataSetProviderRegistry runtimeDataSetProviderRegistry; DataSetDefJSONMarshaller defMarshaller; /** * Keep tracks of contents by runtime model to remove it later */ Map> runtimeModelDatasetContents; @PostConstruct public void init() { defMarshaller = runtimeDataSetProviderRegistry.getDataSetDefJSONMarshaller(); runtimeModelDatasetContents = new HashMap<>(); } public void register(@Observes NewDataSetContentEvent newDataSetContentEvent) { runtimeModelDatasetContents.put(newDataSetContentEvent.getRuntimeModelId(), newDataSetContentEvent.getContent() .stream() .map(DataSetContent::getId) .collect(Collectors.toList())); newDataSetContentEvent.getContent() .forEach(this::registerDataSetContent); } public void unregister(@Observes RemovedRuntimeModelEvent removedRuntimeModelEvent) { List removedIds = runtimeModelDatasetContents.remove(removedRuntimeModelEvent.getRuntimeModelId()); if (removedIds != null) { removedIds.forEach(id -> { storage.deleteCSVFile(id); registry.removeDataSetDef(id); }); } } public void registerDataSetContent(final DataSetContent content) { try { DataSetContentType contentType = content.getContentType(); switch (contentType) { case CSV: storage.storeCSV(content.getId(), content.getContent()); break; case DEFINITION: registerDataSetDefinition(content); break; default: logger.error("Unknown DataSet Content Type: {}", contentType.name(), null); break; } } catch (Exception e) { logger.error("Error registering dataset", e); } } private void registerDataSetDefinition(final DataSetContent content) throws Exception { try { DataSetDef dataSetDef = defMarshaller.fromJson(content.getContent()); dataSetDef.setUUID(content.getId()); if (dataSetDef instanceof RemoteDataSetDef) { String queryName = PartitionHelper.removePartition(dataSetDef.getUUID()); ((RemoteDataSetDef) dataSetDef).setQueryName(queryName); } registry.registerDataSetDef(dataSetDef); } catch (Exception e) { logger.warn("Ignoring Dataset {}: error parsing Json", content.getId()); logger.debug("Error parsing dataset {}. Content: {}", content.getId(), content.getContent(), e); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/ExternalComponentsContentListener.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.io.File; import java.nio.file.Paths; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.apache.commons.io.FileUtils; import org.dashbuilder.external.service.ComponentLoader; import org.dashbuilder.shared.event.RemovedRuntimeModelEvent; /** * When a runtime model is removed then we should remove components content as well. * */ @ApplicationScoped public class ExternalComponentsContentListener { @Inject ComponentLoader loader; @Inject RuntimeOptions options; public void onRuntimeModelRemoved(@Observes RemovedRuntimeModelEvent event) { if (options.isComponentPartition()) { String componentsDir = loader.getExternalComponentsDir(); String runtimeModelId = event.getRuntimeModelId(); if (componentsDir != null && runtimeModelId != null) { File runtimeModelComponentsFile = Paths.get(componentsDir, runtimeModelId).toFile(); FileUtils.deleteQuietly(runtimeModelComponentsFile); } } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/RuntimeModelListener.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import org.dashbuilder.shared.event.RemovedRuntimeModelEvent; import org.dashbuilder.shared.event.UpdatedRuntimeModelEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Register model events * */ @ApplicationScoped public class RuntimeModelListener { Logger logger = LoggerFactory.getLogger(RuntimeModelListener.class); public void logUpdatedModel(@Observes UpdatedRuntimeModelEvent modelUpdated) { logger.info("Updated dashboard {}", modelUpdated.getRuntimeModelId()); } public void logRemovedModel(@Observes RemovedRuntimeModelEvent modelUpdated) { logger.info("Removed dashboard {}", modelUpdated.getRuntimeModelId()); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/RuntimeModelLoader.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.shared.model.DashbuilderRuntimeMode; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.services.cdi.Startup; import static org.dashbuilder.backend.RuntimeOptions.DASHBOARD_EXTENSION; /** * Responsible for runtime model files loading. * */ @Startup @ApplicationScoped public class RuntimeModelLoader { Logger logger = LoggerFactory.getLogger(RuntimeModelLoader.class); @Inject RuntimeModelRegistry runtimeModelRegistry; @Inject RuntimeOptions runtimeOptions; @PostConstruct private void runtimeModelSetup() { setupBaseDir(); runtimeOptions.importFileLocation().ifPresent(importFile -> { logger.info("Importing file {}", importFile); runtimeModelRegistry.registerFile(importFile); runtimeModelRegistry.setMode(DashbuilderRuntimeMode.STATIC); }); if (runtimeOptions.isMultipleImport() && !runtimeOptions.importFileLocation().isPresent()) { runtimeModelRegistry.setMode(DashbuilderRuntimeMode.MULTIPLE_IMPORT); loadAvailableModels(); } } /** * Create, if do not exist, the base directory for runtime models */ protected void setupBaseDir() { Paths.get(runtimeOptions.getImportsBaseDir()).toFile().mkdirs(); } protected void loadAvailableModels() { logger.info("Registering existing models"); try (Stream walk = Files.walk(Paths.get(runtimeOptions.getImportsBaseDir()), 1)) { walk.filter(p -> p.toFile().isFile() && p.toString().toLowerCase().endsWith(DASHBOARD_EXTENSION)) .map(Object::toString) .forEach(p -> { logger.info("Registering {}", p); runtimeModelRegistry.registerFile(p); logger.info("Sucessfully Registered {}", p); }); } catch (Exception e) { throw new RuntimeException("Error registering existing models.", e); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/RuntimeModelWatcherServiceManager.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardWatchEventKinds; import java.nio.file.WatchEvent; import java.nio.file.WatchEvent.Kind; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.Optional; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; import javax.enterprise.concurrent.ManagedExecutorService; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.services.cdi.Startup; @Startup @ApplicationScoped public class RuntimeModelWatcherServiceManager { Logger logger = LoggerFactory.getLogger(RuntimeModelWatcherServiceManager.class); @Inject RuntimeOptions runtimeOptions; @Inject RuntimeModelRegistry registry; @Resource private ManagedExecutorService executorService; private WatchService watchService; @PostConstruct public void start() { if (runtimeOptions.isWatchModels()) { logger.info("Scheduling model watcher"); executorService.execute(() -> { try { createWatcherTask(runtimeOptions.getImportsBaseDir()); } catch (IOException e) { logger.error("Error setting models watcher: {}", e.getMessage()); logger.debug("Error setting models watcher.", e); throw new RuntimeException(e); } catch (InterruptedException e) { logger.warn("Thread Interrupted!", e); Thread.currentThread().interrupt(); } }); } else { logger.info("Not watching for model changes."); } } @SuppressWarnings("unchecked") public void createWatcherTask(String baseDir) throws IOException, InterruptedException { Path baseDirPath = Paths.get(baseDir); logger.info("Watching models directory for changes"); watchService = FileSystems.getDefault().newWatchService(); baseDirPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); WatchKey key; while ((key = watchService.take()) != null) { for (WatchEvent event : key.pollEvents()) { final Kind kind = event.kind(); if (kind == StandardWatchEventKinds.OVERFLOW) { continue; } WatchEvent ev = (WatchEvent) event; Path modelPath = ev.context(); String modelId = modelPath.toFile().getName().replaceAll(RuntimeOptions.DASHBOARD_EXTENSION, ""); if (kind == StandardWatchEventKinds.ENTRY_DELETE) { unregister(modelId); } if (kind == StandardWatchEventKinds.ENTRY_MODIFY) { unregister(modelId); register(modelId); } if (kind == StandardWatchEventKinds.ENTRY_CREATE) { register(modelId); } key.reset(); } } } private void unregister(String modelId) { try { registry.unregister(modelId); } catch (Exception e) { logger.error("Error unregistering model {}", e.getMessage()); logger.debug("Error unregistering model", e); } } private void register(String modelId) { Optional modelPathOp = runtimeOptions.modelPath(modelId); if (modelPathOp.isPresent()) { try { String modelPath = modelPathOp.get(); registry.registerFile(modelPath); } catch (Exception e) { logger.error("Error registering model {}", e.getMessage()); logger.debug("Error registering model", e); } } else { logger.info("File for model {} not found.", modelId); } } @PreDestroy public void stop() { try { if (watchService != null) { watchService.close(); } } catch (IOException e) { logger.warn("Error stopping watch service: {}", e.getMessage()); logger.debug("Error stopping watch service.", e); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/RuntimeOptions.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.data.Pair; /** * Holds Runtime System properties and information. * */ @ApplicationScoped public class RuntimeOptions { Logger logger = LoggerFactory.getLogger(RuntimeOptions.class); public static final String DASHBOARD_EXTENSION = ".zip"; private static final String DEFAULT_MODEL_DIR = "/tmp/dashbuilder/models"; private static final int DEFAULT_UPLOAD_SIZE_KB = 10 * 1024 * 1024; /** * Base Directory where dashboards ZIPs are stored */ private static final String IMPORTS_BASE_DIR_PROP = "dashbuilder.import.base.dir"; /** * Set a static dashboard to run with runtime. When this property is set no new imports are allowed. */ private static final String IMPORT_FILE_LOCATION_PROP = "dashbuilder.runtime.import"; /** * Limits the size of uploaded dashboards (in kb). */ private static final String UPLOAD_SIZE_PROP = "dashbuilder.runtime.upload.size"; /** * When true will allow download of external (remote) files into runtime. */ private static final String ALLOW_EXTERNAL_FILE_REGISTER_PROP = "dashbuilder.runtime.allowExternal"; /** * If set to true Runtime will always allow use of new imports (multi tenancy) */ private static final String DASHBUILDER_RUNTIME_MULTIPLE_IMPORT_PROP = "dashbuilder.runtime.multi"; /** * If true datasets IDs will partitioned by the Runtime Model ID. */ private static final String DATASET_PARTITION_PROP = "dashbuilder.dataset.partition"; /** * If true components will be partitioned by the Runtime Model ID. */ private static final String COMPONENT_PARTITION_PROP = "dashbuilder.components.partition"; /** * Boolean property that allows Runtime to check model last update in FS to update its content. */ private static final String MODEL_UPDATE_PROP = "dashbuilder.model.update"; /** * Boolean property when true will also remove actual model file from file system. */ private static final String MODEL_FILE_REMOVAL_PROP = "dashbuilder.removeModelFile"; /** * Boolean property when true will make Dashbuilder Runtime run on dev mode. */ private static final String DEV_MODE_PROP = "dashbuilder.dev"; /** * Boolean property when true will make dashbuilder watch the models dir to dynamically import models */ private static final String WATCH_MODELS_PROP = "dashbuilder.models.watch"; private boolean multipleImport; private boolean datasetPartition; private boolean componentPartition; private boolean allowExternal; private boolean modelUpdate; private boolean removeModelFile; private boolean devMode; boolean watchModels; private String importFileLocation; private String importsBaseDir; private int uploadSize; @PostConstruct public void init() { importFileLocation = System.getProperty(IMPORT_FILE_LOCATION_PROP); importsBaseDir = System.getProperty(IMPORTS_BASE_DIR_PROP, DEFAULT_MODEL_DIR); multipleImport = booleanProp(DASHBUILDER_RUNTIME_MULTIPLE_IMPORT_PROP, Boolean.FALSE); allowExternal = booleanProp(ALLOW_EXTERNAL_FILE_REGISTER_PROP, Boolean.FALSE); datasetPartition = booleanProp(DATASET_PARTITION_PROP, Boolean.TRUE); componentPartition = booleanProp(COMPONENT_PARTITION_PROP, Boolean.TRUE); modelUpdate = booleanProp(MODEL_UPDATE_PROP, Boolean.TRUE); removeModelFile = booleanProp(MODEL_FILE_REMOVAL_PROP, Boolean.FALSE); devMode = booleanProp(DEV_MODE_PROP, Boolean.FALSE); watchModels = booleanProp(WATCH_MODELS_PROP, Boolean.FALSE); uploadSize = DEFAULT_UPLOAD_SIZE_KB; String uploadSizeStr = System.getProperty(UPLOAD_SIZE_PROP); if (uploadSizeStr != null) { try { uploadSize = 1024 * Integer.parseInt(uploadSizeStr); } catch (Exception e) { logger.warn("Not able to parse upload size {}", uploadSizeStr); logger.debug("Not able to parse upload size {}", uploadSizeStr, e); } } logger.info("Max upload size is {}", uploadSize); } /** * * Returns the model path for the given id * @param id * The model ID * @return * An optional containing the file path or an empty optional otherwise. */ public Optional modelPath(String id) { String filePath = buildFilePath(id); return Paths.get(filePath).toFile().exists() ? Optional.of(filePath) : Optional.empty(); } /** * Generates a new valid file path. * @param fileName * The fileName * @return */ public Pair newFilePath(final String fileName) { String newFileName = fileName; if (fileName == null || fileName.trim().isEmpty()) { newFileName = System.currentTimeMillis() + ""; } else if (fileName.endsWith(DASHBOARD_EXTENSION)) { int lastIndex = fileName.length() - DASHBOARD_EXTENSION.length(); newFileName = fileName.substring(0, lastIndex); } String filePath = buildFilePath(newFileName); return Pair.newPair(newFileName, filePath); } public boolean isMultipleImport() { return multipleImport; } public Optional importFileLocation() { return Optional.ofNullable(importFileLocation); } public String getImportsBaseDir() { return importsBaseDir; } public int getUploadSize() { return uploadSize; } public boolean isAllowExternal() { return allowExternal; } public boolean isDatasetPartition() { return datasetPartition; } public boolean isComponentPartition() { return componentPartition; } public boolean isModelUpdate() { // dev mode forces model update return modelUpdate || devMode; } public boolean isRemoveModelFile() { return removeModelFile; } public boolean isDevMode() { return devMode; } public boolean isWatchModels() { // dev mode requires to watch models return watchModels || devMode; } public String buildFilePath(String fileId) { Path modelFile = Paths.get(fileId + DASHBOARD_EXTENSION); return Paths.get(getImportsBaseDir()).resolve(modelFile).toString(); } private boolean booleanProp(String prop, Boolean defaultValue) { String propStr = System.getProperty(prop, defaultValue.toString()); return Boolean.parseBoolean(propStr); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/ServerSideProducers.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.inject.Inject; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.service.AuthenticationService; import org.uberfire.annotations.Customizable; import org.uberfire.annotations.FallbackImplementation; import org.uberfire.preferences.client.store.PreferenceBeanStoreClientImpl; import org.uberfire.preferences.shared.PreferenceScopeResolutionStrategy; import org.uberfire.preferences.shared.UsernameProvider; import org.uberfire.preferences.shared.bean.PreferenceBeanStore; import org.uberfire.preferences.shared.impl.DefaultPreferenceScopeResolutionStrategy; import org.uberfire.rpc.SessionInfo; import org.uberfire.rpc.impl.SessionInfoImpl; @ApplicationScoped public class ServerSideProducers { @Inject @FallbackImplementation DefaultPreferenceScopeResolutionStrategy defaultPreferenceScopeResolutionStrategy; @Produces @ApplicationScoped public User produceUser() { return User.ANONYMOUS; } @Produces @ApplicationScoped public SessionInfo produceSessionInfo() { return new SessionInfoImpl(); } @Produces @ApplicationScoped public PreferenceBeanStore producePreferenceBeanStore() { return new PreferenceBeanStoreClientImpl(); } @Produces @Customizable @ApplicationScoped public PreferenceScopeResolutionStrategy producePreferenceScopeResolutionStrategy() { return defaultPreferenceScopeResolutionStrategy; } @Produces @ApplicationScoped public UsernameProvider produceUsernameProvider() { return () -> User.ANONYMOUS.getIdentifier(); } @Produces @ApplicationScoped public AuthenticationService produceAuthenticationService() { return new AuthenticationService() { @Override public void logout() { // not used } @Override public User login(String username, String password) { return null; } @Override public boolean isLoggedIn() { return false; } @Override public User getUser() { return User.ANONYMOUS; } }; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/gzip/GzipFilter.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.gzip; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import static javax.ws.rs.core.HttpHeaders.ACCEPT_ENCODING; // NOTE: Brought this from uberfire-backend-server public class GzipFilter implements Filter { static final String GZIP = "gzip"; static final String ORG_UBERFIRE_GZIP_ENABLE = "org.uberfire.gzip.enable"; public void init(final FilterConfig filterConfig) { // Empty on purpose } public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException { switch (getAction(req)) { case HALT: break; case DO_NOT_ACCEPT_GZIP: case DO_NOT_COMPRESS: chain.doFilter(req, res); break; case COMPRESS: compressAndContinue(req, (HttpServletResponse) res, chain); break; } } void compressAndContinue(final ServletRequest req, final HttpServletResponse res, final FilterChain chain) throws IOException, ServletException { final GzipHttpServletResponseWrapper wResponse = new GzipHttpServletResponseWrapper(res); chain.doFilter(req, wResponse); wResponse.close(); } Action getAction(final ServletRequest req) { final String enabled = System.getProperty(ORG_UBERFIRE_GZIP_ENABLE); if (enabled != null && !enabled.equals("true")) { return Action.DO_NOT_COMPRESS; } if (!(req instanceof HttpServletRequest)) { return Action.HALT; } final String acceptEncodingHeader = ((HttpServletRequest) req).getHeader(ACCEPT_ENCODING); if (acceptEncodingHeader == null || !acceptEncodingHeader.contains(GZIP)) { return Action.DO_NOT_ACCEPT_GZIP; } return Action.COMPRESS; } public void destroy() { // Empty on purpose } enum Action { HALT, DO_NOT_COMPRESS, DO_NOT_ACCEPT_GZIP, COMPRESS; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/gzip/GzipHttpServerResponseWrapper.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.gzip; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; class GzipHttpServletResponseWrapper extends HttpServletResponseWrapper { private HttpServletResponse response; private ServletOutputStream stream; private PrintWriter writer; GzipHttpServletResponseWrapper(final HttpServletResponse response) { super(response); this.response = response; this.stream = null; this.writer = null; } @Override public void flushBuffer() throws IOException { stream.flush(); } @Override public ServletOutputStream getOutputStream() throws IOException { if (writer != null) { throw new IllegalStateException("getOutputStream() was already called"); } if (stream == null) { stream = createOutputStream(); } return stream; } @Override public PrintWriter getWriter() throws IOException { if (writer != null) { return writer; } if (stream != null) { throw new IllegalStateException("getWriter() was already called"); } stream = createOutputStream(); writer = new PrintWriter(new OutputStreamWriter(stream, StandardCharsets.UTF_8)); return writer; } @Override public void setContentLength(final int length) { // Empty on purpose } private ServletOutputStream createOutputStream() throws IOException { return new GzipResponseServletOutputStream(response); } void close() { try { if (writer != null) { writer.close(); } else if (stream != null) { stream.close(); } } catch (final IOException e) { // Error on closing writer or stream. } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/gzip/GzipOutputStream.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.gzip; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; class GzipResponseServletOutputStream extends ServletOutputStream { private static final String CONTENT_LENGTH_HEADER = "Content-Length"; private static final String CONTENT_ENCODING_HEADER = "Content-Encoding"; private ByteArrayOutputStream baos; private GZIPOutputStream gzipStream; private HttpServletResponse response; private ServletOutputStream outputStream; private boolean closed; GzipResponseServletOutputStream(final HttpServletResponse response) throws IOException { super(); this.closed = false; this.response = response; this.outputStream = response.getOutputStream(); this.baos = new ByteArrayOutputStream(); this.gzipStream = new GZIPOutputStream(baos); } @Override public void close() throws IOException { if (closed) { return; } gzipStream.finish(); final byte[] bytes = baos.toByteArray(); response.addHeader(CONTENT_LENGTH_HEADER, Integer.toString(bytes.length)); response.addHeader(CONTENT_ENCODING_HEADER, GzipFilter.GZIP); outputStream.write(bytes); outputStream.flush(); outputStream.close(); closed = true; } @Override public void flush() throws IOException { if (closed) { return; } gzipStream.flush(); } @Override public void write(final int b) throws IOException { if (closed) { throw new IOException("Output stream already closed."); } gzipStream.write((byte) b); } @Override public void write(final byte[] data) throws IOException { write(data, 0, data.length); } @Override public void write(final byte[] data, final int offset, final int length) throws IOException { if (closed) { throw new IOException("Output stream already closed."); } gzipStream.write(data, offset, length); } @Override public boolean isReady() { return true; } @Override public void setWriteListener(final WriteListener writeListener) { // Empty on purpose } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/health/HealthService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.health; import javax.annotation.security.PermitAll; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; /** * Service that reports if Runtime is ready and healthy. * */ @Path("/") public class HealthService { private static final String SUCCESS_RESPONSE = "{\"success\": true}"; @GET @PermitAll @Path("/ready") @Produces(APPLICATION_JSON) public String ready() { return SUCCESS_RESPONSE; } @GET @PermitAll @Path("/healthy") @Produces(APPLICATION_JSON) public String alive() { return SUCCESS_RESPONSE; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/helper/PartitionHelper.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.helper; public class PartitionHelper { private static final String PARTITION_SEPARATOR = "|"; private PartitionHelper() { // empty } public static String partition(String modelId, String id) { return id + PARTITION_SEPARATOR + " RuntimeModel=" + modelId; } public static String removePartition(String id) { if (id != null) { int sepatorIndex = id.indexOf(PARTITION_SEPARATOR); if (sepatorIndex > -1) { return id.substring(0, sepatorIndex); } } return id; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/navigation/RuntimeNavigationBuilder.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.navigation; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemContext; import org.dashbuilder.navigation.NavItemVisitor; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.json.NavTreeJSONMarshaller; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; /** * Builds the navigation for Dashbuilder Runtime * */ @ApplicationScoped public class RuntimeNavigationBuilder { static final String ORPHAN_GROUP_ID = "__runtime_dashboards"; static final String ORPHAN_GROUP_NAME = "Runtime Dashboards"; static final String ORPHAN_GROUP_DESC = "Dashboards"; Logger logger = LoggerFactory.getLogger(RuntimeNavigationBuilder.class); public NavTree build(Optional navTreeJson, List layoutTemplates) { if (navTreeJson.isPresent()) { NavTree navTree = NavTreeJSONMarshaller.get().fromJson(navTreeJson.get()); return buildRuntimeTree(navTree, layoutTemplates); } return navTreeForTemplates(layoutTemplates); } protected NavTree buildRuntimeTree(NavTree navTree, List layoutTemplates) { RuntimeNavItemVisitor visitor = new RuntimeNavItemVisitor(layoutTemplates); navTree.accept(visitor); List groups = visitor.getGroups(); List notExported = visitor.getNotExportedPerspectives(); List orphanTemplates = visitor.getOrphanItems(); groups.forEach(grp -> grp.getChildren().removeIf(i -> notExported.contains(i.getId()))); groups.removeIf(grp -> grp.getChildren().isEmpty()); NavTreeBuilder builder = new NavTreeBuilder(); if (!orphanTemplates.isEmpty()) { logger.info("Found {} layout components without a group", orphanTemplates.size()); buildLayoutTemplatesGroup(orphanTemplates, builder); } NavTree runtimeNavTree = builder.build(); runtimeNavTree.getRootItems().addAll(groups); return runtimeNavTree; } private NavTree navTreeForTemplates(List layoutTemplates) { NavTreeBuilder treeBuilder = new NavTreeBuilder(); return buildLayoutTemplatesGroup(layoutTemplates, treeBuilder).build(); } private NavTreeBuilder buildLayoutTemplatesGroup(List layoutTemplates, NavTreeBuilder treeBuilder) { treeBuilder.group(ORPHAN_GROUP_ID, ORPHAN_GROUP_NAME, ORPHAN_GROUP_DESC, false); layoutTemplates.forEach(lt -> { NavItemContext ctx = NavWorkbenchCtx.perspective(lt.getName()); treeBuilder.item(lt.getName(), lt.getName(), "", true, ctx); }); treeBuilder.endGroup(); return treeBuilder; } List checkOrphansLayoutTemplates(NavTree navTree, List layoutTemplates) { return layoutTemplates.stream() .filter(lt -> navTree.getItemById(lt.getName()) == null) .collect(Collectors.toList()); } /** * * Remove groups with child groups that have no children * @param navGroup * @param originTree */ void removedEmptyNestedGroups(NavGroup navGroup, List itemsToRemove) { filteringGroups(navGroup.getChildren()).forEach(group -> removedEmptyNestedGroups(group, itemsToRemove)); if (navGroup.getChildren().isEmpty()) { logger.info("Removing groups {}", navGroup.getName()); itemsToRemove.add(navGroup.getId()); } } Stream filteringGroups(List items) { return items.stream() .filter(item -> item instanceof NavGroup) .map(item -> (NavGroup) item); } /** * Collects non empty groups and create a flatten tree (all groups as root items). * */ class RuntimeNavItemVisitor implements NavItemVisitor { List groups; List layoutTemplates; List orphanItems; List notExportedPerspectives; public RuntimeNavItemVisitor(List layoutTemplates) { this.groups = new ArrayList<>(); this.notExportedPerspectives = new ArrayList<>(); this.orphanItems = new ArrayList<>(layoutTemplates); this.layoutTemplates = layoutTemplates; } @Override public void visitGroup(NavGroup group) { if (!group.getChildren().isEmpty()) { NavGroup clonnedGroup = (NavGroup) group.cloneItem(); clonnedGroup.setParent(null); clonnedGroup.getChildren().removeIf(item -> item instanceof NavGroup); groups.add(clonnedGroup); } } @Override public void visitItem(NavItem item) { String resourceId = NavWorkbenchCtx.get(item.getContext()).getResourceId(); if (layoutTemplates.stream().noneMatch(lt -> lt.getName().equals(resourceId))) { notExportedPerspectives.add(item.getId()); } orphanItems.stream() .filter(lt -> lt.getName().equals(resourceId)) .findFirst().ifPresent(notOrphanItem -> orphanItems.remove(notOrphanItem)); } @Override public void visitDivider(NavDivider divider) { // do nothing } public List getGroups() { return groups; } public List getOrphanItems() { return orphanItems; } public List getNotExportedPerspectives() { return notExportedPerspectives; } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/RuntimeModelServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.backend.RuntimeOptions; import org.dashbuilder.backend.navigation.RuntimeNavigationBuilder; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.model.RuntimeServiceResponse; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.dashbuilder.shared.service.RuntimeModelService; import org.dashbuilder.shared.services.ExternalImportService; import org.jboss.errai.bus.server.annotations.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Service @ApplicationScoped public class RuntimeModelServiceImpl implements RuntimeModelService { Logger logger = LoggerFactory.getLogger(RuntimeModelServiceImpl.class); @Inject RuntimeModelRegistry registry; @Inject RuntimeNavigationBuilder runtimeNavigationBuilder; @Inject RuntimeOptions runtimeOptions; @Inject ExternalImportService externalImportService; @Override public RuntimeServiceResponse info(String runtimeModelId) { List availableModels = new ArrayList<>(registry.availableModels()); return new RuntimeServiceResponse(registry.getMode(), getRuntimeModel(runtimeModelId), availableModels); } @Override public Optional getRuntimeModel(String exportId) { if (!registry.acceptingNewImports()) { return registry.single(); } if (exportId == null || exportId.trim().isEmpty()) { return Optional.empty(); } return loadImportById(exportId); } /** * Attempts to load a model which could be a local file, an already loaded model or an external file. * @param id * The model id or path * @return * An optional containing the loaded model or empty. */ private Optional loadImportById(String id) { Optional runtimeModelOp = registry.get(id); if (runtimeModelOp.isPresent()) { return loadLatestModel(id, runtimeModelOp.get()); } Optional modelPath = runtimeOptions.modelPath(id); if (modelPath.isPresent()) { return registry.registerFile(modelPath.get()); } if (runtimeOptions.isAllowExternal()) { return externalImportService.registerExternalImport(id); } return Optional.empty(); } private Optional loadLatestModel(String id, RuntimeModel runtimeModel) { Optional modelPath = runtimeOptions.modelPath(id); if (runtimeOptions.isModelUpdate() && modelPath.isPresent()) { String modelFilePath = modelPath.get(); if (lastModified(modelFilePath) > runtimeModel.getLastModified()) { logger.info("Replacing model {}", id); registry.unregister(id); return registry.registerFile(modelFilePath); } } return Optional.of(runtimeModel); } private long lastModified(String modelFilePath) { try { return Files.readAttributes(Paths.get(modelFilePath), BasicFileAttributes.class) .lastModifiedTime() .toMillis(); } catch (IOException e) { logger.error("Error reading file last modified time"); logger.debug("Error reading file last modified time", e); return -1; } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/dataset/RuntimeDataSetLookupServices.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services.dataset; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetManager; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.service.DataSetLookupServices; import org.jboss.errai.bus.server.annotations.Service; @Service @ApplicationScoped public class RuntimeDataSetLookupServices implements DataSetLookupServices { @Inject DataSetManager manager; public RuntimeDataSetLookupServices() { // not used, but must exist } @Override public DataSet lookupDataSet(DataSetLookup lookup) throws Exception { return manager.lookupDataSet(lookup); } @Override public DataSet lookupDataSet(DataSetDef def, DataSetLookup lookup) throws Exception { return manager.lookupDataSet(lookup); } @Override public DataSetMetadata lookupDataSetMetadata(String uuid) throws Exception { return manager.getDataSetMetadata(uuid); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/dummy/DummyBackendExperimentalFeatureDefRegistry.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services.dummy; import java.util.Collection; import java.util.Collections; import javax.enterprise.context.ApplicationScoped; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.experimental.service.backend.BackendExperimentalFeatureDefRegistry; import org.uberfire.experimental.service.definition.ExperimentalFeatureDefinition; @Service @ApplicationScoped public class DummyBackendExperimentalFeatureDefRegistry implements BackendExperimentalFeatureDefRegistry { @Override public ExperimentalFeatureDefinition getFeatureById(String definitionId) { return null; } @Override public Collection getAllFeatures() { return Collections.emptyList(); } @Override public Collection getGlobalFeatures() { return Collections.emptyList(); } @Override public Collection getUserFeatures() { return Collections.emptyList(); } @Override public Collection loadFeatureDefinitions(Collection clientDefinitions) { return Collections.emptyList(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/dummy/DummyBackendExperimentalFeaturesRegistryService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services.dummy; import java.util.Collections; import javax.enterprise.context.ApplicationScoped; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.experimental.service.backend.BackendExperimentalFeaturesRegistryService; import org.uberfire.experimental.service.backend.ExperimentalFeaturesSession; import org.uberfire.experimental.service.backend.impl.ExperimentalFeaturesSessionImpl; import org.uberfire.experimental.service.registry.impl.ExperimentalFeaturesRegistryImpl; @Service @ApplicationScoped public class DummyBackendExperimentalFeaturesRegistryService implements BackendExperimentalFeaturesRegistryService{ @Override public ExperimentalFeaturesSession getExperimentalFeaturesSession() { ExperimentalFeaturesSessionImpl session = new ExperimentalFeaturesSessionImpl(); session.setRegistry(new ExperimentalFeaturesRegistryImpl(Collections.emptyList())); return session; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/dummy/DummyPerspectiveServices.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services.dummy; import java.util.Collection; import java.util.Collections; import javax.enterprise.context.ApplicationScoped; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.backend.vfs.Path; import org.uberfire.ext.editor.commons.file.DefaultMetadata; import org.uberfire.ext.layout.editor.api.PerspectiveServices; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate.Style; import org.uberfire.ext.plugin.model.Plugin; @Service @ApplicationScoped public class DummyPerspectiveServices implements PerspectiveServices { @Override public Path copy(Path path, String newName, String comment) { return null; } @Override public Path copy(Path path, String newName, Path targetDirectory, String comment) { return null; } @Override public void delete(Path path, String comment) { // ignored } @Override public Path saveAndRename(Path path, String newFileName, DefaultMetadata metadata, LayoutTemplate content, String comment) { return null; } @Override public Path rename(Path path, String newName, String comment) { return null; } @Override public Path save(Path path, LayoutTemplate content, DefaultMetadata metadata, String comment) { return null; } @Override public Plugin createNewPerspective(String name, Style style) { return null; } @Override public Collection listLayoutTemplates() { return Collections.emptyList(); } @Override public LayoutTemplate getLayoutTemplate(String perspectiveName) { return null; } @Override public LayoutTemplate getLayoutTemplate(Path perspectivePath) { return null; } @Override public LayoutTemplate getLayoutTemplate(Plugin perspectivePlugin) { return null; } @Override public LayoutTemplate convertToLayoutTemplate(String layoutModel) { return null; } @Override public Path saveLayoutTemplate(Path perspectivePath, LayoutTemplate layoutTemplate, String commitMessage) { return null; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/dummy/DummyPluginServices.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services.dummy; import java.util.Collection; import java.util.Collections; import javax.enterprise.context.ApplicationScoped; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.backend.vfs.Path; import org.uberfire.ext.editor.commons.file.DefaultMetadata; import org.uberfire.ext.plugin.model.DynamicMenu; import org.uberfire.ext.plugin.model.LayoutEditorModel; import org.uberfire.ext.plugin.model.Media; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.ext.plugin.model.PluginContent; import org.uberfire.ext.plugin.model.PluginType; import org.uberfire.ext.plugin.model.RuntimePlugin; import org.uberfire.ext.plugin.service.PluginServices; /** * This should be removed as soon as PluginServices cliend side mocked service starts working. * */ @Service @ApplicationScoped public class DummyPluginServices implements PluginServices { @Override public void delete(Path path, String comment) { // not used } @Override public Path copy(Path path, String newName, String comment) { return null; } @Override public Path copy(Path path, String newName, Path targetDirectory, String comment) { return null; } @Override public Path saveAndRename(Path path, String newFileName, DefaultMetadata metadata, Plugin content, String comment) { return null; } @Override public Path rename(Path path, String newName, String comment) { return null; } @Override public Path save(Path path, Plugin content, DefaultMetadata metadata, String comment) { return null; } @Override public String getMediaServletURI() { return null; } @Override public Collection listRuntimePlugins() { return Collections.emptyList(); } @Override public Collection listPluginRuntimePlugins(Path pluginPath) { return Collections.emptyList(); } @Override public Collection listPlugins() { return Collections.emptyList(); } @Override public Collection listPlugins(PluginType type) { return Collections.emptyList(); } @Override public Plugin createNewPlugin(String name, PluginType type) { return null; } @Override public PluginContent getPluginContent(Path path) { return null; } @Override public void deleteMedia(Media media) { // not used } @Override public DynamicMenu getDynamicMenuContent(Path path) { return null; } @Override public Path save(Plugin plugin, String commitMessage) { return null; } @Override public LayoutEditorModel getLayoutEditor(Path path, PluginType pluginType) { return null; } @Override public Path saveMenu(DynamicMenu menu, String commitMessage) { return null; } @Override public Path saveLayout(LayoutEditorModel layoutContent, String commitMessage) { return null; } @Override public Collection listDynamicMenus() { return Collections.emptyList(); } @Override public Collection listLayoutEditor(PluginType pluginType) { return Collections.emptyList(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/dummy/DummyRendererSettingsService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services.dummy; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.renderer.RendererSettings; import org.dashbuilder.renderer.service.RendererSettingsService; import org.jboss.errai.bus.server.annotations.Service; @Service @ApplicationScoped public class DummyRendererSettingsService implements RendererSettingsService { @Override public RendererSettings getSettings() { return new RendererSettings(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/remote/services/dummy/DummyRuntimePluginService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.remote.services.dummy; import java.util.Collection; import java.util.Collections; import java.util.List; import javax.enterprise.context.ApplicationScoped; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.backend.plugin.RuntimePlugin; import org.uberfire.backend.plugin.RuntimePluginService; @Service @ApplicationScoped public class DummyRuntimePluginService implements RuntimePluginService { @Override public Collection listFrameworksContent() { return Collections.emptyList(); } @Override public Collection listPluginsContent() { return Collections.emptyList(); } @Override public String getTemplateContent(String url) { return ""; } @Override public String getRuntimePluginTemplateContent(String url) { return ""; } @Override public List getRuntimePlugins() { return Collections.emptyList(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/resources/FileUploadModel.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.resources; import javax.ws.rs.FormParam; import org.jboss.resteasy.annotations.providers.multipart.PartType; /** * File sent by upload. * */ public class FileUploadModel { private byte[] fileData; private String fileName; public byte[] getFileData() { return fileData; } public String getFileName() { return fileName; } @FormParam("inputFileName") public void setFileName(final String fileName) { this.fileName = fileName; } @FormParam("selectedFile") @PartType("application/octet-stream") public void setFileData(final byte[] fileData) { this.fileData = fileData; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/resources/RuntimeJaxApp.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.resources; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("/rest") public class RuntimeJaxApp extends Application { } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/resources/UploadResourceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.resources; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Optional; import java.util.stream.Stream; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.apache.commons.io.IOUtils; import org.dashbuilder.backend.RuntimeOptions; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.jboss.resteasy.annotations.providers.multipart.MultipartForm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.data.Pair; import static org.dashbuilder.backend.RuntimeOptions.DASHBOARD_EXTENSION; /** * Resource to receive new imports. * */ @Path("/upload") @ApplicationScoped public class UploadResourceImpl { Logger logger = LoggerFactory.getLogger(UploadResourceImpl.class); @Inject RuntimeOptions runtimeOptions; @Inject RuntimeModelRegistry runtimeModelRegistry; @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadFile(@MultipartForm FileUploadModel form) throws IOException { byte[] inputBytes = form.getFileData(); checkInputSize(inputBytes); Optional dashboardOp = checkForExistingFile(inputBytes); if (dashboardOp.isPresent()) { String dashboardName = dashboardOp.get(); logger.info("Found existing file with same contents: {}", dashboardName); if (runtimeModelRegistry.get(dashboardName).isPresent()) { return Response.status(Status.CONFLICT).entity(dashboardName).build(); } else { return registerExistingFile(dashboardName); } } return registerNewFile(form.getFileName(), inputBytes); } /** * Reads the uploaded model bytes controlling the size and throwing exception when the size exceeds the allowed size. * @param fileData * @return */ private void checkInputSize(byte[] bytes) { if (bytes.length > runtimeOptions.getUploadSize()) { logger.debug("Total size {} is greater than the allowed size {}", bytes.length, runtimeOptions.getUploadSize()); throw new WebApplicationException("Upload size is greater than the allowed size: " + runtimeOptions.getUploadSize(), Response.Status.BAD_REQUEST); } } /** * * If a file exists with a given size then probably it is a repeated. * * @param uploadSize * @return * @throws IOException */ private Optional checkForExistingFile(byte[] uploadedFile) throws IOException { try (Stream walk = Files.walk(Paths.get(runtimeOptions.getImportsBaseDir()), 1)) { return walk .filter(p -> p.toFile().isFile() && p.toString().toLowerCase().endsWith(DASHBOARD_EXTENSION) && isContentEquals(uploadedFile, p)) .map(p -> p.getFileName().toString().replace(DASHBOARD_EXTENSION, "")) .findFirst(); } catch (Exception e) { logger.info("Error checking for duplicated file contents."); logger.debug("Error checking for duplicated file contents.", e); return Optional.empty(); } } private boolean isContentEquals(byte[] uploadedFile, java.nio.file.Path p) { try (InputStream fis = Files.newInputStream(p)) { return IOUtils.contentEquals(fis, new ByteArrayInputStream(uploadedFile)); } catch (IOException e) { logger.debug("Error checking file {}. Skipping from verification.", p, e); } return false; } private Response registerNewFile(String fileName, byte[] inputBytes) throws IOException { Pair newImportInfo = runtimeOptions.newFilePath(fileName); java.nio.file.Path path = Paths.get(newImportInfo.getK2()); Files.write(path, inputBytes); try { runtimeModelRegistry.registerFile(newImportInfo.getK2()); } catch (Exception e) { Files.delete(path); logger.error("Error uploading file", e); return Response.status(Response.Status.BAD_REQUEST) .entity(e.getMessage()) .build(); } return Response.ok(newImportInfo.getK1()).build(); } private Response registerExistingFile(String dashboardName) { String filePath = runtimeOptions.buildFilePath(dashboardName); runtimeModelRegistry.registerFile(filePath); return Response.ok(dashboardName).build(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/resources/api/DashbuilderRuntimeResource.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.resources.api; import java.io.IOException; import java.util.Optional; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.dashbuilder.backend.resources.FileUploadModel; import org.dashbuilder.backend.resources.UploadResourceImpl; import org.dashbuilder.backend.services.RuntimeInfoService; import org.dashbuilder.shared.model.DashboardInfo; import org.dashbuilder.shared.model.DashbuilderRuntimeInfo; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.jboss.resteasy.annotations.providers.multipart.MultipartForm; @Path("api/") @Produces(MediaType.APPLICATION_JSON) public class DashbuilderRuntimeResource { private static final String DASHBOARD_BASE_URI = "dashboard"; private static final String DASHBOARD_ID_URI = DASHBOARD_BASE_URI + "/{id}"; @Inject RuntimeInfoService runtimeInfoService; @Inject UploadResourceImpl uploadResourceImpl; @Inject RuntimeModelRegistry registry; @GET public DashbuilderRuntimeInfo info() { return runtimeInfoService.info(); } @GET @Path(DASHBOARD_ID_URI) public Response dashboard(@PathParam("id") String id) { return runtimeInfoService.dashboardInfo(id) .map(info -> Response.ok().entity(info).build()) .orElse(Response.status(Status.NOT_FOUND).build()); } @POST @Path(DASHBOARD_BASE_URI) @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadResource(@MultipartForm FileUploadModel form) throws IOException { return uploadResourceImpl.uploadFile(form); } @DELETE @Path(DASHBOARD_BASE_URI) public void removeAll() { registry.clear(); } @DELETE @Path(DASHBOARD_ID_URI) public Response remove(@PathParam("id") String id) { Optional dashboardInfo = runtimeInfoService.dashboardInfo(id); if (dashboardInfo.isPresent()) { registry.remove(id); return Response.ok().build(); } else { return Response.status(Status.NOT_FOUND).build(); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/security/BasicAuthSecurityFilter.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.security; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import javax.inject.Inject; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.google.common.base.Charsets; import org.apache.commons.codec.binary.Base64; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.exception.FailedAuthenticationException; import org.jboss.errai.security.shared.service.AuthenticationService; import static java.util.stream.Collectors.toSet; import static org.apache.commons.lang3.StringUtils.isBlank; public class BasicAuthSecurityFilter implements Filter { public static final String REALM_NAME_PARAM = "realmName"; public static final String INVALIDATE_PARAM = "invalidate"; public static final String EXCEPTION_PATHS = "excludedPaths"; public static final String ALLOW_OPTIONS = "allowOptions"; private static final String OPTIONS = "OPTIONS"; @Inject AuthenticationService authenticationService; private String realmName = "UberFire Security Extension Default Realm"; private Boolean invalidate = true; private Boolean allowOptions = true; private Set excludedPaths = new HashSet<>(); @Override public void init(final FilterConfig filterConfig) { final String realmName = filterConfig.getInitParameter(REALM_NAME_PARAM); if (realmName != null) { this.realmName = realmName; } final String invalidate = filterConfig.getInitParameter(INVALIDATE_PARAM); if (invalidate != null) { this.invalidate = Boolean.valueOf(invalidate); } final String excludedPaths = filterConfig.getInitParameter(EXCEPTION_PATHS); if (excludedPaths != null) { this.excludedPaths = Arrays.stream(excludedPaths.split(",")).filter(s -> !isBlank(s)).collect(toSet()); } final String allowOptions = filterConfig.getInitParameter(ALLOW_OPTIONS); if (allowOptions != null) { this.allowOptions = Boolean.parseBoolean(allowOptions); } } @Override public void destroy() {} @Override public void doFilter(final ServletRequest _request, final ServletResponse _response, final FilterChain chain) throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) _request; final HttpServletResponse response = (HttpServletResponse) _response; if (isExceptionPath(request) || checkOptions(request)) { chain.doFilter(request, response); return; } HttpSession session = request.getSession(false); final User user = authenticationService.getUser(); try { if (user == null || isAnonymousUser(user)) { if (authenticate(request)) { chain.doFilter(request, response); if (response.isCommitted()) { authenticationService.logout(); } } else { challengeClient(request, response); } } else { chain.doFilter(request, response); } } finally { // invalidate session only when it did not exists before this request, // it was created as part of this request and filter is configured to invalidate. if (session == null && invalidate) { session = request.getSession(false); if (session != null) { session.invalidate(); } } } } private boolean checkOptions(HttpServletRequest request) { return OPTIONS.equalsIgnoreCase(request.getMethod()) && allowOptions; } private boolean isExceptionPath(final HttpServletRequest request) { String requestURI = request.getRequestURI(); while (requestURI != null && requestURI.endsWith("/")) { requestURI = requestURI.substring(0, requestURI.length() - 1); } if (requestURI != null && requestURI.startsWith(request.getContextPath())) { requestURI = requestURI.replaceFirst(request.getContextPath(), ""); } return excludedPaths.contains(requestURI); } public void challengeClient(final HttpServletRequest request, final HttpServletResponse response) throws IOException { response.setHeader("WWW-Authenticate", "Basic realm=\"" + this.realmName + "\""); // this usually means we have a failing authentication request from an ajax client. so we return SC_FORBIDDEN instead. if (isAjaxRequest(request)) { response.sendError(HttpServletResponse.SC_FORBIDDEN); } else { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } private boolean authenticate(final HttpServletRequest req) { final String authHead = req.getHeader("Authorization"); if (authHead != null) { final int index = authHead.indexOf(' '); final String[] credentials = new String(Base64.decodeBase64(authHead.substring(index)), Charsets.UTF_8).split(":", -1); try { authenticationService.login(credentials[0], credentials[1]); return true; } catch (final FailedAuthenticationException e) { return false; } } return false; } private boolean isAjaxRequest(HttpServletRequest request) { return request.getHeader("X-Requested-With") != null && "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With")); } private boolean isAnonymousUser(User user) { if (user.getRoles().size() != 1) { return false; } String roleName = user.getRoles().iterator().next().getName(); return User.ANONYMOUS.getIdentifier().equals(user.getIdentifier()) && Role.NOBODY.getName().equals(roleName); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/security/LoginRedirectServlet.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.security; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Map; import java.util.Set; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * A workaround for the servlet form authentication process (j_security_check), which, at least on WildFly 8.1, uses the * HTTP POST method when forwarding the request after successful login. This blows up after login, giving an * HTTP 405 Method Not Allowed response when the desired resource is a static one, such as a GWT host page. *

    * This servlet works around the issue by sending an HTTP redirect only if the request comes from an authenticated * user to a URL of your choice. The end result is that your user will see the real resource's URL in their * browser's location bar after login. In addition, this servlet copies all request parameters that were submitted along * with the login form (except j_username and j_password) to the redirect URL. *

    * To set this servlet up, configure your web application as follows: *

      *
    • Declare this servlet in web.xml with init-param display-after-login set to the context-relative URI * of the page you want the user to land on after a successful login. (for example, /host_page.html) *
    • Map this servlet to a url-pattern that makes sense for a sign-in page, such as /login. *
    • Mark this servlet's url-pattern with a security-constraint that only allows logged-in users to see it. (I know, * this part is confusing! The login URL has to be a protected resource!) *
    • Configure web.xml for auth-method FORM *
    • Configure the form-login-page and form-error-page to any resource you like. It can even be JSP's under /WEB-INF, * since the login and error pages will never display under their "own" URLs. They always display in place of the "real" * resource that was being requested by an unauthorized user. In our case, that resource should always be whatever this * servlet is mapped to (eg. /login). *
    • (Optional) set welcome-page-uri to this servlet's uri-pattern, as an easy way to direct new visitors into this * tangled web of deceit. *
    * * === COPIED FROM UBERFIRE SERVLETS === */ public class LoginRedirectServlet extends HttpServlet { public static final String DISPLAY_AFTER_LOGIN_INIT_PARAM = "display-after-login"; public static final String DISPLAY_WHEN_NOT_AUTH_INIT_PARAM = "display-when-not-authenticated"; private static final Logger logger = LoggerFactory.getLogger(LoginRedirectServlet.class); /** * URI of the GWT host page, relative to the servlet container root (so it starts with '/' and includes the context * path). */ private String displayAfterLoginUri; /** * Optional URI of a page to redirect in case coming request is not authenticated (no user principal exists), * relative to the servlet container root (so it starts with '/' and does not include context path) */ private String displayWhenNotAuthenticatedUri; @Override public void init(ServletConfig config) throws ServletException { String contextRelativeHostPageUri = config.getInitParameter(DISPLAY_AFTER_LOGIN_INIT_PARAM); if (contextRelativeHostPageUri == null) { throw new IllegalStateException(getClass().getSimpleName() + " requires that you set the init parameter \"" + DISPLAY_AFTER_LOGIN_INIT_PARAM + "\" to the context-relative URI of the host page."); } displayAfterLoginUri = config.getServletContext().getContextPath() + contextRelativeHostPageUri; // optional display-when-not-authenticated String contextRelativeNotAuthPageUri = config.getInitParameter(DISPLAY_WHEN_NOT_AUTH_INIT_PARAM); if (contextRelativeNotAuthPageUri != null) { displayWhenNotAuthenticatedUri = config.getServletContext().getContextPath() + contextRelativeNotAuthPageUri; } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { handleRequest(req, resp); } catch (Exception e) { handleError(resp, e); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // perform optional check and redirect in case no authenticated request is available try { handleRequest(req, resp); } catch (Exception e) { handleError(resp, e); } } private void handleError(HttpServletResponse resp, Exception e) throws IOException { logger.error("Error during login redirect filter execution: {}", e.getMessage()); logger.debug("Error during redirect", e); resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error handling request"); } private void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { if (displayWhenNotAuthenticatedUri != null && req.getUserPrincipal() == null) { logger.debug("No authorized user thus cleaning up session and redirecting to {}", displayWhenNotAuthenticatedUri); try { // clean up session req.logout(); req.getSession().invalidate(); } catch (Exception e) { // to avoid cases where logout causes issues for first request } resp.sendRedirect(displayWhenNotAuthenticatedUri); return; } logger.debug("Redirecting {} to {}", req.getUserPrincipal(), displayAfterLoginUri); StringBuilder redirectTarget = new StringBuilder(displayAfterLoginUri); String extraParams = extractParameters(req); if (extraParams.length() > 0) { redirectTarget.append("?").append(extraParams); } resp.sendRedirect(redirectTarget.toString()); } /** * Extracts all parameters except the username and password into a URL-encoded query string. The string does not begin * or end with a "&". */ private static String extractParameters(HttpServletRequest fromRequest) { try { StringBuilder sb = new StringBuilder(); for (Map.Entry param : (Set>) fromRequest.getParameterMap().entrySet()) { String paramName = URLEncoder.encode(param.getKey(), "UTF-8"); if (paramName.equals("j_username") || paramName.equals("j_password")) { continue; } for (String value : param.getValue()) { if (sb.length() != 0) { sb.append("&"); } sb.append(paramName).append("=").append(URLEncoder.encode(value, "UTF-8")); } } return sb.toString(); } catch (UnsupportedEncodingException e) { throw new AssertionError("UTF-8 not supported on this JVM?"); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/RuntimeInfoService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services; import java.util.Optional; import org.dashbuilder.shared.model.DashboardInfo; import org.dashbuilder.shared.model.DashbuilderRuntimeInfo; /** * Provides information about the running server. * */ public interface RuntimeInfoService { /** * Access Server information. */ DashbuilderRuntimeInfo info(); /** * Information about a specific runtime model. Used in MULTI mode. * * @param modelId * The model ID. * @return * The dashboard information for the given runtime model id or empty if no dashboard is found. */ Optional dashboardInfo(String modelId); } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/dataset/DataSetServicesProducer.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.dataset; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import org.dashbuilder.DataSetCore; import org.dashbuilder.backend.services.dataset.provider.RuntimeDataSetProviderRegistry; import org.dashbuilder.backend.services.dataset.provider.RuntimeSQLDataSourceLocator; import org.dashbuilder.dataprovider.StaticDataSetProvider; import org.dashbuilder.dataprovider.csv.CSVDataSetProvider; import org.dashbuilder.dataprovider.csv.CSVFileStorage; import org.dashbuilder.dataprovider.kafka.KafkaDataSetProvider; import org.dashbuilder.dataprovider.prometheus.PrometheusDataSetProvider; import org.dashbuilder.dataprovider.sql.SQLDataSetProvider; import org.dashbuilder.dataset.DataSetDefRegistryImpl; import org.dashbuilder.dataset.DataSetManager; import org.dashbuilder.dataset.DataSetManagerImpl; import org.dashbuilder.dataset.def.DataSetDefRegistry; import org.dashbuilder.scheduler.Scheduler; /** * Produces types related to DataSet * */ public class DataSetServicesProducer { @Produces @ApplicationScoped public CSVDataSetProvider produceCSVProvider(StaticDataSetProvider staticDataSetProvider, CSVFileStorage csvStorage) { return new CSVDataSetProvider(staticDataSetProvider, csvStorage); } @Produces @ApplicationScoped public StaticDataSetProvider produceStaticDataSetProviderCDI() { return new StaticDataSetProvider(DataSetCore.get().getSharedDataSetOpEngine()); } @Produces @ApplicationScoped public SQLDataSetProvider produceSQLDataSetProvider(StaticDataSetProvider staticDataSetProvider, RuntimeSQLDataSourceLocator sqlDataSourceLocator) { SQLDataSetProvider provider = new SQLDataSetProvider(staticDataSetProvider, DataSetCore.get().getIntervalBuilderLocator(), DataSetCore.get().getIntervalBuilderDynamicDate(), DataSetCore.get().getSharedDataSetOpEngine()); provider.setDataSourceLocator(sqlDataSourceLocator); return provider; } @Produces @ApplicationScoped public PrometheusDataSetProvider producePrometheusProvider(StaticDataSetProvider staticDataSetProvider) { return new PrometheusDataSetProvider(staticDataSetProvider); } @Produces @ApplicationScoped public KafkaDataSetProvider produceKafkaProvider(StaticDataSetProvider staticDataSetProvider) { return new KafkaDataSetProvider(staticDataSetProvider); } @Produces @ApplicationScoped public DataSetDefRegistry produceDataSetDefRegistry(RuntimeDataSetProviderRegistry providerRegistry) { Scheduler scheduler = new Scheduler(); scheduler.init(10); return new DataSetDefRegistryImpl(providerRegistry, scheduler); } @Produces @ApplicationScoped public DataSetManager produceDataSetManager(StaticDataSetProvider staticDataSetProvider, DataSetDefRegistry dataSetDefRegistry, RuntimeDataSetProviderRegistry dataSetProviderRegistry) { return new DataSetManagerImpl(dataSetDefRegistry, dataSetProviderRegistry, staticDataSetProvider, true, 1024); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/dataset/RuntimeCSVFileStorage.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.dataset; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.dataprovider.csv.CSVFileStorage; import org.dashbuilder.dataset.def.CSVDataSetDef; /** * In Memory CSV storage. * */ @ApplicationScoped public class RuntimeCSVFileStorage implements CSVFileStorage { Map csvStorage; public RuntimeCSVFileStorage() { // not used } @PostConstruct public void init() { csvStorage = new HashMap<>(); } @Override public InputStream getCSVInputStream(CSVDataSetDef def) { String csvStr = getCSVString(def); return new ByteArrayInputStream(csvStr.getBytes()); } @Override public String getCSVString(CSVDataSetDef def) { return csvStorage.getOrDefault(def.getUUID(), ""); } public void storeCSV(String uuid, String csvContent) { csvStorage.put(uuid, csvContent); } @Override public void saveCSVFile(CSVDataSetDef def) { // not going to save } @Override public void deleteCSVFile(CSVDataSetDef def) { csvStorage.remove(def.getUUID()); } public void deleteCSVFile(String uuid) { csvStorage.remove(uuid); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/dataset/provider/RuntimeBeanDataSetProvider.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.dataset.provider; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import org.dashbuilder.dataprovider.BeanDataSetProvider; import org.dashbuilder.dataprovider.StaticDataSetProvider; import org.dashbuilder.dataset.DataSetGenerator; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.dashbuilder.dataset.def.DataSetDef; @ApplicationScoped public class RuntimeBeanDataSetProvider extends BeanDataSetProvider { protected BeanManager beanManager; protected Map generatorMap = new HashMap<>(); public RuntimeBeanDataSetProvider() { super(); } @Inject public RuntimeBeanDataSetProvider(StaticDataSetProvider staticDataSetProvider, BeanManager beanManager) { super(staticDataSetProvider); this.beanManager = beanManager; } @PostConstruct protected void init() { Set> beans = beanManager.getBeans(DataSetGenerator.class); for (Bean bean : beans) { CreationalContext ctx = beanManager.createCreationalContext(bean); DataSetGenerator generator = (DataSetGenerator) beanManager.getReference(bean, DataSetGenerator.class, ctx); generatorMap.put(bean.getBeanClass().getName(), generator); } } @Override public DataSetGenerator lookupGenerator(DataSetDef def) { if (def instanceof BeanDataSetDef) { return loadDataSetGenerator((BeanDataSetDef) def); } throw new IllegalArgumentException("Not a BeanDataSetDef instance"); } private DataSetGenerator loadDataSetGenerator(BeanDataSetDef beanDef) { String beanName = beanDef.getGeneratorClass(); DataSetGenerator generator = generatorMap.get(beanName); if (generator != null) { return generator; } else { throw new IllegalArgumentException("Data set generator class not found: " + beanName); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/dataset/provider/RuntimeDataSetProviderRegistry.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.dataset.provider; import java.util.Iterator; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.dashbuilder.DataSetCore; import org.dashbuilder.dataprovider.DataSetProvider; import org.dashbuilder.dataprovider.DataSetProviderRegistryImpl; import org.dashbuilder.dataprovider.StaticDataSetProvider; import org.dashbuilder.dataprovider.csv.CSVDataSetProvider; import org.dashbuilder.dataprovider.sql.SQLDataSetProvider; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; @ApplicationScoped public class RuntimeDataSetProviderRegistry extends DataSetProviderRegistryImpl { @Inject private StaticDataSetProvider staticDataSetProvider; @Inject private RuntimeBeanDataSetProvider beanDataSetProvider; @Inject private CSVDataSetProvider csvDataSetProvider; @Inject private SQLDataSetProvider sqlDataSetProvider; @Inject private Instance providerSet; protected DataSetDefJSONMarshaller dataSetDefJSONMarshaller = new DataSetDefJSONMarshaller(this); @PostConstruct public void init() { DataSetCore.get().setDataSetDefJSONMarshaller(dataSetDefJSONMarshaller); // Register all the providers available in classpath Iterator it = providerSet.iterator(); while (it.hasNext()) { DataSetProvider provider = it.next(); super.registerDataProvider(provider); } // Register the core providers super.registerDataProvider(staticDataSetProvider); super.registerDataProvider(beanDataSetProvider); super.registerDataProvider(csvDataSetProvider); super.registerDataProvider(sqlDataSetProvider); } public StaticDataSetProvider getStaticDataSetProvider() { return staticDataSetProvider; } public RuntimeBeanDataSetProvider getBeanDataSetProvider() { return beanDataSetProvider; } public CSVDataSetProvider getCsvDataSetProvider() { return csvDataSetProvider; } public SQLDataSetProvider getSqlDataSetProvider() { return sqlDataSetProvider; } public DataSetDefJSONMarshaller getDataSetDefJSONMarshaller() { return dataSetDefJSONMarshaller; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/dataset/provider/RuntimeSQLDataSourceLocator.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.dataset.provider; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.naming.InitialContext; import javax.sql.DataSource; import org.dashbuilder.dataprovider.sql.JDBCUtils; import org.dashbuilder.dataprovider.sql.SQLDataSourceLocator; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.def.SQLDataSourceDef; @ApplicationScoped public class RuntimeSQLDataSourceLocator implements SQLDataSourceLocator { @Override public DataSource lookup(SQLDataSetDef def) throws Exception { return InitialContext.doLookup(def.getDataSource()); } @Override public List list() { return JDBCUtils.listDatasourceDefs(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/impl/ExternalImportServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.backend.RuntimeOptions; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.dashbuilder.shared.services.ExternalImportService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ApplicationScoped public class ExternalImportServiceImpl implements ExternalImportService { private static final String ERROR_PARSING_URL = "Error parsing URL: {}"; Logger logger = LoggerFactory.getLogger(ExternalImportServiceImpl.class); @Inject RuntimeOptions runtimeOptions; @Inject RuntimeModelRegistry runtimeModelRegistry; @Override public Optional registerExternalImport(String externalModelUrl) { String modelId = ""; URL url = getExternalModelUrl(externalModelUrl); modelId = buildURLIdentifier(url); final String filePath = runtimeOptions.buildFilePath(modelId); int totalBytes = 0; final int pageSize = 1024; try (BufferedInputStream in = new BufferedInputStream(url.openStream()); FileOutputStream fos = new FileOutputStream(filePath)) { byte[] dataBuffer = new byte[pageSize]; int bytesRead; while ((bytesRead = in.read(dataBuffer, 0, pageSize)) != -1) { fos.write(dataBuffer, 0, bytesRead); totalBytes += pageSize; checkSize(filePath, totalBytes); } } catch (IOException e) { logger.debug("Error downloading and parsing content from URL {}", externalModelUrl, e); logger.warn("Error downloading and parsing content from URL {}", externalModelUrl); deleteFile(filePath); throw new IllegalArgumentException("Not able to download file", e); } return runtimeModelRegistry.registerFile(filePath); } private void checkSize(final String filePath, int totalBytes) { if (totalBytes > runtimeOptions.getUploadSize()) { deleteFile(filePath); logger.error("Size file is bigger than max upload size {}", runtimeOptions.getUploadSize()); throw new IllegalArgumentException("External file size is too big."); } } private String buildURLIdentifier(URL url) { try { return Math.abs(url.toURI().hashCode()) + ""; } catch (URISyntaxException e) { logger.debug(ERROR_PARSING_URL, url.toExternalForm(), e); logger.warn(ERROR_PARSING_URL, url.toExternalForm()); throw new IllegalArgumentException("Not a valid URL: " + url.toExternalForm(), e); } } private URL getExternalModelUrl(String externalModelUrl) { try { return new URL(externalModelUrl); } catch (Exception e) { logger.debug(ERROR_PARSING_URL, externalModelUrl, e); logger.error(ERROR_PARSING_URL, externalModelUrl); throw new IllegalArgumentException("Not a valid URL: " + externalModelUrl, e); } } private void deleteFile(final String filePath) { try { Files.deleteIfExists(Paths.get(filePath)); } catch (IOException e) { logger.error("Error deleting bad model file: {}", filePath, e); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/impl/ImportValidationServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.io.FileInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.shared.service.ImportValidationService; import static org.dashbuilder.shared.model.ImportDefinitions.DATASET_PREFIX; import static org.dashbuilder.shared.model.ImportDefinitions.NAVIGATION_PREFIX; import static org.dashbuilder.shared.model.ImportDefinitions.PERSPECTIVE_PREFIX; /** * Simple Validation Service Implementation that checks if the ZIPs contains the necessary structure. * */ @ApplicationScoped public class ImportValidationServiceImpl implements ImportValidationService { /** * Checks if the given file URL is valid for a Runtime Model. */ @Override public boolean validate(final String file) { boolean hasDatasetDir = false; boolean hasPage = false; boolean hasNavigation = false; try (final ZipInputStream zis = new ZipInputStream(new FileInputStream(file))) { ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { hasDatasetDir = hasDatasetDir || entryStartsWith(entry, DATASET_PREFIX); hasPage = hasPage || entryStartsWith(entry, PERSPECTIVE_PREFIX); hasNavigation = hasNavigation || entryStartsWith(entry, NAVIGATION_PREFIX); if (hasNavigation && hasDatasetDir && hasPage) { return true; } } } catch (Exception e) { throw new IllegalArgumentException("Error validating file: " + file, e); } return false; } private boolean entryStartsWith(ZipEntry entry, String path) { return entry.getName().startsWith(path); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/impl/RuntimeInfoServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.util.List; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.backend.services.RuntimeInfoService; import org.dashbuilder.shared.model.DashboardInfo; import org.dashbuilder.shared.model.DashbuilderRuntimeInfo; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static java.util.stream.Collectors.toList; @ApplicationScoped public class RuntimeInfoServiceImpl implements RuntimeInfoService { @Inject RuntimeModelRegistry registry; @Override public DashbuilderRuntimeInfo info() { return new DashbuilderRuntimeInfo(registry.getMode().name(), registry.availableModels(), registry.acceptingNewImports()); } @Override public Optional dashboardInfo(String modelId) { return registry.get(modelId) .map(model -> new DashboardInfo(modelId, perspectives(model))); } private List perspectives(RuntimeModel runtimeModel) { return runtimeModel.getLayoutTemplates().stream() .map(LayoutTemplate::getName) .collect(toList()); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/impl/RuntimeModelParserImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.dashbuilder.backend.RuntimeOptions; import org.dashbuilder.backend.helper.PartitionHelper; import org.dashbuilder.backend.navigation.RuntimeNavigationBuilder; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.external.service.ComponentLoader; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.shared.event.NewDataSetContentEvent; import org.dashbuilder.shared.model.DataSetContent; import org.dashbuilder.shared.model.DataSetContentType; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.RuntimeModelParser; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_ID_KEY; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_PARTITION_KEY; import static org.dashbuilder.shared.model.ImportDefinitions.DATASET_DEF_PREFIX; import static org.dashbuilder.shared.model.ImportDefinitions.NAVIGATION_FILE; import static org.dashbuilder.shared.model.ImportDefinitions.PERSPECTIVE_SUFFIX; import static org.dashbuilder.transfer.DataTransferServices.COMPONENTS_EXPORT_PATH; /** * Parses an exported zip file from Transfer Services into RuntimeModel. * */ @ApplicationScoped public class RuntimeModelParserImpl implements RuntimeModelParser { @Inject Event newDataSetContentEvent; @Inject RuntimeNavigationBuilder runtimeNavigationBuilder; @Inject RuntimeOptions options; @Inject RuntimeModelRegistry registry; @Inject ComponentLoader externalComponentLoader; Gson gson; private DisplayerSettingsJSONMarshaller displayerSettingsMarshaller; @PostConstruct void init() { gson = new GsonBuilder().create(); displayerSettingsMarshaller = DisplayerSettingsJSONMarshaller.get(); } @Override public RuntimeModel parse(String modelId, InputStream is) { try { return retrieveRuntimeModel(modelId, is); } catch (IOException e) { throw new RuntimeException(e); } } RuntimeModel retrieveRuntimeModel(String modelId, InputStream is) throws IOException { List datasetContents = new ArrayList<>(); List layoutTemplates = new ArrayList<>(); Optional navTreeOp = Optional.empty(); try (ZipInputStream zis = new ZipInputStream(is)) { ZipEntry entry; while ((entry = zis.getNextEntry()) != null) { if (entry.isDirectory()) { continue; } String entryName = entry.getName(); if (entryName.startsWith(DATASET_DEF_PREFIX)) { datasetContents.add(retrieveDataSetContent(entry, zis)); } if (entryName.endsWith(PERSPECTIVE_SUFFIX)) { layoutTemplates.add(retrieveLayoutTemplate(zis)); } if (entryName.equalsIgnoreCase(NAVIGATION_FILE)) { navTreeOp = Optional.of(nextEntryContentAsString(zis)); } if (entryName.startsWith(COMPONENTS_EXPORT_PATH)) { extractComponentFile(modelId, zis, entry.getName()); } } } if (options.isMultipleImport()) { if (options.isDatasetPartition()) { datasetContents.forEach(ds -> ds.setId(PartitionHelper.partition(modelId, ds.getId()))); } layoutTemplates.forEach(lt -> partitionLayoutTemplate(modelId, lt)); } if (!datasetContents.isEmpty()) { newDataSetContentEvent.fire(new NewDataSetContentEvent(modelId, datasetContents)); } NavTree navTree = runtimeNavigationBuilder.build(navTreeOp, layoutTemplates); return new RuntimeModel(navTree, layoutTemplates, System.currentTimeMillis()); } void extractComponentFile(String modelId, InputStream zis, String name) throws IOException { String externalComponentsDir = externalComponentLoader.getExternalComponentsDir(); if (externalComponentsDir != null) { externalComponentsDir = externalComponentsDir.endsWith(File.separator) ? externalComponentsDir : externalComponentsDir + File.separator; String newFileName = null; if (options.isComponentPartition() && options.isMultipleImport()) { newFileName = externalComponentsDir + modelId + File.separator + name.replaceAll(COMPONENTS_EXPORT_PATH, ""); } else { newFileName = externalComponentsDir + name.replaceAll(COMPONENTS_EXPORT_PATH, ""); } File target = new File(newFileName); target.getParentFile().mkdirs(); final int BUFFER_SIZE = 1024; byte[] buffer = new byte[BUFFER_SIZE]; int read = 0; try (FileOutputStream fos = new FileOutputStream(target)) { while ((read = zis.read(buffer, 0, BUFFER_SIZE)) >= 0) { fos.write(buffer, 0, read); } } } } private LayoutTemplate retrieveLayoutTemplate(final ZipInputStream zis) { String content = nextEntryContentAsString(zis); return gson.fromJson(content, LayoutTemplate.class); } private DataSetContent retrieveDataSetContent(final ZipEntry entry, final ZipInputStream zis) { String fileName = entry.getName().split("/")[3]; String[] nameParts = fileName.split("\\."); String id = nameParts[0]; String ext = nameParts[1]; String content = nextEntryContentAsString(zis); return new DataSetContent(id, content, DataSetContentType.fromFileExtension(ext)); } private String nextEntryContentAsString(final ZipInputStream zis) { try { final int BUFFER_SIZE = 8192; byte[] buffer = new byte[BUFFER_SIZE]; int read = 0; String output = ""; while ((read = zis.read(buffer, 0, BUFFER_SIZE)) != -1) { output = output.concat(new String(buffer, 0, read)); } return output.trim(); } catch (Exception e) { throw new RuntimeException(e); } } private void partitionLayoutTemplate(String modelId, LayoutTemplate lt) { allComponentsStream(lt.getRows()).forEach(lc -> { String json = lc.getProperties().get("json"); String componentId = lc.getProperties().get(COMPONENT_ID_KEY); if (json != null) { partitionDisplayer(lc, modelId, json); } // For components that does not use displayers (noData components) if (options.isComponentPartition() && isExternalComponent(componentId)) { lc.getProperties().put(COMPONENT_PARTITION_KEY, modelId); } }); } private void partitionDisplayer(LayoutComponent lc, String modelId, String json) { DisplayerSettings settings = displayerSettingsMarshaller.fromJsonString(json); String componentId = settings.getComponentId(); if (options.isDatasetPartition() && settings.getDataSetLookup() != null) { DataSetLookup dataSetLookup = settings.getDataSetLookup(); String newId = PartitionHelper.partition(modelId, dataSetLookup.getDataSetUUID()); settings.getDataSetLookup().setDataSetUUID(newId); } if (options.isComponentPartition() && settings.getType() == DisplayerType.EXTERNAL_COMPONENT && isExternalComponent(componentId)) { settings.setComponentPartition(modelId); } lc.getProperties().put("json", displayerSettingsMarshaller.toJsonString(settings)); } private Stream allComponentsStream(List row) { return row.stream() .flatMap(r -> r.getLayoutColumns().stream()) .flatMap(cl -> Stream.concat(cl.getLayoutComponents().stream(), allComponentsStream(cl.getRows()))); } private boolean isExternalComponent(String componentId) { return externalComponentLoader.loadProvided().stream().noneMatch(c -> c.getId().equals(componentId)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/backend/services/impl/RuntimeModelRegistryImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.apache.commons.io.FileUtils; import org.dashbuilder.backend.RuntimeOptions; import org.dashbuilder.shared.event.NewDataSetContentEvent; import org.dashbuilder.shared.event.RemovedRuntimeModelEvent; import org.dashbuilder.shared.event.UpdatedRuntimeModelEvent; import org.dashbuilder.shared.model.DashbuilderRuntimeMode; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.ImportValidationService; import org.dashbuilder.shared.service.RuntimeModelParser; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.apache.commons.io.FilenameUtils; @ApplicationScoped public class RuntimeModelRegistryImpl implements RuntimeModelRegistry { Logger logger = LoggerFactory.getLogger(RuntimeModelRegistryImpl.class); Map runtimeModels; DashbuilderRuntimeMode mode = DashbuilderRuntimeMode.SINGLE_IMPORT; @Inject RuntimeModelParser parser; @Inject Event newDataSetContentEvent; @Inject ImportValidationService importValidationService; @Inject Event runtimeModelUpdatedEvent; @Inject Event removedRuntimeModelEvent; @Inject RuntimeOptions options; @PostConstruct public void init() { runtimeModels = new HashMap<>(); } @Override public Optional single() { return runtimeModels.values().stream().findFirst(); } @Override public Optional get(String id) { if (mode == DashbuilderRuntimeMode.MULTIPLE_IMPORT) { return Optional.ofNullable(runtimeModels.get(id)); } return single(); } @Override public Optional registerFile(String fileName) { // it could be possible to NOT STORE models if (fileName == null || fileName.trim().isEmpty()) { logger.error("Invalid file name: {}", fileName); throw new IllegalArgumentException("Invalid file name."); } File file = new File(fileName); if (!file.exists()) { logger.error("File does not exist: {}", fileName); throw new IllegalArgumentException("File does not exist"); } if (!importValidationService.validate(fileName)) { logger.error("File does not have a valid structure: {}", fileName); throw new IllegalArgumentException("Not a valid file structure."); } try (FileInputStream fis = new FileInputStream(fileName)) { String importId = FilenameUtils.getBaseName(file.getPath()); return register(importId, fis); } catch (IOException e) { logger.error("Not able to load file {}", fileName, e); throw new IllegalArgumentException("Error loading import file: " + fileName, e); } } @Override public void setMode(DashbuilderRuntimeMode mode) { this.mode = mode; } @Override public boolean isEmpty() { return runtimeModels.isEmpty(); } @Override public DashbuilderRuntimeMode getMode() { return mode; } @Override public void remove(String modelId) { internalRemove(modelId, true); } public Optional register(String id, InputStream fileStream) { if (!acceptingNewImports()) { throw new IllegalArgumentException("New imports are not allowed in mode " + mode); } try { if (id == null) { id = UUID.randomUUID().toString(); } RuntimeModel runtimeModel = parser.parse(id, fileStream); runtimeModels.put(id, runtimeModel); if (options.isDevMode()) { runtimeModelUpdatedEvent.fire(new UpdatedRuntimeModelEvent(id)); } return Optional.of(runtimeModel); } catch (Exception e) { throw new IllegalArgumentException("Error parsing import model.", e); } } @Override public Collection availableModels() { return Collections.unmodifiableCollection(runtimeModels.keySet()); } @Override public void clear() { availableModels().forEach(this::remove); runtimeModels.clear(); } @Override public void unregister(String id) { internalRemove(id, false); } public void internalRemove(String modelId, boolean deleteFile) { if (runtimeModels.remove(modelId) != null) { removedRuntimeModelEvent.fire(new RemovedRuntimeModelEvent(modelId)); if (options.isRemoveModelFile() && deleteFile) { removeModelFile(modelId); } } } private void removeModelFile(String modelId) { String modelPath = options.buildFilePath(modelId); FileUtils.deleteQuietly(new File(modelPath)); } void setRemovedRuntimeModelEvent(Event removedRuntimeModelEvent) { this.removedRuntimeModelEvent = removedRuntimeModelEvent; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/RuntimeClientLoader.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client; import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.Window; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.perspective.generator.RuntimePerspectiveGenerator; import org.dashbuilder.client.plugins.RuntimePerspectivePluginManager; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.model.RuntimeServiceResponse; import org.dashbuilder.shared.service.RuntimeModelService; import org.jboss.errai.common.client.api.Caller; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.mvp.Command; @ApplicationScoped public class RuntimeClientLoader { private static AppConstants i18n = AppConstants.INSTANCE; public static final String IMPORT_ID_PARAM = "import"; private Caller runtimeModelServiceCaller; RuntimePerspectiveGenerator perspectiveEditorGenerator; RuntimePerspectivePluginManager runtimePerspectivePluginManager; NavigationManager navigationManager; BusyIndicatorView loading; public RuntimeClientLoader() { // do nothing } @Inject public RuntimeClientLoader(Caller runtimeModelServiceCaller, RuntimePerspectiveGenerator perspectiveEditorGenerator, RuntimePerspectivePluginManager runtimePerspectivePluginManager, NavigationManager navigationManager, BusyIndicatorView loading) { this.runtimeModelServiceCaller = runtimeModelServiceCaller; this.perspectiveEditorGenerator = perspectiveEditorGenerator; this.runtimePerspectivePluginManager = runtimePerspectivePluginManager; this.navigationManager = navigationManager; this.loading = loading; } public void load(Consumer responseConsumer, BiConsumer error) { String importID = getImportId(); loading.showBusyIndicator(i18n.loadingDashboards()); runtimeModelServiceCaller.call((RuntimeServiceResponse response) -> { loading.hideBusyIndicator(); response.getRuntimeModelOp().ifPresent(this::registerModel); responseConsumer.accept(response); }, (msg, t) -> handleError(error, msg, t)) .info(importID); } public void loadModel(Consumer modelLoaded, Command emptyModel, BiConsumer error) { String importID = getImportId(); loadModel(importID, modelLoaded, emptyModel, error); } public void loadModel(String importId, Consumer modelLoaded, Command emptyModel, BiConsumer error) { loading.showBusyIndicator(i18n.loadingDashboards()); runtimeModelServiceCaller.call((Optional runtimeModelOp) -> handleResponse(modelLoaded, emptyModel, runtimeModelOp), (msg, t) -> handleError(error, msg, t)) .getRuntimeModel(importId); } private boolean handleError(BiConsumer error, Object message, Throwable throwable) { loading.hideBusyIndicator(); error.accept(message, throwable); return false; } private void handleResponse(Consumer modelLoaded, Command emptyModel, Optional runtimeModelOp) { loading.hideBusyIndicator(); if (runtimeModelOp.isPresent()) { RuntimeModel runtimeModel = runtimeModelOp.get(); registerModel(runtimeModel); modelLoaded.accept(runtimeModel); } else { emptyModel.execute(); } } private void registerModel(RuntimeModel runtimeModel) { runtimeModel.getLayoutTemplates().forEach(perspectiveEditorGenerator::generatePerspective); runtimePerspectivePluginManager.setTemplates(runtimeModel.getLayoutTemplates()); navigationManager.setDefaultNavTree(runtimeModel.getNavTree()); } public String getImportId() { return Window.Location.getParameter(IMPORT_ID_PARAM); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/RuntimeCommunication.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import elemental2.dom.DomGlobal; import org.uberfire.workbench.events.NotificationEvent; /** * Utility methods to perform user communication * */ @ApplicationScoped public class RuntimeCommunication { @Inject Event wbNotification; public void showError(final String message, final Object details) { DomGlobal.console.log(details); wbNotification.fire(new NotificationEvent(message, NotificationEvent.NotificationType.ERROR)); } public void showWarning(final String message) { wbNotification.fire(new NotificationEvent(message, NotificationEvent.NotificationType.WARNING)); } public void showSuccess(final String message) { wbNotification.fire(new NotificationEvent(message, NotificationEvent.NotificationType.SUCCESS)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/RuntimeEntryPoint.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.Window; import elemental2.dom.DomGlobal; import elemental2.dom.Element; import org.dashbuilder.client.error.DefaultRuntimeErrorCallback; import org.dashbuilder.client.perspective.NotFoundPerspective; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.shared.model.RuntimeModel; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.ioc.client.api.UncaughtExceptionHandler; import org.jboss.errai.ui.shared.api.annotations.Bundle; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.Workbench; @EntryPoint @ApplicationScoped @Bundle("resources/i18n/AppConstants.properties") public class RuntimeEntryPoint { public static final String DASHBOARD_PARAM = "dashboard"; public static final String PERSPECTIVE_PARAM = "perspective"; private static AppConstants i18n = AppConstants.INSTANCE; @Inject Workbench workbench; @Inject RuntimeClientLoader modelLoader; @Inject PlaceManager placeManager; @Inject RuntimeCommunication runtimeCommunication; @Inject DefaultRuntimeErrorCallback defaultRuntimeErrorCallback; private String dashboard; @PostConstruct public void startup() { workbench.addStartupBlocker(RuntimeEntryPoint.class); Map> params = Window.Location.getParameterMap(); boolean isStandalone = params.containsKey("standalone"); List dashboardParams = params.get(DASHBOARD_PARAM); if (!foundDashboard(dashboardParams)) { dashboardParams = params.get(PERSPECTIVE_PARAM); } if (isStandalone && foundDashboard(dashboardParams)) { dashboard = dashboardParams.get(0); modelLoader.loadModel(this::foundRuntimeModel, this::notFound, this::error); } else { this.hideLoading(); } } private void foundRuntimeModel(RuntimeModel runtimeModel) { boolean perspectiveNotFound = runtimeModel.getLayoutTemplates().stream() .noneMatch(lt -> lt.getName().equals(dashboard)); if (perspectiveNotFound) { notFound(); } else { targetPerspective(); } } public void notFound() { String newUrl = GWT.getHostPageBaseURL() + "?standalone&" + PERSPECTIVE_PARAM + "=" + NotFoundPerspective.ID + "&" + DASHBOARD_PARAM + "=" + dashboard; DomGlobal.window.history.pushState(null, "Dashbuilder Runtime | Not Found", newUrl); this.hideLoading(); } public void targetPerspective() { String newUrl = Window.Location.createUrlBuilder() .setParameter(PERSPECTIVE_PARAM, dashboard) .buildString(); DomGlobal.window.history.pushState(null, "Dashbuilder Runtime", newUrl); this.hideLoading(); } public void error(Object e, Throwable t) { runtimeCommunication.showError(i18n.errorLoadingDashboards(), t); this.hideLoading(); } @UncaughtExceptionHandler public void generalErrorHandling(final Throwable t) { defaultRuntimeErrorCallback.error(t); } private void hideLoading() { workbench.removeStartupBlocker(RuntimeEntryPoint.class); Element loading = DomGlobal.document.getElementById("loading"); if (loading != null) { loading.remove(); } } private boolean foundDashboard(List dashboardParams) { return dashboardParams != null && !dashboardParams.isEmpty(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/error/DefaultRuntimeErrorCallback.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.error; import java.util.Arrays; import java.util.List; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.user.client.Window; import org.dashbuilder.client.resources.i18n.AppConstants; import org.jboss.errai.bus.client.api.InvalidBusContentException; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.ext.widgets.common.client.common.popups.YesNoCancelPopup; import org.uberfire.ext.widgets.common.client.resources.i18n.CommonConstants; import static org.uberfire.ext.widgets.common.client.common.popups.YesNoCancelPopup.newYesNoCancelPopup; import static org.uberfire.ext.widgets.common.client.common.popups.errors.ErrorPopup.showMessage; @Dependent public class DefaultRuntimeErrorCallback { public static final String PARSING_JSON_SYNTAX_MSG = "Error parsing JSON: SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data"; public static final String PARSING_JSON_MSG = "Error parsing JSON: SyntaxError: Unexpected token � in JSON at position 1"; public static final String SCRIPT_ERROR_MSG = "Script error. (:0)"; @Inject BusyIndicatorView loading; AppConstants i18n = AppConstants.INSTANCE; private boolean errorPopUpLock = false; public void error(final Throwable throwable) { if (errorPopUpLock) { return; } loading.hideBusyIndicator(); errorPopUpLock = true; if (isServerOfflineException(throwable)) { showPopup(i18n.disconnectedFromServer(), i18n.couldNotConnectToServer()); } else if (isInvalidBusContentException(throwable)) { showPopup(i18n.sessionTimeout(), i18n.invalidBusResponseProbablySessionTimeout()); } else { showMessage(CommonConstants.INSTANCE.ExceptionGeneric0(extractMessageRecursively(throwable)), this::unlock, this::unlock); } } private void showPopup(String title, String content) { final YesNoCancelPopup result = newYesNoCancelPopup(title, content, Window.Location::reload, null, this::unlock); result.clearScrollHeight(); result.show(); } protected static String extractMessageRecursively(final Throwable t) { if (t == null) { return ""; } if (t.getCause() == null) { return t.getMessage(); } return t.getMessage() + " Caused by: " + extractMessageRecursively(t.getCause()); } private static boolean isInvalidBusContentException(final Throwable throwable) { return throwable instanceof InvalidBusContentException; } protected static boolean isServerOfflineException(final Throwable throwable) { Throwable cause = throwable.getCause(); String message = throwable.getMessage(); List messages = Arrays.asList(SCRIPT_ERROR_MSG, PARSING_JSON_MSG, PARSING_JSON_SYNTAX_MSG); return cause == null && message != null && messages.stream().anyMatch(message::equals); } public void unlock() { errorPopUpLock = false; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/AppNavBar.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/AppNavBar.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import elemental2.dom.HTMLDivElement; import jsinterop.base.Js; import org.jboss.errai.ioc.client.api.AfterInitialization; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.workbench.Header; import org.uberfire.client.workbench.widgets.menu.megamenu.WorkbenchMegaMenuPresenter; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.Menus; @Templated @ApplicationScoped public class AppNavBar implements Header { @Inject @DataField HTMLDivElement header; @Inject WorkbenchMegaMenuPresenter menuBarPresenter; @Inject LogoutMenuBuilder logoutMenu; @Inject GoToDashboardMenuBuilder goToDashboardMenu; @Inject DashboardListMenuBuilder dashboardsListMenu; private boolean isDashboardListEnabled = false; private boolean isGoToDashboardMenuEnabled = false; @AfterInitialization public void setup() { setupMenus(); } public void setupMenus(final Menus menus) { setupMenus(); menuBarPresenter.addMenus(menus); } @Override public String getId() { return "AppNavBar"; } @Override public int getOrder() { return 20; } public void setDashboardListEnabled(boolean isDashboardListEnabled) { this.isDashboardListEnabled = isDashboardListEnabled; } public void setExternalMenuEnabled(boolean isExternalMenuEnabled) { this.isGoToDashboardMenuEnabled = isExternalMenuEnabled; } public void setupMenus() { menuBarPresenter.clear(); menuBarPresenter.clearContextMenu(); if (isGoToDashboardMenuEnabled) { menuBarPresenter.addMenus(MenuFactory.newTopLevelCustomMenu(goToDashboardMenu).endMenu().build()); } if (isDashboardListEnabled) { menuBarPresenter.addMenus(MenuFactory.newTopLevelCustomMenu(dashboardsListMenu).endMenu().build()); } menuBarPresenter.addMenus(MenuFactory.newTopLevelCustomMenu(logoutMenu).endMenu().build()); header.innerHTML = ""; header.appendChild(Js.cast(menuBarPresenter.getView().getElement())); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/DashboardListMenuBuilder.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.RouterScreen; import org.gwtbootstrap3.client.ui.constants.IconType; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuFactory.CustomMenuBuilder; import org.uberfire.workbench.model.menu.MenuItem; @ApplicationScoped public class DashboardListMenuBuilder implements MenuFactory.CustomMenuBuilder { private static final AppConstants i18n = AppConstants.INSTANCE; @Inject MenuBuilderHelper menuBuilderHelper; @Inject private RouterScreen router; @Override public void push(CustomMenuBuilder element) { // do nothing } @Override public MenuItem build() { return menuBuilderHelper.buildMenuItem(i18n.dashboardListTooltip(), IconType.LIST, this::goToList); } private void goToList() { router.listDashboards(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/GoToDashboardMenuBuilder.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.Window; import elemental2.dom.DomGlobal; import org.dashbuilder.client.RuntimeEntryPoint; import org.dashbuilder.client.resources.i18n.AppConstants; import org.gwtbootstrap3.client.ui.constants.IconType; import org.uberfire.client.mvp.PerspectiveManager; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuFactory.CustomMenuBuilder; import org.uberfire.workbench.model.menu.MenuItem; @ApplicationScoped public class GoToDashboardMenuBuilder implements MenuFactory.CustomMenuBuilder { @Inject private PerspectiveManager perspectiveManager; @Inject MenuBuilderHelper menuBuilderHelper; @Override public void push(CustomMenuBuilder element) { // do nothing } @Override public MenuItem build() { return menuBuilderHelper.buildMenuItem(AppConstants.INSTANCE.dashboardOpenTooltip(), IconType.EXTERNAL_LINK, this::openDashboardInNewWindow); } private void openDashboardInNewWindow() { String currentPlace = perspectiveManager.getCurrentPerspective().getIdentifier(); String standaloneUrl = Window.Location.createUrlBuilder() .setParameter(RuntimeEntryPoint.DASHBOARD_PARAM, currentPlace) .setParameter("standalone", "true") .buildString(); DomGlobal.window.open(standaloneUrl); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/LogoutMenuBuilder.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import elemental2.dom.DomGlobal; import org.dashbuilder.client.resources.i18n.AppConstants; import org.gwtbootstrap3.client.ui.constants.IconType; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.security.shared.service.AuthenticationService; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuFactory.CustomMenuBuilder; import org.uberfire.workbench.model.menu.MenuItem; @ApplicationScoped public class LogoutMenuBuilder implements MenuFactory.CustomMenuBuilder { private static final AppConstants i18n = AppConstants.INSTANCE; @Inject MenuBuilderHelper menuBuilderHelper; @Inject private Caller authService; @Override public void push(CustomMenuBuilder element) { // do nothing } @Override public MenuItem build() { return menuBuilderHelper.buildMenuItem(i18n.logoutMenuTooltip(), IconType.SIGN_OUT, this::logout); } private void logout() { authService.call(r -> { final String location = GWT.getModuleBaseURL() .replaceFirst("/" + GWT.getModuleName() + "/", "/logout.jsp"); DomGlobal.window.location.assign(location); }).logout(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/MenuBuilderHelper.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.enterprise.context.ApplicationScoped; import com.google.gwt.user.client.ui.IsWidget; import org.gwtbootstrap3.client.ui.AnchorListItem; import org.gwtbootstrap3.client.ui.constants.IconType; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.menu.MenuItem; import org.uberfire.workbench.model.menu.MenuPosition; import org.uberfire.workbench.model.menu.impl.BaseMenuCustom; @ApplicationScoped public class MenuBuilderHelper { public MenuItem buildMenuItem(String title, IconType icon, Command action) { AnchorListItem link = new AnchorListItem(); link.setIcon(icon); link.getWidget(0).setStyleName("nav-item-iconic"); // Fix for IE11 link.setTitle(title); link.addClickHandler(e -> action.execute()); return new BaseMenuCustom() { @Override public IsWidget build() { return link; } @Override public MenuPosition getPosition() { return MenuPosition.RIGHT; } }; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/NavBarHelper.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuFactory.MenuBuilder; import org.uberfire.workbench.model.menu.MenuFactory.TopLevelMenusBuilder; import org.uberfire.workbench.model.menu.MenuItem; @ApplicationScoped public class NavBarHelper { // code taken from DefaultWorkbenchFeaturesMenusHelper public TopLevelMenusBuilder buildMenusFromNavTree(NavTree navTree) { if (navTree == null) { return null; } MenuBuilder> builder = null; for (NavItem navItem : navTree.getRootItems()) { // Skip dividers if (navItem instanceof NavDivider) { continue; } // AF-953: Ignore empty groups if (navItem instanceof NavGroup && ((NavGroup) navItem).getChildren().isEmpty()) { continue; } // Build a top level menu entry if (builder == null) { builder = MenuFactory.newTopLevelMenu(navItem.getName()); } else { builder = builder.endMenu().newTopLevelMenu(navItem.getName()); } // Append its children if (navItem instanceof NavGroup) { List childItems = buildMenuItemsFromNavGroup((NavGroup) navItem); if (! childItems.isEmpty()) { builder.withItems(childItems); } } // Append the place request NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); if (navCtx.getResourceId() != null && ActivityResourceType.PERSPECTIVE.equals(navCtx.getResourceType())) { PlaceRequest placeRequest = resolvePlaceRequest(navCtx.getResourceId()); builder = builder.place(placeRequest); } } return builder != null ? builder.endMenu() : null; } private List buildMenuItemsFromNavGroup(NavGroup navGroup) { List result = new ArrayList<>(); for (NavItem navItem : navGroup.getChildren()) { // Skip dividers if (navItem instanceof NavDivider) { continue; } // Append its children MenuBuilder builder = MenuFactory.newSimpleItem(navItem.getName()); if (navItem instanceof NavGroup) { List childItems = buildMenuItemsFromNavGroup((NavGroup) navItem); if (!childItems.isEmpty()) { builder.withItems(childItems); } } // Append the place request NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); if (navCtx.getResourceId() != null && ActivityResourceType.PERSPECTIVE.equals(navCtx.getResourceType())) { PlaceRequest placeRequest = resolvePlaceRequest(navCtx.getResourceId()); builder.place(placeRequest); } // Build the menu item & continue with the next one MenuItem menuItem = builder.endMenu().build().getItems().get(0); result.add(menuItem); } return result; } public PlaceRequest resolvePlaceRequest(String perspectiveId) { return new DefaultPlaceRequest(perspectiveId); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/navbar/RuntimeNavBrand.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.enterprise.context.ApplicationScoped; import org.uberfire.client.workbench.widgets.menu.megamenu.brand.MegaMenuBrand; @ApplicationScoped public class RuntimeNavBrand implements MegaMenuBrand { @Override public String brandImageUrl() { return "./images/runtime_logo.png"; } @Override public String brandImageLabel() { return "Dashbuilder Runtime"; } @Override public String menuAccessorLabel() { return "Dashboards"; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/perspective/DashboardsListPerspective.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspective; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.DashboardsListScreen; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @ApplicationScoped @WorkbenchPerspective(identifier = DashboardsListPerspective.ID) public class DashboardsListPerspective { private static AppConstants i18n = AppConstants.INSTANCE; public static final String ID = "DashboardsListPerspective"; @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(StaticWorkbenchPanelPresenter.class.getName()); final PlaceRequest place = new DefaultPlaceRequest(DashboardsListScreen.ID); PartDefinitionImpl dashboardScreen = new PartDefinitionImpl(place); perspective.getRoot().addPart(dashboardScreen); perspective.setName(i18n.listDashboardsScreenTitle()); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/perspective/EmptyPerspective.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspective; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.screens.EmptyScreen; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @ApplicationScoped @WorkbenchPerspective(identifier = EmptyPerspective.ID) public class EmptyPerspective { public static final String ID = "EmptyPerspective"; @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(StaticWorkbenchPanelPresenter.class.getName()); final PlaceRequest place = new DefaultPlaceRequest(EmptyScreen.ID); PartDefinitionImpl dashboardScreen = new PartDefinitionImpl(place); perspective.getRoot().addPart(dashboardScreen); perspective.setName("Upload Dashboard"); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/perspective/NotFoundPerspective.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspective; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.screens.NotFoundScreen; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @ApplicationScoped @WorkbenchPerspective(identifier = NotFoundPerspective.ID) public class NotFoundPerspective { public static final String ID = "NotFoundPerspective"; @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(StaticWorkbenchPanelPresenter.class.getName()); final PlaceRequest place = new DefaultPlaceRequest(NotFoundScreen.ID); PartDefinitionImpl dashboardScreen = new PartDefinitionImpl(place); perspective.getRoot().addPart(dashboardScreen); perspective.setName("Not Found Perspective"); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/perspective/RouterPerspective.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspective; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.RouterScreen; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @ApplicationScoped @WorkbenchPerspective(identifier = RouterPerspective.ID, isDefault = true) public class RouterPerspective { private static AppConstants i18n = AppConstants.INSTANCE; public static final String ID = "RouterPerspective"; @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(StaticWorkbenchPanelPresenter.class.getName()); final PlaceRequest place = new DefaultPlaceRequest(RouterScreen.ID); PartDefinitionImpl dashboardScreen = new PartDefinitionImpl(place); perspective.getRoot().addPart(dashboardScreen); perspective.setName(i18n.routerPerspective()); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/perspective/RuntimePerspective.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspective; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.screens.RuntimeScreen; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @ApplicationScoped @WorkbenchPerspective(identifier = RuntimePerspective.ID) public class RuntimePerspective { public static final String ID = "RuntimePerspective"; @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(StaticWorkbenchPanelPresenter.class.getName()); final PlaceRequest place = new DefaultPlaceRequest(RuntimeScreen.ID); PartDefinitionImpl dashboardScreen = new PartDefinitionImpl(place); perspective.getRoot().addPart(dashboardScreen); perspective.setName("Dashboards"); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/perspective/generator/RuntimePerspectiveEditorActivity.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspective.generator; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.plugin.client.perspective.editor.generator.PerspectiveEditorActivity; import org.uberfire.ext.plugin.client.perspective.editor.generator.PerspectiveEditorScreenActivity; public class RuntimePerspectiveEditorActivity extends PerspectiveEditorActivity { public RuntimePerspectiveEditorActivity(LayoutTemplate editor, PerspectiveEditorScreenActivity screen) { super(editor, screen); } @Override protected String getDefaultPanelType() { return StaticWorkbenchPanelPresenter.class.getName(); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/perspective/generator/RuntimePerspectiveGenerator.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspective.generator; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.Activity; import org.uberfire.client.mvp.ActivityBeansCache; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.WorkbenchScreenActivity; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.layout.editor.client.generator.LayoutGenerator; import org.uberfire.ext.plugin.client.perspective.editor.generator.PerspectiveEditorActivity; import org.uberfire.ext.plugin.client.perspective.editor.generator.PerspectiveEditorScreenActivity; import org.uberfire.jsbridge.client.cdi.SingletonBeanDefinition; import static org.jboss.errai.ioc.client.QualifierUtil.DEFAULT_QUALIFIERS; @ApplicationScoped public class RuntimePerspectiveGenerator { @Inject private SyncBeanManager beanManager; @Inject private ActivityBeansCache activityBeansCache; @Inject private LayoutGenerator layoutGenerator; public PerspectiveEditorActivity generatePerspective(LayoutTemplate layoutTemplate) { if (isANewPerspective(layoutTemplate)) { PerspectiveEditorScreenActivity screen = createNewScreen(layoutTemplate); return createNewPerspective(layoutTemplate, screen); } else { PerspectiveEditorScreenActivity screen = updateScreen(layoutTemplate); return updatePerspective(layoutTemplate, screen); } } private PerspectiveEditorScreenActivity createNewScreen(LayoutTemplate perspective) { PerspectiveEditorScreenActivity activity = new PerspectiveEditorScreenActivity(perspective, layoutGenerator); final Set qualifiers = new HashSet<>(Arrays.asList(DEFAULT_QUALIFIERS)); final SingletonBeanDefinition beanDef = new SingletonBeanDefinition<>( activity, PerspectiveEditorScreenActivity.class, qualifiers, activity.getIdentifier(), true, WorkbenchScreenActivity.class, Activity.class); beanManager.registerBean(beanDef); beanManager.registerBeanTypeAlias(beanDef, Activity.class); beanManager.registerBeanTypeAlias(beanDef, WorkbenchScreenActivity.class); String activityID = activity.getIdentifier(); activityBeansCache.removeActivity(activityID); activityBeansCache.addNewScreenActivity(beanManager.lookupBeans(activityID).iterator().next()); return activity; } private PerspectiveEditorActivity createNewPerspective(LayoutTemplate perspective, PerspectiveEditorScreenActivity screen) { final PerspectiveEditorActivity activity = new RuntimePerspectiveEditorActivity(perspective, screen); String perspectiveName = perspective.getName(); beanManager.registerBean(new SingletonBeanDefinition<>(activity, PerspectiveActivity.class, new HashSet<>(Arrays.asList(DEFAULT_QUALIFIERS)), perspectiveName, true)); activityBeansCache.removeActivity(perspectiveName); activityBeansCache.addNewPerspectiveActivity(beanManager.lookupBeans(perspectiveName).iterator().next()); return activity; } private PerspectiveEditorScreenActivity updateScreen(LayoutTemplate layoutTemplate) { final String perspectiveScreenId = PerspectiveEditorScreenActivity.buildScreenId(layoutTemplate.getName()); final SyncBeanDef activity = activityBeansCache.getActivity(perspectiveScreenId); final PerspectiveEditorScreenActivity screenActivity = (PerspectiveEditorScreenActivity) activity.getInstance(); screenActivity.setLayoutTemplate(layoutTemplate); return screenActivity; } private PerspectiveEditorActivity updatePerspective(LayoutTemplate layoutTemplate, PerspectiveEditorScreenActivity screen) { final SyncBeanDef activity = activityBeansCache.getActivity(layoutTemplate.getName()); final PerspectiveEditorActivity perspectiveEditorActivity = (PerspectiveEditorActivity) activity.getInstance(); perspectiveEditorActivity.update(layoutTemplate, screen); return perspectiveEditorActivity; } private boolean isANewPerspective(LayoutTemplate layoutTemplate) { return activityBeansCache.getActivity(layoutTemplate.getName()) == null; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/plugins/RuntimePerspectivePluginManager.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.plugins; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.stream.Collectors; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Alternative; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.navigation.plugin.PerspectivePluginManager; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.layout.LayoutRecursionIssue; import org.dashbuilder.navigation.layout.LayoutTemplateContext; import org.dashbuilder.navigation.layout.LayoutTemplateInfo; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.common.client.ui.ElementWrapperWidget; import org.uberfire.ext.layout.editor.api.editor.LayoutInstance; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.layout.editor.client.generator.LayoutGenerator; import org.uberfire.ext.plugin.model.Plugin; import org.uberfire.ext.plugin.model.PluginType; import org.uberfire.mvp.ParameterizedCommand; /** * A specific Runtime perspective plugin manager. This is used by Navigation Components to load a custom perspective. * */ @Alternative @ApplicationScoped public class RuntimePerspectivePluginManager implements PerspectivePluginManager { @Inject LayoutGenerator layoutGenerator; List templates = new ArrayList<>(); @Override public void loadPlugins() { // not used in Runtime } @Override public void getPerspectivePlugins(ParameterizedCommand> callback) { List plugins = templates.stream() .map(lt -> new Plugin(lt.getName(), PluginType.PERSPECTIVE, null)) .collect(Collectors.toList()); callback.execute(plugins); } @Override public boolean isRuntimePerspective(Plugin plugin) { return searchLayoutTemplate(plugin.getName()); } @Override public boolean isRuntimePerspective(NavItem navItem) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); String resourceId = navCtx.getResourceId(); return searchLayoutTemplate(resourceId); } @Override public boolean isRuntimePerspective(String perspectiveId) { return searchLayoutTemplate(perspectiveId); } @Override public String getRuntimePerspectiveId(NavItem navItem) { NavWorkbenchCtx navCtx = NavWorkbenchCtx.get(navItem); return navCtx.getResourceId(); } @Override public boolean existsPerspectivePlugin(String perspectiveName) { return searchLayoutTemplate(perspectiveName); } @Override public void getLayoutTemplateInfo(String perspectiveName, ParameterizedCommand callback) { // not used in runtime } @Override public void getLayoutTemplateInfo(LayoutTemplate layoutTemplate, ParameterizedCommand callback) { // not used in runtime } @Override public void buildPerspectiveWidget(String perspectiveName, LayoutTemplateContext layoutCtx, ParameterizedCommand afterBuild, ParameterizedCommand onInfiniteRecursion) { templates.stream().filter(lt -> lt.getName().equals(perspectiveName)).findFirst().ifPresent(lt -> { LayoutInstance result = layoutGenerator.build(lt); IsWidget widget = ElementWrapperWidget.getWidget(result.getElement()); afterBuild.execute(widget); }); } @Override public NavGroup getLastBuildPerspectiveNavGroup() { return null; } public void setTemplates(List templates) { this.templates = templates; } private boolean searchLayoutTemplate(String name) { return templates.stream().anyMatch(lt -> lt.getName().equals(name)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/resources/i18n/AppConstants.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface AppConstants extends Messages { public static final AppConstants INSTANCE = GWT.create(AppConstants.class); String logoutMenuTooltip(); String errorLoadingDashboards(); String loadingDashboards(); String errorUploadingDashboards(); String uploadingDashboards(); String runtimeScreenTitle(); String uploadDashboardsTitle(); String notFoundScreenTitle(); String notFoundDashboard(String perspectiveName); String routerScreenTitle(); String dashboardsListScreenTitle(); String dashboardListTooltip(); String listDashboardsScreenTitle(); String routerPerspective(); String dashboardAlreadyImport(String newModelId, String exitingModel); String importSuccess(String fileName); String disconnectedFromServer(); String couldNotConnectToServer(); String sessionTimeout(); String invalidBusResponseProbablySessionTimeout(); String dashboardOpenTooltip(); } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/DashboardsListScreen.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import java.util.List; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.perspective.DashboardsListPerspective; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.widgets.DashboardCard; import org.dashbuilder.shared.event.RemovedRuntimeModelEvent; import org.dashbuilder.shared.event.UpdatedRuntimeModelEvent; import org.jboss.errai.ioc.client.api.ManagedInstance; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PerspectiveManager; import org.uberfire.client.mvp.UberElemental; import org.uberfire.lifecycle.OnClose; /** * Screen that shows a list of dashboards available in a MULTI dashboards installation. * */ @ApplicationScoped @WorkbenchScreen(identifier = DashboardsListScreen.ID) public class DashboardsListScreen { public static final String ID = "ListDashboardsScreen"; private static AppConstants i18n = AppConstants.INSTANCE; @Inject RouterScreen router; @Inject PerspectiveManager perspectiveManager; public interface View extends UberElemental { void addCard(DashboardCard card); void clear(); } @Inject View view; @Inject ManagedInstance dashboardCardInstance; @PostConstruct public void init() { view.init(this); } public void loadList(List dashboardsNames) { clear(); dashboardsNames.stream() .map(this::createDashboardCard) .forEach(view::addCard); } private DashboardCard createDashboardCard(String id) { DashboardCard card = dashboardCardInstance.get(); card.setDashboardId(id); return card; } @WorkbenchPartTitle public String getScreenTitle() { return i18n.dashboardsListScreenTitle(); } @WorkbenchPartView public View workbenchPart() { return this.view; } @OnClose public void clear() { dashboardCardInstance.destroyAll(); view.clear(); } public void onModelUpdated(@Observes UpdatedRuntimeModelEvent event) { reload(); } public void onModelRemoved(@Observes RemovedRuntimeModelEvent event) { reload(); } private void reload() { String currentPlace = perspectiveManager.getCurrentPerspective().getIdentifier(); if (DashboardsListPerspective.ID.equals(currentPlace)) { router.listDashboards(); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/EmptyScreen.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.perspective.EmptyPerspective; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.shared.event.UpdatedRuntimeModelEvent; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PerspectiveManager; import org.uberfire.client.mvp.UberElemental; /** * Screen displayed when there's no dashboards available. * */ @ApplicationScoped @WorkbenchScreen(identifier = EmptyScreen.ID) public class EmptyScreen { public static final String ID = "EmptyScreen"; private static final AppConstants i18n = AppConstants.INSTANCE; @Inject View view; @Inject RouterScreen router; @Inject PerspectiveManager perspectiveManager; public interface View extends UberElemental { } @PostConstruct public void init() { view.init(this); } @WorkbenchPartTitle public String title() { return i18n.uploadDashboardsTitle(); } @WorkbenchPartView protected View getPart() { return view; } public void onModelUpdated(@Observes UpdatedRuntimeModelEvent event) { reload(); } private void reload() { String currentPlace = perspectiveManager.getCurrentPerspective().getIdentifier(); if (EmptyPerspective.ID.equals(currentPlace)) { router.listDashboards(); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/NotFoundScreen.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.Window; import org.dashbuilder.client.RuntimeEntryPoint; import org.dashbuilder.client.resources.i18n.AppConstants; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.UberElemental; import org.uberfire.lifecycle.OnOpen; /** * Screen displayed when a perspective is not found. * */ @ApplicationScoped @WorkbenchScreen(identifier = NotFoundScreen.ID) public class NotFoundScreen { public static final String ID = "NotFoundScreen"; private static AppConstants i18n = AppConstants.INSTANCE; public interface View extends UberElemental { void setNotFoundDashboard(String perspectiveName); } @Inject View view; @OnOpen public void onOpen() { List targetParams = Window.Location.getParameterMap().get(RuntimeEntryPoint.DASHBOARD_PARAM); if (targetParams != null && !targetParams.isEmpty()) { String dashboardName = targetParams.get(0); view.setNotFoundDashboard(dashboardName); } } @WorkbenchPartTitle public String getScreenTitle() { return i18n.notFoundScreenTitle(); } @WorkbenchPartView public View workbenchPart() { return this.view; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/RouterScreen.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import elemental2.dom.DomGlobal; import org.dashbuilder.client.RuntimeClientLoader; import org.dashbuilder.client.RuntimeCommunication; import org.dashbuilder.client.navbar.AppNavBar; import org.dashbuilder.client.perspective.DashboardsListPerspective; import org.dashbuilder.client.perspective.EmptyPerspective; import org.dashbuilder.client.perspective.RuntimePerspective; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.shared.event.UpdatedRuntimeModelEvent; import org.dashbuilder.shared.model.DashbuilderRuntimeMode; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.model.RuntimeServiceResponse; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElemental; import org.uberfire.lifecycle.OnOpen; /** * * Responsible for handling screens transition and communication. * */ @ApplicationScoped @WorkbenchScreen(identifier = RouterScreen.ID) public class RouterScreen { public static final String ID = "RouterScreen"; private static AppConstants i18n = AppConstants.INSTANCE; public interface View extends UberElemental { } @Inject RuntimeClientLoader clientLoader; @Inject RuntimeScreen runtimeScreen; @Inject DashboardsListScreen dashboardsListScreen; @Inject RuntimeCommunication runtimeCommunication; @Inject PlaceManager placeManager; @Inject AppNavBar appNavBar; @Inject View view; private DashbuilderRuntimeMode mode; @WorkbenchPartTitle public String title() { return i18n.routerScreenTitle(); } @WorkbenchPartView public View getView() { return view; } @OnOpen public void onOpen() { doRoute(); } public void doRoute() { clientLoader.load(this::route, (a, t) -> runtimeCommunication.showError(i18n.errorLoadingDashboards(), t)); } protected void route(RuntimeServiceResponse response) { this.mode = response.getMode(); Optional runtimeModelOp = response.getRuntimeModelOp(); if (mode == DashbuilderRuntimeMode.MULTIPLE_IMPORT) { appNavBar.setDashboardListEnabled(true); appNavBar.setup(); } if (runtimeModelOp.isPresent()) { RuntimeModel runtimeModel = runtimeModelOp.get(); placeManager.goTo(RuntimePerspective.ID); runtimeScreen.loadDashboards(runtimeModel); runtimeScreen.goToIndex(runtimeModel.getLayoutTemplates()); return; } if (response.getAvailableModels().isEmpty()) { placeManager.goTo(EmptyPerspective.ID); return; } dashboardsListScreen.loadList(response.getAvailableModels()); placeManager.goTo(DashboardsListPerspective.ID); } public void afterDashboardUpload(String id) { if (mode != null && mode == DashbuilderRuntimeMode.MULTIPLE_IMPORT) { listDashboards(); } else { loadDashboard(id); } } public void loadDashboard(String importId) { String newUrl = GWT.getHostPageBaseURL() + "?" + RuntimeClientLoader.IMPORT_ID_PARAM + "=" + importId; DomGlobal.window.history.replaceState(null, "Dashbuilder Runtime |" + importId, newUrl); doRoute(); } public void listDashboards() { DomGlobal.window.history.replaceState(null, "Dashbuilder Runtime", GWT.getHostPageBaseURL()); doRoute(); } public void onUpdatedRuntimeModelEvent(@Observes UpdatedRuntimeModelEvent updatedRuntimeModelEvent) { String updatedModel = updatedRuntimeModelEvent.getRuntimeModelId(); if (updatedModel.equals(clientLoader.getImportId())) { doRoute(); runtimeScreen.setKeepHistory(true); } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/RuntimeScreen.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.dashbuilder.client.navbar.AppNavBar; import org.dashbuilder.client.navbar.NavBarHelper; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.shared.model.RuntimeModel; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElemental; import org.uberfire.client.workbench.events.PerspectiveChange; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.workbench.model.menu.Menus; /** * The Main application screen that contains dashboards from a RuntimeModel. * */ @ApplicationScoped @WorkbenchScreen(identifier = RuntimeScreen.ID) public class RuntimeScreen { public static final String ID = "RuntimeScreen"; public static final String INDEX_PAGE_NAME = "index"; private static AppConstants i18n = AppConstants.INSTANCE; public interface View extends UberElemental { void addMenus(Menus menus); } @Inject View view; @Inject NavBarHelper menusHelper; @Inject PlaceManager placeManager; @Inject AppNavBar appNavBar; private RuntimeModel currentRuntimeModel; String lastVisited; boolean keepHistory; @WorkbenchPartTitle public String getScreenTitle() { return i18n.runtimeScreenTitle(); } @WorkbenchPartView public View workbenchPart() { return this.view; } public void loadDashboards(RuntimeModel runtimeModel) { this.currentRuntimeModel = runtimeModel; refreshMenus(); } public void goToIndex(List templates) { if (keepHistory && lastVisited != null && templates.stream().anyMatch(t -> t.getName().equals(lastVisited))) { keepHistory = false; placeManager.goTo(lastVisited); } else if (templates.size() == 1) { placeManager.goTo(templates.get(0).getName()); } else { templates.stream() .map(LayoutTemplate::getName) .filter(INDEX_PAGE_NAME::equals) .findFirst() .ifPresent(placeManager::goTo); } } public void setKeepHistory(boolean keepHistory) { this.keepHistory = keepHistory; } void onPerspectiveChange(@Observes PerspectiveChange perspectiveChange) { if (currentRuntimeModel != null) { String perspective = perspectiveChange.getIdentifier(); boolean isLayoutTemplate = currentRuntimeModel.getLayoutTemplates() .stream() .anyMatch(lt -> lt.getName().equals(perspective)); appNavBar.setExternalMenuEnabled(isLayoutTemplate); refreshMenus(); if (isLayoutTemplate) { lastVisited = perspective; } } else { appNavBar.setupMenus(); } } private void refreshMenus() { NavTree navTree = currentRuntimeModel.getNavTree(); Menus menus = menusHelper.buildMenusFromNavTree(navTree).build(); view.addMenus(menus); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/DashboardsListScreenView.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ .listTitle { font-size: 1.5em; margin: 0px 8px 0px 8px; float: left; } .uploadButtonContainer { float: right; margin-right: 15px; margin-bottom: 5px; } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/DashboardsListScreenView.html ================================================
    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/DashboardsListScreenView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.DashboardsListScreen; import org.dashbuilder.client.widgets.DashboardCard; import org.dashbuilder.client.widgets.UploadWidget; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated @Dependent public class DashboardsListScreenView implements DashboardsListScreen.View { AppConstants i18n = AppConstants.INSTANCE; @Inject @DataField HTMLDivElement dashboardsListRoot; @Inject @DataField HTMLDivElement uploadWidgetContainer; @Inject @DataField HTMLDivElement dashboardsList; @Inject UploadWidget uploadWidget; @Override public HTMLElement getElement() { return dashboardsListRoot; } @Override public void init(DashboardsListScreen presenter) { uploadWidgetContainer.appendChild(uploadWidget.getElement()); } @Override public void addCard(DashboardCard card) { dashboardsList.appendChild(card.getElement()); } @Override public void clear() { dashboardsList.innerHTML = ""; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/EmptyScreenView.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #emptyImport { height: 100%; } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/EmptyScreenView.html ================================================

    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/EmptyScreenView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.EmptyScreen; import org.dashbuilder.client.widgets.UploadWidget; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated @Dependent public class EmptyScreenView implements EmptyScreen.View { AppConstants i18n = AppConstants.INSTANCE; @Inject @DataField HTMLDivElement emptyImport; @Inject @DataField HTMLDivElement uploadContainer; @Inject UploadWidget uploadWidget; @Override public HTMLElement getElement() { return emptyImport; } @Override public void init(EmptyScreen presenter) { uploadContainer.appendChild(uploadWidget.getElement()); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/NotFoundScreenView.html ================================================

    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/NotFoundScreenView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLParagraphElement; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.NotFoundScreen; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class NotFoundScreenView implements NotFoundScreen.View { private static AppConstants i18n = AppConstants.INSTANCE; @Inject @DataField HTMLDivElement root; @Inject @DataField HTMLParagraphElement subTitle; @Override public HTMLElement getElement() { return root; } @Override public void init(NotFoundScreen presenter) { // do nothing } @Override public void setNotFoundDashboard(String perspectiveName) { subTitle.textContent = i18n.notFoundDashboard(perspectiveName); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/RouterScreenView.html ================================================
    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/RouterScreenView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.RouterScreen; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; @Templated @Dependent public class RouterScreenView implements RouterScreen.View { AppConstants i18n = AppConstants.INSTANCE; @Inject @DataField HTMLDivElement routerRoot; @Override public HTMLElement getElement() { return routerRoot; } @Override public void init(RouterScreen presenter) { // not used } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/RuntimeScreenView.html ================================================

    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/RuntimeScreenView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import org.dashbuilder.client.RuntimeCommunication; import org.dashbuilder.client.navbar.AppNavBar; import org.dashbuilder.client.screens.RuntimeScreen; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.workbench.model.menu.Menus; @Dependent @Templated public class RuntimeScreenView implements RuntimeScreen.View { @Inject @DataField HTMLDivElement runtimePage; @Inject AppNavBar appNavBar; @Inject RuntimeCommunication runtimeCommunication; @Inject BusyIndicatorView loading; @Override public HTMLElement getElement() { return runtimePage; } @Override public void init(RuntimeScreen presenter) { // empty } @Override public void addMenus(Menus menus) { appNavBar.setupMenus(menus); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/screens/view/RuntimeScreenView.less ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #runtimePage { height: 100%; .runtimePageBody { background-image: url('./images/runtime_home_bg.jpg'); align-items: stretch; display: flex; justify-content: space-between; flex-flow: column nowrap; height: 100%; max-height: 100vh; } .runtimePage__content { flex: 1 1 auto; } .runtimeContent--bg-image { background-color: #4d5258; background-position: top center; background-size: cover; .blank-slate-pf { background-color: transparent; color: #d1d1d1; border: 0; } } .runtime-container-fluid--blank-slate { @media (min-width: 992px) { width: 100%; background-color: rgba(0, 0, 0, .2); } } .runtime-blank-slate { display: flex; background-color: transparent; @media (min-width: 992px) { align-items: center; } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/widgets/DashboardCard.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.HTMLElement; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.RouterScreen; import org.jboss.errai.ui.client.local.api.elemental2.IsElement; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElemental; /** * Allow users to upload new dashboards * */ @Dependent public class DashboardCard implements IsElement { static final AppConstants i18n = AppConstants.INSTANCE; @Inject View view; @Inject RouterScreen routerScreen; @Inject PlaceManager placeManager; public interface View extends UberElemental { void setDashboardId(String title); } @PostConstruct public void init() { this.view.init(this); } @Override public HTMLElement getElement() { return this.view.getElement(); } public void setDashboardId(String dashboardId) { view.setDashboardId(dashboardId); } public void onCardSelected(String dashboardId) { routerScreen.loadDashboard(dashboardId); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/widgets/UploadWidget.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import elemental2.dom.DomGlobal; import elemental2.dom.FormData; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLFormElement; import elemental2.dom.RequestInit; import elemental2.dom.Response; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.RouterScreen; import org.jboss.errai.ui.client.local.api.elemental2.IsElement; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElemental; /** * Allow users to upload new dashboards * */ @Dependent public class UploadWidget implements IsElement { static final AppConstants i18n = AppConstants.INSTANCE; @Inject View view; @Inject RouterScreen routerScreen; @Inject PlaceManager placeManager; public interface View extends UberElemental { void loading(); void stopLoading(); void badResponseUploading(Response response); void errorDuringUpload(Object error); void dashboardAlreadyImportedError(String importName, String modelId); void importSuccess(String importName); } @PostConstruct public void init() { this.view.init(this); } @Override public HTMLElement getElement() { return this.view.getElement(); } public void submit(String fileName, final HTMLFormElement uploadForm) { RequestInit request = RequestInit.create(); request.setMethod("POST"); request.setBody(new FormData(uploadForm)); view.loading(); DomGlobal.window.fetch("./rest/upload", request) .then((Response response) -> response.text().then(newImportName -> { view.stopLoading(); if (response.status == 200) { openImport(newImportName); } else if(response.status == 409) { importAlreadyExists(fileName, newImportName); } else { view.badResponseUploading(response); } return null; }), error -> { view.stopLoading(); view.errorDuringUpload(error); return null; }); } private void openImport(final String newImportName) { view.importSuccess(newImportName); routerScreen.afterDashboardUpload(newImportName); } private void importAlreadyExists(final String fileName, final String modelId) { view.dashboardAlreadyImportedError(fileName, modelId); routerScreen.afterDashboardUpload(modelId); } public String retrieveFileName(String value) { int pos = 0; if (value.contains("\\")) { pos = value.lastIndexOf('\\'); } else if (value.contains("/")) { pos = value.lastIndexOf('/'); } return value.substring(pos + 1); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/widgets/view/DashboardCardView.html ================================================

    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/widgets/view/DashboardCardView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.inject.Named; import com.google.gwt.event.dom.client.ClickEvent; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLHeadingElement; import org.dashbuilder.client.widgets.DashboardCard; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; @Dependent @Templated public class DashboardCardView implements DashboardCard.View { @Inject @DataField HTMLDivElement dashboardCardRoot; @Inject @DataField @Named("h2") HTMLHeadingElement cardTitle; private String dashboardId; private DashboardCard presenter; @Override public HTMLElement getElement() { return dashboardCardRoot; } @Override public void init(DashboardCard presenter) { this.presenter = presenter; } @Override public void setDashboardId(String dashboardId) { this.dashboardId = dashboardId; cardTitle.textContent = dashboardId; } @EventHandler("dashboardCardRoot") public void onCardSelected(ClickEvent e) { presenter.onCardSelected(dashboardId); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/widgets/view/UploadWidgetView.html ================================================
    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/client/widgets/view/UploadWidgetView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.widgets.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ClickEvent; import elemental2.dom.HTMLButtonElement; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import elemental2.dom.HTMLFormElement; import elemental2.dom.HTMLInputElement; import elemental2.dom.Response; import org.dashbuilder.client.RuntimeCommunication; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.widgets.UploadWidget; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; @Dependent @Templated public class UploadWidgetView implements UploadWidget.View { private static final AppConstants i18n = AppConstants.INSTANCE; UploadWidget presenter; @Inject @DataField HTMLDivElement uploadButtonContainer; @Inject @DataField HTMLButtonElement btnImport; @Inject @DataField HTMLFormElement uploadForm; @Inject @DataField HTMLInputElement inputFile; @Inject @DataField HTMLInputElement inputFileName; @Inject RuntimeCommunication runtimeCommunication; @Inject BusyIndicatorView loading; @Override public void init(UploadWidget presenter) { this.presenter = presenter; } @Override public void loading() { loading.showBusyIndicator(i18n.uploadingDashboards()); } @Override public void stopLoading() { loading.hideBusyIndicator(); } @Override public void badResponseUploading(Response response) { runtimeCommunication.showError(i18n.errorUploadingDashboards(), response); } @Override public void errorDuringUpload(Object error) { runtimeCommunication.showError(i18n.errorUploadingDashboards(), error); } @Override public void dashboardAlreadyImportedError(String newImportName, String existingImport) { runtimeCommunication.showWarning(i18n.dashboardAlreadyImport(newImportName, existingImport)); } @EventHandler("btnImport") public void handleImport(ClickEvent e) { inputFile.click(); } @EventHandler("inputFile") public void handleInputFileChange(ChangeEvent e) { String importName = presenter.retrieveFileName(inputFile.value); inputFileName.value = importName; presenter.submit(importName, uploadForm); } @Override public HTMLElement getElement() { return uploadButtonContainer; } @Override public void importSuccess(String importName) { runtimeCommunication.showSuccess(i18n.importSuccess(importName)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/event/NewDataSetContentEvent.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.event; import java.util.List; import org.dashbuilder.shared.model.DataSetContent; /** * Fired when new datasets are found in a Runtime model. * */ public class NewDataSetContentEvent { private String runtimeModelId; private List content; public NewDataSetContentEvent(String runtimeModelId, List content) { this.runtimeModelId = runtimeModelId; this.content = content; } public List getContent() { return content; } public String getRuntimeModelId() { return runtimeModelId; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/event/RemovedRuntimeModelEvent.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.event; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; /** * Fired when datasets are removed. * */ @Portable public class RemovedRuntimeModelEvent { /** * Removed runtime model IDs */ String runtimeModelId; public RemovedRuntimeModelEvent(@MapsTo("id") String id) { this.runtimeModelId = id; } public String getRuntimeModelId() { return runtimeModelId; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/event/UpdatedRuntimeModelEvent.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.event; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; /** * Fired only in dev mode when Runtime Models are updated * */ @Portable public class UpdatedRuntimeModelEvent { /** * Updated runtime model ID */ String runtimeModelId; public UpdatedRuntimeModelEvent() { // empty constructor for marshalling } public UpdatedRuntimeModelEvent(@MapsTo("id") String id) { this.runtimeModelId = id; } public String getRuntimeModelId() { return runtimeModelId; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/DashboardInfo.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; import java.util.Collection; /** * Specific Dashboard information. * */ public class DashboardInfo { private String runtimeModelId; private Collection pages; public DashboardInfo(String runtimeModelId, Collection pages) { this.runtimeModelId = runtimeModelId; this.pages = pages; } public String getRuntimeModelId() { return runtimeModelId; } public Collection getPages() { return pages; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/DashbuilderRuntimeInfo.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; import java.util.Collection; /** * Dashbuilder Runtime information. * */ public class DashbuilderRuntimeInfo { private String mode; private Collection availableModels; private boolean acceptingNewImports; public DashbuilderRuntimeInfo(String mode, Collection availableModels, boolean acceptingNewImports) { this.mode = mode; this.availableModels = availableModels; this.acceptingNewImports = acceptingNewImports; } public String getMode() { return mode; } public Collection getAvailableModels() { return availableModels; } public boolean isAcceptingNewImports() { return acceptingNewImports; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/DashbuilderRuntimeMode.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; /** * Execution for dashbuilder Runtime * */ public enum DashbuilderRuntimeMode { /** * Used when only the first import is used */ STATIC, /** * Allow users to import once */ SINGLE_IMPORT, /** * Users can import how many dashboards they want and reopen them later. */ MULTIPLE_IMPORT; } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/DataSetContent.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class DataSetContent { private String id; private String content; private DataSetContentType contentType; public DataSetContent() {} public DataSetContent(@MapsTo("id") String id, @MapsTo("content") String content, @MapsTo("contentType") DataSetContentType contentType) { this.id = id; this.content = content; this.contentType = contentType; } public void setId(String id) { this.id = id; } public String getId() { return id; } public String getContent() { return content; } public DataSetContentType getContentType() { return contentType; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/DataSetContentType.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public enum DataSetContentType { DEFINITION, CSV; public static DataSetContentType fromFileExtension(String ext) { if (ext.equalsIgnoreCase("dset")) { return DEFINITION; } if (ext.equalsIgnoreCase("csv")) { return CSV; } throw new IllegalArgumentException("Extension not supported: " + ext); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/ImportDefinitions.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; /** * Holds Constants for the Import ZIP * */ public class ImportDefinitions { public static final String DATASET_PREFIX = "dashbuilder/datasets"; public static final String DATASET_DEF_PREFIX = DATASET_PREFIX + "/definitions"; public static final String DATASET_SUFFIX = ".dset"; public static final String PERSPECTIVE_PREFIX = "dashbuilder/perspectives"; public static final String PERSPECTIVE_SUFFIX = "perspective_layout"; public static final String NAVIGATION_PREFIX = "dashbuilder/navigation"; public static final String NAVIGATION_FILE = NAVIGATION_PREFIX + "/navigation/navtree.json"; public static final String COMPONENT_PREFIX = "dashbuilder/components"; private ImportDefinitions() { } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/RuntimeModel.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; import java.util.List; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; /** * Representation of assets and information needed to build Runtime Dashbuilder client. * */ @Portable public class RuntimeModel { NavTree navTree; List layoutTemplates; Long lastModified; public RuntimeModel(@MapsTo("navTree") final NavTree navTree, @MapsTo("layoutTemplates") final List layoutTemplates, @MapsTo("lastModified") Long lastModified) { this.navTree = navTree; this.layoutTemplates = layoutTemplates; this.lastModified = lastModified; } public NavTree getNavTree() { return navTree; } public List getLayoutTemplates() { return layoutTemplates; } public Long getLastModified() { return lastModified; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/model/RuntimeServiceResponse.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.model; import java.util.List; import java.util.Optional; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; /** * Runtime Service response model object that contains any useful information for the client. */ @Portable public class RuntimeServiceResponse { private DashbuilderRuntimeMode mode; private Optional runtimeModelOp; private List availableModels; public RuntimeServiceResponse() { // not used } public RuntimeServiceResponse(@MapsTo("mode") DashbuilderRuntimeMode mode, @MapsTo("runtimeModelOp") Optional runtimeModelOp, @MapsTo("availableModels") List availableModels) { this.mode = mode; this.runtimeModelOp = runtimeModelOp; this.availableModels = availableModels; } public Optional getRuntimeModelOp() { return runtimeModelOp; } public List getAvailableModels() { return availableModels; } public DashbuilderRuntimeMode getMode() { return mode; } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/service/ImportValidationService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.service; /** * Validates an imported ZIP file * */ public interface ImportValidationService { /** * * Validate the file from the given path. * @param file * The File path * @return * true if the file is valid, false otherwise; */ public boolean validate(String file); } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/service/RuntimeModelParser.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.service; import java.io.InputStream; import org.dashbuilder.shared.model.RuntimeModel; /** * Parses an imported content to RuntimeModel. * */ public interface RuntimeModelParser { /** * Parse the given input stream into a RuntimeModel. * @param is * The input stream with runtime model binary content to be parsed. * @return * The parsed runtime model. */ RuntimeModel parse(String runtimeModelId, InputStream is); } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/service/RuntimeModelRegistry.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.service; import java.util.Collection; import java.util.Optional; import org.dashbuilder.shared.model.DashbuilderRuntimeMode; import org.dashbuilder.shared.model.RuntimeModel; import static org.dashbuilder.shared.model.DashbuilderRuntimeMode.MULTIPLE_IMPORT; /** * Provides access to a saved ImportModelService. * */ public interface RuntimeModelRegistry { public default boolean acceptingNewImports() { return getMode() == MULTIPLE_IMPORT || (getMode() == DashbuilderRuntimeMode.SINGLE_IMPORT && isEmpty()); } /** * Returns the first model available. * * @return */ Optional single(); /** * Returns if this registry has at least one model. * @return */ boolean isEmpty(); /** * Returns the registry mode * * @return */ DashbuilderRuntimeMode getMode(); /** * Get a previously registered import model. * @param id * @return */ Optional get(String id); /** * Sets this runtime mode. * * @param mode * The mode to be used. */ void setMode(DashbuilderRuntimeMode mode); /** * Store the import from a File path; * @param filePath * The path to the file. */ Optional registerFile(String filePath); /** * Removes a runtime model. * @param runtimeModelid * The id of the runtime model to be removed. */ void remove(String runtimeModelid); /** * Unregister a model from memory * @param runtimeModelid * The id of the runtime model to be unregistered. */ void unregister(String runtimeModelid); /** * List all models that are currently available. */ Collection availableModels(); /** * Remove all registered models. */ void clear(); } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/service/RuntimeModelService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.service; import java.util.Optional; import org.dashbuilder.shared.model.RuntimeServiceResponse; import org.dashbuilder.shared.model.RuntimeModel; import org.jboss.errai.bus.server.annotations.Remote; /** * Service to access RuntimeModel. * */ @Remote public interface RuntimeModelService { /** * Loads information about this installation. * * @param runtimeModelId * A runtime model id to be loaded. Can be null or an empty String. * @return * */ public RuntimeServiceResponse info(String runtimeModelId); /** * * Get a runtime model given an ID. * * @param runtimeModelId * The Runtime model represented by runtimeModelId. * @return * An optional containing the RuntimeModel or empty if the runtime model couldn't be found or built. */ Optional getRuntimeModel(String runtimeModelId); } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/java/org/dashbuilder/shared/services/ExternalImportService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.services; import java.util.Optional; import org.dashbuilder.shared.model.RuntimeModel; /** * Responsible for downloading external models and registering it * */ public interface ExternalImportService { /** * Register an external model coming from an external server * @param externalModelUrl * the external model URL * @return * Optional containing the downloaded RuntimeModel or empty */ Optional registerExternalImport(String externalModelUrl); } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. errai.marshalling.use_static_marshallers=false errai.marshalling.force_static_marshallers=false errai.ioc.enabled.alternatives=org.dashbuilder.client.plugins.RuntimePerspectivePluginManager \ org.uberfire.client.plugin.RuntimePluginsServiceProxyClientImpl \ org.uberfire.client.workbench.WorkbenchServicesProxyClientImpl \ org.uberfire.client.workbench.VFSServiceProxyClientImpl \ org.uberfire.client.workbench.VFSLockServiceProxyClientImpl \ org.uberfire.preferences.client.store.PreferenceBeanStoreClientImpl \ errai.ioc.denylist=org.uberfire.preferences.client.store.PreferenceBeanStoreImpl \ org.uberfire.client.RuntimePluginsServiceProxyBackendImpl \ org.uberfire.client.WorkbenchServicesProxyBackendImpl errai.marshalling.serializableTypes=org.dashbuilder.dataprovider.StaticProviderType \ org.dashbuilder.dataprovider.BeanProviderType \ org.dashbuilder.dataprovider.CSVProviderType \ org.dashbuilder.dataprovider.SQLProviderType \ org.dashbuilder.dataset.ColumnType \ org.dashbuilder.dataset.ColumnType \ org.dashbuilder.dataset.DataSetLookup \ org.dashbuilder.dataset.backend.EditDataSetDef \ org.dashbuilder.dataset.date.DayOfWeek \ org.dashbuilder.dataset.date.Month \ org.dashbuilder.dataset.date.Quarter \ org.dashbuilder.dataset.date.TimeAmount \ org.dashbuilder.dataset.date.TimeFrame \ org.dashbuilder.dataset.date.TimeInstant \ org.dashbuilder.dataset.def.DataSetDef \ org.dashbuilder.dataset.def.BeanDataSetDef \ org.dashbuilder.dataset.def.CSVDataSetDef \ org.dashbuilder.dataset.def.SQLDataSetDef \ org.dashbuilder.dataset.def.SQLDataSourceDef \ org.dashbuilder.dataset.def.StaticDataSetDef \ org.dashbuilder.dataset.def.DataColumnDef \ org.dashbuilder.dataset.events.DataSetDefModifiedEvent \ org.dashbuilder.dataset.events.DataSetDefRegisteredEvent \ org.dashbuilder.dataset.events.DataSetDefRemovedEvent \ org.dashbuilder.dataset.events.DataSetModifiedEvent \ org.dashbuilder.dataset.events.DataSetPushingEvent \ org.dashbuilder.dataset.events.DataSetPushOkEvent \ org.dashbuilder.dataset.events.DataSetStaleEvent \ org.dashbuilder.dataset.exception.DataSetLookupException \ org.dashbuilder.dataset.filter.CoreFunctionFilter \ org.dashbuilder.dataset.filter.CoreFunctionType \ org.dashbuilder.dataset.filter.DataSetFilter \ org.dashbuilder.dataset.filter.LogicalExprFilter \ org.dashbuilder.dataset.filter.LogicalExprType \ org.dashbuilder.dataset.group.AggregateFunctionType \ org.dashbuilder.dataset.group.ColumnGroup \ org.dashbuilder.dataset.group.DataSetGroup \ org.dashbuilder.dataset.group.DateIntervalType \ org.dashbuilder.dataset.group.GroupFunction \ org.dashbuilder.dataset.group.GroupStrategy \ org.dashbuilder.dataset.group.Interval \ org.dashbuilder.dataset.impl.DataColumnImpl \ org.dashbuilder.dataset.impl.DataSetBuilderImpl \ org.dashbuilder.dataset.impl.DataSetImpl \ org.dashbuilder.dataset.impl.DataSetLookupBuilderImpl \ org.dashbuilder.dataset.impl.DataSetMetadataImpl \ org.dashbuilder.dataset.sort.ColumnSort \ org.dashbuilder.dataset.sort.DataSetSort \ org.dashbuilder.dataset.sort.SortedList ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/application-roles.properties ================================================ admin=admin ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/application-users.properties ================================================ admin=207b6e0cc556d7084b5e2db7d822555c ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/org/dashbuilder/DashbuilderRuntime.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/org/dashbuilder/FastCompiledDashbuilderRuntime.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # EmptyScreenView.title=Dashboards are not available EmptyScreenView.subTitle=Dashboards were not imported. You can import them by uploading a file previously exported in Business Central. UploadWidgetView.importButton=Import Dashboards RuntimeScreenView.title=Welcome to Dashbuilder Runtimes RuntimeScreenView.subTitle=Select a Dashboard from menu to get started. NotFoundScreenView.title=Dashboard not found NotFoundScreenView.subTitle=Dashboard not found in this installation. Please check the dashboard name and try again. logoutMenuTooltip=Logout errorLoadingDashboards=Error Loading Dashboards loadingDashboards=Loading Dashboards errorUploadingDashboards=Error Uploading Dashboards uploadingDashboards=Uploading Dashboards runtimeScreenTitle=Welcome to Dashboards uploadDashboardsTitle=Upload Dashboards notFoundScreenTitle=Page not found notFoundDashboard=Dashboard {0} not found. Please review the dashboard name and try again. routerScreenTitle=Dashbuilder Runtime dashboardsListScreenTitle=Dashboards List DashboardsListScreenView.title=Available Dashboards dashboardListTooltip=Dashboards List listDashboardsScreenTitle=Dashboards List routerPerspective=Router dashboardAlreadyImport=Dashboard {0} already imported with name {1} importSuccess=Dashboard {0} successfully imported # Error messages disconnectedFromServer=Disconnected from server couldNotConnectToServer=Could not connect to server. This very likely means a network problem. Do you want to reload the application? sessionTimeout=Session timeout invalidBusResponseProbablySessionTimeout=Invalid response received from the server. This very likely means that you have been logged out due to inactivity. Do you want to log in again? dashboardOpenTooltip=Open this page in another tab ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_es.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # EmptyScreenView.title=Los cuadros de mando no están disponibles EmptyScreenView.subTitle=Los cuadros de mando no se han importado. Puede importarlos cargando un archivo previamente exportado en Business Central. UploadWidgetView.importButton=No hay cuadros de mando RuntimeScreenView.title=¡Bienvenido a Dashbuilder! RuntimeScreenView.subTitle=Seleccione un panel en el menú para empezar. NotFoundScreenView.title=No se encuentra el tablero de mandos NotFoundScreenView.subTitle=No se encuentra el tablero de mandos en esta instalación. Por favor, compruebe el nombre del panel de control y vuelva a intentarlo. logoutMenuTooltip=Cierre de sesión errorLoadingDashboards=Cargando el cuadro de mando ... loadingDashboards=Cargando el cuadro de mando ... errorUploadingDashboards=Error al cargar los cuadros de mando uploadingDashboards=Carga de cuadros de mando runtimeScreenTitle=¡Bienvenido a Dashbuilder! uploadDashboardsTitle=No hay cuadros de mando notFoundScreenTitle=No se encuentra la página notFoundDashboard=Tablero {0} no encontrado. Por favor, revise el nombre del tablero y vuelva a intentarlo. routerScreenTitle=Tiempo de ejecución de Dashbuilder dashboardsListScreenTitle=cuadros de mando DashboardsListScreenView.title=Cuadros de mando disponibles dashboardListTooltip=cuadros de mando listDashboardsScreenTitle=cuadros de mando routerPerspective=Router dashboardAlreadyImport=El tablero {0} ya se ha importado con el nombre \ {1\} importSuccess=Proyecto importado correctamente. # Error messages disconnectedFromServer=Desconectado del servidor couldNotConnectToServer=No se pudo conectar al servidor. Es muy probable que esto implique la existencia de un problema en la red. ¿Desea recargar la aplicación? sessionTimeout=Tiempo de espera de la sesión invalidBusResponseProbablySessionTimeout=Respuesta no válida recibida del servidor. Esto probablemente significa que se ha cerrado la sesión debido a la inactividad. ¿Desea iniciar sesión otra vez? dashboardOpenTooltip=Abrir esta página en otra pestaña ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_fr.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # EmptyScreenView.title=Les tableaux de bord ne sont pas disponibles EmptyScreenView.subTitle=Les tableaux de bord n''ont pas été importés. Vous pouvez les importer en téléchargeant un fichier précédemment exporté dans Business Central. UploadWidgetView.importButton=Tableaux de bord des importations RuntimeScreenView.title=Bienvenue dans les Runtimes de Dashbuilder ! RuntimeScreenView.subTitle=Sélectionnez un tableau de bord dans le menu pour commencer. NotFoundScreenView.title=Tableau de bord non trouvé NotFoundScreenView.subTitle=Tableau de bord non trouvé dans cette installation. Veuillez vérifier le nom du tableau de bord et réessayer. logoutMenuTooltip=Déconnexion errorLoadingDashboards=Erreur lors du chargement des tableaux de bord… loadingDashboards=Chargement des tableaux de bord… errorUploadingDashboards=Erreur lors du téléchargement des tableaux de bord… uploadingDashboards=Téléchargement des tableaux de bord runtimeScreenTitle=Bienvenue à Dashboards uploadDashboardsTitle=Télécharger les tableaux de bord notFoundScreenTitle=Page introuvable notFoundDashboard=Tableau de bord {0} non trouvé. Veuillez revoir le nom du tableau de bord et réessayer. routerScreenTitle=Dashbuilder Runtime dashboardsListScreenTitle=Liste des tableaux de bord DashboardsListScreenView.title=Tableaux de bord disponibles dashboardListTooltip=Liste des tableaux de bord listDashboardsScreenTitle=Liste des tableaux de bord routerPerspective=Routeur dashboardAlreadyImport=Tableau de bord {0} déjà importé avec le nom {1} importSuccess=Tableau de bord {0} importé avec succès # Error messages disconnectedFromServer=Déconnecté du serveur couldNotConnectToServer=Impossible de se connecter au serveur. Cela indique un probable problème réseau. Voulez-vous recharger l''application ? sessionTimeout=Timeout de session invalidBusResponseProbablySessionTimeout=Réponse non valide reçue du serveur. Cela signifie probablement que vous avez été déconnecté en raison de votre inactivité. Voulez-vous vous reconnecter ? dashboardOpenTooltip=Ouvrir cette page dans un autre onglet ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_it.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # EmptyScreenView.title=I dashboard non sono disponibili EmptyScreenView.subTitle=I dashboard non sono stati importati. Puoi importarli caricando un file precedentemente esportato in Business Central. UploadWidgetView.importButton=Importa Dashboard RuntimeScreenView.title=Benvenuto in Dashbuilder Runtimes RuntimeScreenView.subTitle=Seleziona un Dashboard dal menu per iniziare. NotFoundScreenView.title=Dashboard non trovato NotFoundScreenView.subTitle=Dashboard non trovato in questa installazione. Controlla il nome del dashboard e riprova. logoutMenuTooltip=Logout errorLoadingDashboards=Errore durante il caricamento delle dashboard loadingDashboards=Caricamento delle dashboard in corso errorUploadingDashboards=Errore durante l''importazione delle dashboard uploadingDashboards=Importazione delle dashboard in corso runtimeScreenTitle=Benvenuto in Dashboards uploadDashboardsTitle=Carica Dashboard notFoundScreenTitle=Pagina non trovata notFoundDashboard=Dashboard {0} non trovato. Controlla il nome del dashboard e riprova. routerScreenTitle=Dashbuilder Runtime dashboardsListScreenTitle=Elenco delle Dashboard DashboardsListScreenView.title=Dashboard disponibili dashboardListTooltip=Elenco delle Dashboard listDashboardsScreenTitle=Elenco delle Dashboard routerPerspective=Router dashboardAlreadyImport=Dashboard {0} già importato con nome {1} importSuccess=Dashboard {0} importato con successo # Error messages disconnectedFromServer=Disconnesso dal server couldNotConnectToServer=Impossibile connettersi al server. Molto probabilmente significa un problema di rete. Vuoi ricaricare l''applicazione? sessionTimeout=Timeout della sessione invalidBusResponseProbablySessionTimeout=Risposta non valida ricevuta dal server. Molto probabilmente significa che sei stato disconnesso a causa di inattività. Vuoi effettuare nuovamente il login? dashboardOpenTooltip=Apri questa pagina in un''altra scheda ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_ja.properties ================================================ # # Copyright (C) 2020 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # EmptyScreenView.title=ダッシュボードは利用できません EmptyScreenView.subTitle=ダッシュボードはインポートされませんでした。以前に Business Central でエクスポートしたファイルをアップロードすることで、そのファイルをインポートできます。 UploadWidgetView.importButton=ダッシュボードのインポート RuntimeScreenView.title=Dashbuilder Runtime にようこそ! RuntimeScreenView.subTitle=メニューからダッシュボードを選択して開始します。 NotFoundScreenView.title=ダッシュボードが見つかりません NotFoundScreenView.subTitle=このインストールではダッシュボードが見つかりません。ダッシュボード名を確認して再試行してください。 logoutMenuTooltip=ログアウト errorLoadingDashboards=ダッシュボードのロードエラー loadingDashboards=ダッシュボードのロード中 errorUploadingDashboards=ダッシュボードのアップロード中にエラー uploadingDashboards=ダッシュボードのアップロード runtimeScreenTitle=ダッシュボードへようこそ uploadDashboardsTitle=ダッシュボードのアップロード notFoundScreenTitle=ページが見つかりません notFoundDashboard=ダッシュボード {0} が見つかりません。ダッシュボード名を確認して再試行してください。 routerScreenTitle=Dashbuilder Runtime dashboardsListScreenTitle=ダッシュボードリスト DashboardsListScreenView.title=利用可能なダッシュボード dashboardListTooltip=ダッシュボードリスト listDashboardsScreenTitle=ダッシュボードリスト routerPerspective=ルーター dashboardAlreadyImport=ダッシュボード {0} はすでに {1} という名前でインポートされています importSuccess=ダッシュボード {0} が正常にインポートされました # Error messages disconnectedFromServer=サーバーから切断しました couldNotConnectToServer=サーバーに接続できませんでした。これはネットワークの問題である可能性が非常に高いです。アプリケーションをリロードしますか? sessionTimeout=セッションタイムアウト invalidBusResponseProbablySessionTimeout=サーバーから無効な応答を受け取りました。しばらく操作されなかったため、ログアウトした可能性が非常に高いです。再度ログインしますか? dashboardOpenTooltip=このページを別のタブで開く ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/WEB-INF/.gitignore ================================================ /classes/ ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/WEB-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/WEB-INF/jboss-deployment-structure.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/WEB-INF/jboss-web.xml ================================================ other / ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/WEB-INF/web.xml ================================================ GzipFilter org.dashbuilder.backend.gzip.GzipFilter GzipFilter *.js ErraiServlet org.jboss.errai.bus.server.servlet.DefaultBlockingServlet service-locator org.jboss.errai.cdi.server.CDIServiceLocator 1 ErraiServlet *.erraiBus LoginRedirectServlet org.dashbuilder.backend.security.LoginRedirectServlet display-after-login /dashbuilder.html LoginRedirectServlet /login dashbuilder.html DashbuilderExternalComponentsServlet org.dashbuilder.external.ExternalComponentServlet DashbuilderExternalComponentsServlet /dashbuilder/component/* HTTP Basic Auth Filter org.dashbuilder.backend.security.BasicAuthSecurityFilter realmName Dashbuilder Runtime Realm excludedPaths /rest/upload,/rest/healthy,/rest/ready HTTP Basic Auth Filter /rest/api/* FORM /login.html /login.html?loginMessage=Login failed. Please try again. Admin - Can import and read dashboards admin openResources /org.dashbuilder.DashbuilderRuntime/css/* /org.dashbuilder.DashbuilderRuntime/fonts/* /org.dashbuilder.DashbuilderRuntime/img/* /org.dashbuilder.DashbuilderRuntime/images/* /rest/ready /rest/healthy 403 /not_authorized.jsp default /rest/upload/* /dashbuilder.html /org.dashbuilder.DashbuilderRuntime/* *.erraiBus /plugins/* /dashbuilder/component/* admin ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/banner/banner.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/dashbuilder.html ================================================ Dashbuilder Runtime

    Please wait

    Loading application...
    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/login.html ================================================ Dashbuilder Runtime
    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/logout.jsp ================================================ <%-- ~ Copyright 2020 Red Hat, Inc. and/or its affiliates. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% request.logout(); javax.servlet.http.HttpSession httpSession = request.getSession(false); if (httpSession != null) { httpSession.invalidate(); } %> Dashbuilder Runtime
    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/main/webapp/not_authorized.jsp ================================================ <%-- ~ Copyright 2020 Red Hat, Inc. and/or its affiliates. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% request.getSession().invalidate(); %> Dashbuilder Runtime
    ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/DataSetContentListenerTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.util.Arrays; import java.util.List; import java.util.Map; import org.dashbuilder.backend.services.dataset.RuntimeCSVFileStorage; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.def.DataSetDefRegistry; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; import org.dashbuilder.shared.event.NewDataSetContentEvent; import org.dashbuilder.shared.event.RemovedRuntimeModelEvent; import org.dashbuilder.shared.model.DataSetContent; import org.dashbuilder.shared.model.DataSetContentType; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.ArgumentMatchers.matches; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class DataSetContentListenerTest { @Mock DataSetDefRegistry registry; @Mock RuntimeCSVFileStorage storage; @Mock DataSetDefJSONMarshaller defMarshaller; @Mock Map> runtimeModelDatasetContents; @InjectMocks DataSetContentListener datasetContentListener; @Test public void testRegister() throws Exception { final String runtimeModelId = "TEST"; final String C1 = "C1"; final String C2 = "C2"; final String content2 = "TESTCONTENT"; final String content3 = "TESTCSV"; List content = Arrays.asList(new DataSetContent(C1, content2, DataSetContentType.DEFINITION), new DataSetContent(C2, content3, DataSetContentType.CSV)); List contentIds = Arrays.asList(C1, C2); DataSetDef def = mock(DataSetDef.class); when(defMarshaller.fromJson(matches(content2))).thenReturn(def); datasetContentListener.register(new NewDataSetContentEvent(runtimeModelId, content)); verify(runtimeModelDatasetContents).put(runtimeModelId, contentIds); verify(storage).storeCSV(C2, content3); verify(def).setUUID(matches(C1)); verify(registry).registerDataSetDef(def); } @Test public void testUnregister() { final String id = "ID"; final String C1 = "C1"; List registeredContent = Arrays.asList(C1); when(runtimeModelDatasetContents.remove(matches(id))).thenReturn(registeredContent); datasetContentListener.unregister(new RemovedRuntimeModelEvent(id)); verify(storage).deleteCSVFile(matches(C1)); verify(registry).removeDataSetDef(matches(C1)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/RuntimeModelLoaderTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import org.apache.commons.io.FileUtils; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.matches; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class RuntimeModelLoaderTest { Path baseTempDir; @Mock RuntimeModelRegistry registry; @Mock RuntimeOptions runtimeOptions; @InjectMocks RuntimeModelLoader runtimeModelLoader; @Before public void init() throws IOException { baseTempDir = Files.createTempDirectory("dashbuilder-tests"); } @After public void cleanup() { FileUtils.deleteQuietly(baseTempDir.toFile()); } @Test public void testCreateBaseDir() { String tempPath = Paths.get(baseTempDir.toString(), "tmp").toString(); when(runtimeOptions.getImportsBaseDir()).thenReturn(tempPath); assertFalse(Paths.get(tempPath).toFile().exists()); runtimeModelLoader.setupBaseDir(); assertTrue(Paths.get(tempPath).toFile().exists()); } @Test public void testLoadAvailableModels() throws IOException { String baseDir = baseTempDir.toString(); when(runtimeOptions.getImportsBaseDir()).thenReturn(baseDir); Path p1 = Paths.get(baseDir, "model1" + RuntimeOptions.DASHBOARD_EXTENSION); Path p2 = Paths.get(baseDir, "model2" + RuntimeOptions.DASHBOARD_EXTENSION); Path p3 = Paths.get(baseDir, "ignored.bkp"); Path p4 = Paths.get(baseDir, "intermediary", "ignored.bkp"); p4.toFile().getParentFile().mkdirs(); for (Path p : Arrays.asList(p1, p2, p3, p4)) { p.toFile().createNewFile(); } runtimeModelLoader.loadAvailableModels(); verify(registry).registerFile(matches(p1.toString())); verify(registry).registerFile(matches(p2.toString())); verify(registry, times(0)).registerFile(matches(p3.toString())); verify(registry, times(0)).registerFile(matches(p4.toString())); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/helper/PartitionHelperTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.helper; import org.junit.Test; import static org.junit.Assert.assertEquals; public class PartitionHelperTest { @Test public void testPartition() { String id = PartitionHelper.partition("model", "abc"); assertEquals("abc| RuntimeModel=model", id); } @Test public void testRemovePartition() { String id = PartitionHelper.removePartition("abc| RuntimeModel=model"); assertEquals("abc", id); } @Test public void testRemovePartitionWithoutSeparator() { String idWithoutSeparator = "abc"; String id = PartitionHelper.removePartition(idWithoutSeparator); assertEquals(idWithoutSeparator, id); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/navigation/RuntimeNavigationBuilderTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.navigation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.junit.Before; import org.junit.Test; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class RuntimeNavigationBuilderTest { private static final String ITEM = "item1"; private static final String GROUP = "group"; private static final String EMPTY_GROUP = "emptyGroup"; RuntimeNavigationBuilder runtimeNavigationBuilder; @Before public void init() { runtimeNavigationBuilder = new RuntimeNavigationBuilder(); } /** * Checks if groups are pruned correctly */ @Test public void groupPruneTest() { NavTreeBuilder builder = new NavTreeBuilder(); LayoutTemplate lt = new LayoutTemplate("lt1"); final String NOT_PRUNED_GROUP = "notemptygroup"; final String EMPTYCHILDGROUP = "emptychildgroup"; final String EMPTYONANONEMPTY = "empty_on_a_not_empty"; builder.group(EMPTY_GROUP, "empty", "", false); builder.group(EMPTYCHILDGROUP, "", "", false); builder.endGroup(); builder.endGroup(); builder.group(NOT_PRUNED_GROUP, "notemptygroup", "", false); builder.item(ITEM, ITEM, "", false, NavWorkbenchCtx.perspective(lt.getName())); builder.group(EMPTYONANONEMPTY, EMPTYONANONEMPTY, "", false); builder.endGroup(); builder.endGroup(); List templates = new ArrayList<>(); templates.add(lt); NavTree originalTree = builder.build(); assertEquals(2, originalTree.getRootItems().size()); assertNotNull(originalTree.getItemById(EMPTYONANONEMPTY)); assertNotNull(originalTree.getItemById(EMPTY_GROUP)); assertNotNull(originalTree.getItemById(EMPTYCHILDGROUP)); NavTree runtimeTree = runtimeNavigationBuilder.buildRuntimeTree(originalTree, templates); assertNull(runtimeTree.getItemById(EMPTYONANONEMPTY)); assertNull(runtimeTree.getItemById(EMPTY_GROUP)); assertNull(runtimeTree.getItemById(EMPTYCHILDGROUP)); assertEquals(1, runtimeTree.getRootItems().size()); NavGroup notPrunedGroup = (NavGroup) runtimeTree.getItemById(NOT_PRUNED_GROUP); NavItem item = runtimeTree.getItemById(ITEM); assertNotNull(notPrunedGroup); assertNotNull(item); assertEquals(notPrunedGroup, item.getParent()); assertEquals(1, notPrunedGroup.getChildren().size()); } @Test public void removeItemWithoutTemplateTest() { NavTreeBuilder builder = new NavTreeBuilder(); LayoutTemplate lt = new LayoutTemplate("lt1"); final String ITEM_TO_REMOVE = "item2"; builder.group(GROUP, GROUP, "", false); builder.item(ITEM, ITEM, "", false, NavWorkbenchCtx.perspective(lt.getName())); builder.item(ITEM_TO_REMOVE, ITEM_TO_REMOVE, "", false); builder.endGroup(); NavTree originalTree = builder.build(); assertNotNull(originalTree.getItemById(ITEM_TO_REMOVE)); List templates = new ArrayList<>(); templates.add(lt); NavTree runtimeTree = runtimeNavigationBuilder.buildRuntimeTree(originalTree, templates); assertEquals(1, runtimeTree.getRootItems().size()); NavGroup group = (NavGroup) runtimeTree.getItemById(GROUP); assertNotNull(group); assertEquals(1, group.getChildren().size()); assertNull(runtimeTree.getItemById(ITEM_TO_REMOVE)); assertNotNull(runtimeTree.getItemById(ITEM)); } @Test public void groupForOrphanItemsTest() { final String ORPHAN_ITEM = "orphanitem"; NavTreeBuilder builder = new NavTreeBuilder(); LayoutTemplate lt = new LayoutTemplate("lt1"); LayoutTemplate lt2 = new LayoutTemplate(ORPHAN_ITEM); final String ITEM_TO_REMOVE = "item2"; builder.group(GROUP, GROUP, "", false); builder.item(ITEM, ITEM, "", false, NavWorkbenchCtx.perspective(lt.getName())); builder.item(ITEM_TO_REMOVE, ITEM_TO_REMOVE, "", false); builder.endGroup(); List templates = Arrays.asList(lt, lt2); NavTree originalTree = builder.build(); assertNull(originalTree.getItemById(RuntimeNavigationBuilder.ORPHAN_GROUP_ID)); assertEquals(1, originalTree.getRootItems().size()); NavTree runtimeTree = runtimeNavigationBuilder.buildRuntimeTree(originalTree, templates); assertEquals(2, runtimeTree.getRootItems().size()); NavGroup orphanItemsGroup = (NavGroup) runtimeTree.getItemById(RuntimeNavigationBuilder.ORPHAN_GROUP_ID); assertNotNull(orphanItemsGroup); assertEquals(1, orphanItemsGroup.getChildren().size()); NavItem orphanItem = runtimeTree.getItemById(ORPHAN_ITEM); String resourceId = NavWorkbenchCtx.get(orphanItem).getResourceId(); assertEquals(ORPHAN_ITEM, resourceId); assertEquals(orphanItemsGroup, orphanItem.getParent()); } @Test public void treeForEmptyNavigationTest() { LayoutTemplate lt1 = new LayoutTemplate("lt1"); LayoutTemplate lt2 = new LayoutTemplate("lt2"); LayoutTemplate lt3 = new LayoutTemplate("lt3"); List templates = Arrays.asList(lt1, lt2, lt3); NavTree runtimeTree = runtimeNavigationBuilder.build(Optional.empty(), templates); NavGroup orphanItemsGroup = (NavGroup) runtimeTree.getItemById(RuntimeNavigationBuilder.ORPHAN_GROUP_ID); assertNotNull(orphanItemsGroup); assertEquals(3, orphanItemsGroup.getChildren().size()); assertTrue(containsLayoutTemplate(orphanItemsGroup, lt1)); assertTrue(containsLayoutTemplate(orphanItemsGroup, lt2)); assertTrue(containsLayoutTemplate(orphanItemsGroup, lt3)); } private boolean containsLayoutTemplate(NavGroup group, LayoutTemplate lt) { return group.getChildren().stream() .anyMatch(lt1 -> lt1.getName().equals(lt.getName())); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/services/impl/ImportValidationServiceImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class ImportValidationServiceImplTest { ImportValidationServiceImpl importValidationService; @Before public void init() { importValidationService = new ImportValidationServiceImpl(); } @Test public void validFileTest() { String file = this.getClass().getResource("/valid_import.zip").getFile(); assertTrue(importValidationService.validate(file)); } @Test public void invalidFileTest() { String file = this.getClass().getResource("/not_valid.zip").getFile(); assertFalse(importValidationService.validate(file)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/services/impl/RuntimeInfoServiceImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.util.Arrays; import java.util.HashSet; import java.util.Optional; import org.dashbuilder.shared.model.DashboardInfo; import org.dashbuilder.shared.model.DashbuilderRuntimeInfo; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.dashbuilder.shared.model.DashbuilderRuntimeMode.MULTIPLE_IMPORT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class RuntimeInfoServiceImplTest { final static String RUNTIME_MODEL_ID = "ID"; final static String NOT_FOUND_ID = "NOT FOUND"; final static String LT_NAME = "LAYOUT TEMPLATE"; @Mock RuntimeModel runtimeModel; @Mock RuntimeModelRegistry registry; @InjectMocks RuntimeInfoServiceImpl runtimeInfoService; @Before public void init() { LayoutTemplate lt = new LayoutTemplate(LT_NAME); when(runtimeModel.getLayoutTemplates()).thenReturn(Arrays.asList(lt)); when(registry.getMode()).thenReturn(MULTIPLE_IMPORT); when(registry.get(RUNTIME_MODEL_ID)).thenReturn(Optional.of(runtimeModel)); when(registry.get(NOT_FOUND_ID)).thenReturn(Optional.empty()); when(registry.availableModels()).thenReturn(new HashSet<>(Arrays.asList(RUNTIME_MODEL_ID))); } @Test public void testInfo() { DashbuilderRuntimeInfo info = runtimeInfoService.info(); assertEquals(1, info.getAvailableModels().size()); assertTrue(info.getAvailableModels().contains(RUNTIME_MODEL_ID)); assertEquals(MULTIPLE_IMPORT.name(), info.getMode()); assertFalse(info.isAcceptingNewImports()); } @Test public void testDashboardInfoWithFoundModel() { Optional dashboardInfoOp = runtimeInfoService.dashboardInfo(RUNTIME_MODEL_ID); DashboardInfo dashboardInfo = dashboardInfoOp.get(); assertEquals(1, dashboardInfo.getPages().size()); assertTrue(dashboardInfo.getPages().contains(LT_NAME)); assertEquals(RUNTIME_MODEL_ID, dashboardInfo.getRuntimeModelId()); } @Test public void testDashboardInfoWithNotFoundModel() { Optional dashboardInfoOp = runtimeInfoService.dashboardInfo(NOT_FOUND_ID); assertFalse(dashboardInfoOp.isPresent()); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/services/impl/RuntimeModelParserImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Collectors; import javax.enterprise.event.Event; import org.dashbuilder.backend.RuntimeOptions; import org.dashbuilder.backend.helper.PartitionHelper; import org.dashbuilder.backend.navigation.RuntimeNavigationBuilder; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.external.service.ComponentLoader; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.shared.event.NewDataSetContentEvent; import org.dashbuilder.shared.model.DataSetContent; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.RuntimeModelRegistry; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.dashbuilder.shared.model.DataSetContentType.CSV; import static org.dashbuilder.shared.model.DataSetContentType.DEFINITION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class RuntimeModelParserImplTest { @Mock Event newDataSetContentEventSource; @Mock RuntimeNavigationBuilder navigationBuilder; @Mock RuntimeOptions runtimeOptions; @Mock RuntimeModelRegistry runtimeModelRegistry; @Mock ComponentLoader externalComponentLoader; @InjectMocks RuntimeModelParserImpl parser; @Test public void testEmptyImport() throws IOException { when(navigationBuilder.build(any(), any())).thenReturn(new NavTreeBuilder().build()); InputStream emptyImport = this.getClass().getResourceAsStream("/empty.zip"); RuntimeModel runtimeModel = parser.retrieveRuntimeModel("", emptyImport); verify(newDataSetContentEventSource, times(0)).fire(any()); assertTrue(runtimeModel.getLayoutTemplates().isEmpty()); assertTrue(runtimeModel.getNavTree().getRootItems().isEmpty()); } @Test @SuppressWarnings("unchecked") public void testValidImport() throws IOException { parser.init(); InputStream validImport = this.getClass().getResourceAsStream("/valid_import.zip"); RuntimeModel runtimeModel = parser.parse("", validImport); @SuppressWarnings("rawtypes") ArgumentCaptor navigationContent = ArgumentCaptor.forClass(Optional.class); verify(navigationBuilder).build(navigationContent.capture(), any()); assertEquals("{}", navigationContent.getValue().get()); List layoutTemplates = runtimeModel.getLayoutTemplates(); assertEquals(1, layoutTemplates.size()); LayoutTemplate layoutTemplate = layoutTemplates.get(0); assertEquals("life_expectancy", layoutTemplate.getName()); assertEquals(3, layoutTemplate.getVersion()); ArgumentCaptor datasetContents = ArgumentCaptor.forClass(NewDataSetContentEvent.class); verify(newDataSetContentEventSource).fire(datasetContents.capture()); NewDataSetContentEvent newDataSetContentEvent = datasetContents.getValue(); assertEquals(2, newDataSetContentEvent.getContent().size()); List datasets = newDataSetContentEvent.getContent(); assertEquals(2, datasets.size()); assertEquals("e26a81a1-5636-493c-96e0-51bc32322b17", datasets.get(0).getId()); assertEquals("e26a81a1-5636-493c-96e0-51bc32322b17", datasets.get(1).getId()); Predicate csvMatcher = ds -> ds.getContentType().equals(CSV); Predicate defMatcher = ds -> ds.getContentType().equals(DEFINITION); assertTrue(datasets.stream().anyMatch(csvMatcher)); assertTrue(datasets.stream().anyMatch(defMatcher)); String dsContent = datasets.stream().filter(defMatcher).findAny().get().getContent(); String csvContent = datasets.stream().filter(csvMatcher).findAny().get().getContent(); assertEquals(getFileContent("/ds.dset"), dsContent); assertEquals(getFileContent("/ds.csv"), csvContent); } @Test public void testTransformedUuid() { when(runtimeOptions.isMultipleImport()).thenReturn(true); when(runtimeOptions.isDatasetPartition()).thenReturn(true); final String runtimeModelId = "123"; final String transformedId = PartitionHelper.partition(runtimeModelId, "e26a81a1-5636-493c-96e0-51bc32322b17"); parser.init(); InputStream validImport = this.getClass().getResourceAsStream("/valid_import.zip"); RuntimeModel runtimeModel = parser.parse(runtimeModelId, validImport); List layoutTemplates = runtimeModel.getLayoutTemplates(); // check if ID in the layout template component was transformed LayoutTemplate layoutTemplate = layoutTemplates.get(0); String json = layoutTemplate.getRows().get(1).getLayoutColumns().get(0).getLayoutComponents().get(0).getProperties().get("json"); String loadedUUID = DisplayerSettingsJSONMarshaller.get().fromJsonString(json).getDataSetLookup().getDataSetUUID(); assertEquals(transformedId, loadedUUID); // check if dataset ID was changed ArgumentCaptor datasetContents = ArgumentCaptor.forClass(NewDataSetContentEvent.class); verify(newDataSetContentEventSource).fire(datasetContents.capture()); NewDataSetContentEvent newDataSetContentEvent = datasetContents.getValue(); List datasets = newDataSetContentEvent.getContent(); assertEquals(transformedId, datasets.get(0).getId()); assertEquals(transformedId, datasets.get(1).getId()); } @Test public void testUnzipComponentFile() throws IOException, URISyntaxException { Path componentPath = Paths.get(this.getClass().getResource("/").toURI()); when(externalComponentLoader.getExternalComponentsDir()).thenReturn(componentPath.toString()); String componentFileContent1 = "This is a component file."; String fileName = "component1/someFile.txt"; InputStream zis = new ByteArrayInputStream(componentFileContent1.getBytes()); parser.extractComponentFile("test", zis, fileName); Path componentFilePath = componentPath.resolve(fileName); assertTrue(Files.exists(componentFilePath)); assertEquals(componentFileContent1, Files.readAllLines(componentFilePath).get(0)); Files.delete(componentFilePath); } @Test public void testUnzipComponentFileWithPartition() throws IOException, URISyntaxException { Path componentPath = Paths.get(this.getClass().getResource("/").toURI()); when(externalComponentLoader.getExternalComponentsDir()).thenReturn(componentPath.toString()); when(runtimeOptions.isComponentPartition()).thenReturn(true); when(runtimeOptions.isMultipleImport()).thenReturn(true); String modelId = "testModel"; String componentFileContent1 = "This is a component file."; String fileName = "component1/someFile.txt"; InputStream zis = new ByteArrayInputStream(componentFileContent1.getBytes()); parser.extractComponentFile(modelId, zis, fileName); Path componentFilePath = Paths.get(componentPath.toString(), modelId, fileName); assertTrue(Files.exists(componentFilePath)); assertEquals(componentFileContent1, Files.readAllLines(componentFilePath).get(0)); Files.delete(componentFilePath); } private String getFileContent(String resource) throws IOException { Path csvActualPath = Paths.get(this.getClass() .getResource(resource) .getFile()); return Files.readAllLines(csvActualPath) .stream() .collect(Collectors.joining(System.lineSeparator())); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/backend/services/impl/RuntimeModelRegistryImplTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.services.impl; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.enterprise.event.Event; import org.dashbuilder.backend.RuntimeOptions; import org.dashbuilder.shared.event.RemovedRuntimeModelEvent; import org.dashbuilder.shared.model.DashbuilderRuntimeMode; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.ImportValidationService; import org.dashbuilder.shared.service.RuntimeModelParser; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.apache.commons.io.FilenameUtils; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalMatchers.or; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class RuntimeModelRegistryImplTest { @Mock ImportValidationService importValidationService; @Mock Map runtimeModels; @Mock RuntimeModelParser parser; @Mock RuntimeOptions options; @Mock Event removedRuntimeModelEvent; @InjectMocks RuntimeModelRegistryImpl registry; private Path tempFile; private Path tempFile2; @Before public void init() throws IOException { tempFile = Files.createTempFile("test", RuntimeOptions.DASHBOARD_EXTENSION); tempFile2 = Files.createTempFile("test", RuntimeOptions.DASHBOARD_EXTENSION); registry.setRemovedRuntimeModelEvent(removedRuntimeModelEvent); } @After public void cleanup() throws IOException { Files.deleteIfExists(tempFile); Files.deleteIfExists(tempFile2); } @Test(expected = IllegalArgumentException.class) public void testRegisterFileEmpty() { registry.registerFile(""); } @Test(expected = IllegalArgumentException.class) public void testRegisterFileNull() { registry.registerFile(null); } @Test(expected = IllegalArgumentException.class) public void testRegisterFileNotExist() { registry.registerFile("file"); } @Test(expected = IllegalArgumentException.class) public void testRegisterFileInvalid() throws IOException { String file = tempFile.toString(); when(importValidationService.validate(file)).thenReturn(false); registry.registerFile(file); } @Test(expected = IllegalArgumentException.class) public void testRegisterFileNotAcceptingImports() throws IOException { String file = tempFile.toString(); when(importValidationService.validate(file)).thenReturn(true); // to make sure that it is not accepting new imports registry.setMode(DashbuilderRuntimeMode.STATIC); registry.registerFile(file); } @Test(expected = IllegalArgumentException.class) public void testRegisterFileParsingError() throws IOException { String file = tempFile.toString(); String importId = FilenameUtils.getBaseName(tempFile.toFile().getPath()); when(runtimeModels.isEmpty()).thenReturn(true); when(importValidationService.validate(file)).thenReturn(true); when(parser.parse(eq(importId), any())).thenThrow(new RuntimeException()); registry.registerFile(file); } @Test public void testRegisterFileSuccess() throws IOException { String file = tempFile.toString(); String importId = FilenameUtils.getBaseName(tempFile.toFile().getPath()); RuntimeModel runtimeModel = mock(RuntimeModel.class); when(runtimeModels.isEmpty()).thenReturn(true); when(importValidationService.validate(file)).thenReturn(true); when(parser.parse(eq(importId), any())).thenReturn(runtimeModel); registry.registerFile(file); verify(runtimeModels).put(eq(importId), eq(runtimeModel)); } @Test public void testRegisterFileSuccessMultiMode() throws IOException { String file1 = tempFile.toString(); String file2 = tempFile2.toString(); String importId1 = FilenameUtils.getBaseName(tempFile.toFile().getPath()); String importId2 = FilenameUtils.getBaseName(tempFile2.toFile().getPath()); RuntimeModel runtimeModel1 = mock(RuntimeModel.class); RuntimeModel runtimeModel2 = mock(RuntimeModel.class); when(importValidationService.validate(or(eq(file1), eq(file2)))).thenReturn(true); when(parser.parse(eq(importId1), any())).thenReturn(runtimeModel1); when(parser.parse(eq(importId2), any())).thenReturn(runtimeModel2); registry.setMode(DashbuilderRuntimeMode.MULTIPLE_IMPORT); registry.registerFile(file1); verify(runtimeModels).put(eq(importId1), eq(runtimeModel1)); registry.registerFile(file2); verify(runtimeModels).put(eq(importId2), eq(runtimeModel2)); } @Test public void testSingle() { RuntimeModel model1 = mock(RuntimeModel.class); when(runtimeModels.values()).thenReturn(Collections.singleton(model1)); assertEquals(model1, registry.single().get()); } @Test public void testGetInMultipleMode() { registry.setMode(DashbuilderRuntimeMode.MULTIPLE_IMPORT); String id = "ID"; registry.get(id); verify(runtimeModels).get(eq(id)); } @Test public void testGetWithSingleMode() { registry.setMode(DashbuilderRuntimeMode.SINGLE_IMPORT); String id = "ID"; RuntimeModel model1 = mock(RuntimeModel.class); when(runtimeModels.values()).thenReturn(Collections.singleton(model1)); assertEquals(model1, registry.single().get()); verify(runtimeModels, Mockito.times(0)).get(eq(id)); verify(runtimeModels).values(); } @Test public void testRemoveExistingModel() throws IOException { String file = tempFile.toString(); String importId = FilenameUtils.getBaseName(tempFile.toFile().getPath()); RuntimeModel runtimeModel = mock(RuntimeModel.class); when(options.buildFilePath(eq(importId))).thenReturn(tempFile.toFile().getPath()); when(runtimeModels.remove(eq(importId))).thenReturn(runtimeModel); when(options.isRemoveModelFile()).thenReturn(true); registry.remove(importId); verify(runtimeModels).remove(eq(importId)); verify(removedRuntimeModelEvent).fire(any()); assertFalse(Files.exists(Paths.get(file))); } @Test public void testRemoveWithoutDeletingFile() throws IOException { String file = tempFile.toString(); String importId = FilenameUtils.getBaseName(tempFile.toFile().getPath()); RuntimeModel runtimeModel = mock(RuntimeModel.class); when(runtimeModels.remove(eq(importId))).thenReturn(runtimeModel); when(options.isRemoveModelFile()).thenReturn(false); registry.remove(importId); verify(runtimeModels).remove(eq(importId)); verify(removedRuntimeModelEvent).fire(any()); assertTrue(Files.exists(Paths.get(file))); } @Test public void testRemoveNotExistingModel() throws IOException { String file = tempFile.toString(); String importId = FilenameUtils.getBaseName(tempFile.toFile().getPath()); registry.remove(importId); verify(runtimeModels).remove(eq(importId)); verify(removedRuntimeModelEvent, times(0)).fire(any()); assertTrue(Files.exists(Paths.get(file))); } @Test public void testClear() throws IOException { String importId1 = FilenameUtils.getBaseName(tempFile.toFile().getPath()); String importId2 = FilenameUtils.getBaseName(tempFile2.toFile().getPath()); when(options.buildFilePath(eq(importId1))).thenReturn(tempFile.toFile().getPath()); when(options.buildFilePath(eq(importId2))).thenReturn(tempFile2.toFile().getPath()); when(options.isRemoveModelFile()).thenReturn(true); Set keys = new HashSet<>(); keys.add(importId1); keys.add(importId2); when(runtimeModels.keySet()).thenReturn(keys); when(runtimeModels.remove(importId1)).thenReturn(mock(RuntimeModel.class)); when(runtimeModels.remove(importId2)).thenReturn(mock(RuntimeModel.class)); registry.clear(); verify(removedRuntimeModelEvent, times(2)).fire(any()); verify(runtimeModels).clear(); assertFalse(Files.exists(Paths.get(tempFile.toString()))); assertFalse(Files.exists(Paths.get(tempFile2.toString()))); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/client/ClientRuntimeModelLoaderTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.perspective.generator.RuntimePerspectiveGenerator; import org.dashbuilder.client.plugins.RuntimePerspectivePluginManager; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.service.RuntimeModelService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.widgets.common.client.common.BusyIndicatorView; import org.uberfire.mocks.CallerMock; import org.uberfire.mvp.Command; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class ClientRuntimeModelLoaderTest { CallerMock importModelServiceCaller; @Mock RuntimeModelService runtimeModelService; @Mock RuntimePerspectiveGenerator runtimePerspectiveGenerator; @Mock RuntimePerspectivePluginManager runtimePerspectivePluginManager; @Mock NavigationManager navigationManager; @Mock BusyIndicatorView loading; RuntimeClientLoader clientRuntimeModelLoader; @Before public void setup() { importModelServiceCaller = new CallerMock<>(runtimeModelService); clientRuntimeModelLoader = new RuntimeClientLoader(importModelServiceCaller, runtimePerspectiveGenerator, runtimePerspectivePluginManager, navigationManager, loading); } @Test @SuppressWarnings("unchecked") public void testLoadModelSuccess() { String modelId = "abc"; LayoutTemplate perspective = mock(LayoutTemplate.class); List perspectives = Arrays.asList(perspective); NavTree navTree = mock(NavTree.class); RuntimeModel runtimeModel = new RuntimeModel(navTree, perspectives, System.currentTimeMillis()); when(runtimeModelService.getRuntimeModel(eq(modelId))).thenReturn(Optional.of(runtimeModel)); Consumer runtimeModelConsumer = mock(Consumer.class); Command empty = mock(Command.class); BiConsumer error = mock(BiConsumer.class); clientRuntimeModelLoader.loadModel(modelId, runtimeModelConsumer, empty, error); verify(runtimeModelConsumer).accept(runtimeModel); verify(runtimePerspectiveGenerator).generatePerspective(eq(perspective)); verify(runtimePerspectivePluginManager).setTemplates(eq(perspectives)); verify(navigationManager).setDefaultNavTree(navTree); verify(empty, times(0)).execute(); verify(error, times(0)).accept(any(), any()); } @Test @SuppressWarnings("unchecked") public void testLoadModelNotFound() { when(runtimeModelService.getRuntimeModel(any())).thenReturn(Optional.empty()); Consumer runtimeModelConsumer = mock(Consumer.class); Command empty = mock(Command.class); BiConsumer error = mock(BiConsumer.class); clientRuntimeModelLoader.loadModel("", runtimeModelConsumer, empty, error); verify(runtimeModelConsumer, times(0)).accept(any()); verify(empty, times(1)).execute(); verify(error, times(0)).accept(any(), any()); } @Test @SuppressWarnings("unchecked") public void testLoadModelError() { when(runtimeModelService.getRuntimeModel(any())).thenThrow(new RuntimeException()); Consumer runtimeModelConsumer = mock(Consumer.class); Command empty = mock(Command.class); BiConsumer error = mock(BiConsumer.class); clientRuntimeModelLoader.loadModel("", runtimeModelConsumer, empty, error); verify(runtimeModelConsumer, times(0)).accept(any()); verify(empty, times(0)).execute(); verify(error, times(1)).accept(any(), any()); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/client/error/DefaultRuntimeErrorCallbackTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.error; import org.junit.Test; import static org.dashbuilder.client.error.DefaultRuntimeErrorCallback.PARSING_JSON_MSG; import static org.dashbuilder.client.error.DefaultRuntimeErrorCallback.SCRIPT_ERROR_MSG; import static org.dashbuilder.client.error.DefaultRuntimeErrorCallback.extractMessageRecursively; import static org.dashbuilder.client.error.DefaultRuntimeErrorCallback.PARSING_JSON_SYNTAX_MSG; import static org.dashbuilder.client.error.DefaultRuntimeErrorCallback.isServerOfflineException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class DefaultRuntimeErrorCallbackTest { @Test public void testIsServerOfflineException() { assertTrue(isServerOfflineException(new Exception(PARSING_JSON_SYNTAX_MSG))); assertTrue(isServerOfflineException(new Exception(PARSING_JSON_MSG))); assertTrue(isServerOfflineException(new Exception(SCRIPT_ERROR_MSG))); assertFalse(isServerOfflineException(new Exception())); assertFalse(isServerOfflineException(new Exception("any message"))); } @Test public void testExtractMessageRecursively() { Exception cause = new Exception("CAUSE"); Exception intermediary = new Exception("INTERMEDIARY", cause); Exception e = new Exception("FIRST", intermediary); String message = DefaultRuntimeErrorCallback.extractMessageRecursively(e); assertEquals("FIRST Caused by: INTERMEDIARY Caused by: CAUSE", message); String MESSAGE = "Message"; message = extractMessageRecursively(new Exception(MESSAGE)); assertEquals(MESSAGE, message); assertEquals("", extractMessageRecursively(null)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/client/screens/RouterScreenTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.client.navbar.AppNavBar; import org.dashbuilder.client.perspective.DashboardsListPerspective; import org.dashbuilder.client.perspective.EmptyPerspective; import org.dashbuilder.client.perspective.RuntimePerspective; import org.dashbuilder.shared.model.DashbuilderRuntimeMode; import org.dashbuilder.shared.model.RuntimeModel; import org.dashbuilder.shared.model.RuntimeServiceResponse; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.uberfire.client.mvp.PlaceManager; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class RouterScreenTest { @Mock PlaceManager placeManager; @Mock AppNavBar appNavBar; @Mock RuntimeScreen runtimeScreen; @Mock DashboardsListScreen dashboardsListScreen; @InjectMocks RouterScreen routerScreen; @Test public void testRouteToRuntimePerspective() { RuntimeModel runtimeModel = mock(RuntimeModel.class); RuntimeServiceResponse response = new RuntimeServiceResponse(DashbuilderRuntimeMode.SINGLE_IMPORT, Optional.of(runtimeModel), Collections.emptyList()); routerScreen.route(response); verify(runtimeScreen).loadDashboards(eq(runtimeModel)); verify(placeManager).goTo(eq(RuntimePerspective.ID)); } @Test public void testRouteToEmptyPerspective() { RuntimeServiceResponse response = new RuntimeServiceResponse(DashbuilderRuntimeMode.SINGLE_IMPORT, Optional.empty(), Collections.emptyList()); routerScreen.route(response); verify(placeManager).goTo(eq(EmptyPerspective.ID)); } @Test public void testRouteToDashboardsListPerspective() { List models = Arrays.asList("m1", "m2"); RuntimeServiceResponse response = new RuntimeServiceResponse(DashbuilderRuntimeMode.MULTIPLE_IMPORT, Optional.empty(), models); routerScreen.route(response); verify(dashboardsListScreen).loadList(eq(models)); verify(placeManager).goTo(eq(DashboardsListPerspective.ID)); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/client/screens/RuntimeScreenTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import java.util.Arrays; import java.util.List; import com.google.gwtmockito.GwtMockitoTestRunner; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class RuntimeScreenTest { @Mock PlaceManager placeManager; @InjectMocks RuntimeScreen runtimeScreen; @Test public void testGoToIndexWithIndexPage() { String randomPage = "randomPage"; List templates = Arrays.asList(new LayoutTemplate(randomPage), new LayoutTemplate(RuntimeScreen.INDEX_PAGE_NAME)); runtimeScreen.goToIndex(templates); verify(placeManager).goTo(RuntimeScreen.INDEX_PAGE_NAME); verify(placeManager, times(0)).goTo(randomPage); } @Test public void testGoToIndexWithSinglePage() { String randomPage = "randomPage"; List templates = Arrays.asList(new LayoutTemplate(randomPage)); runtimeScreen.goToIndex(templates); verify(placeManager).goTo(randomPage); } @Test public void testGoToIndexWithoutIndex() { List templates = Arrays.asList(new LayoutTemplate("page1"), new LayoutTemplate("page2")); runtimeScreen.goToIndex(templates); verify(placeManager, times(0)).goTo(anyString()); } @Test public void testGoToIndexWithHistoryAndKeepIndex() { List templates = Arrays.asList(new LayoutTemplate("page1"), new LayoutTemplate("page2")); runtimeScreen.keepHistory = true; runtimeScreen.lastVisited = "page1"; runtimeScreen.goToIndex(templates); verify(placeManager).goTo("page1"); } @Test public void testGoToIndexWithoutHistory() { List templates = Arrays.asList(new LayoutTemplate("page1"), new LayoutTemplate("page2")); runtimeScreen.keepHistory = false; runtimeScreen.lastVisited = "page1"; runtimeScreen.goToIndex(templates); verify(placeManager, times(0)).goTo(anyString()); } @Test public void testGoToIndexWithDeletedPage() { List templates = Arrays.asList(new LayoutTemplate("page1"), new LayoutTemplate("page2")); runtimeScreen.keepHistory = true; runtimeScreen.lastVisited = "deleted"; runtimeScreen.goToIndex(templates); verify(placeManager, times(0)).goTo(anyString()); } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/java/org/dashbuilder/shared/service/RuntimeModelRegistryTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.service; import java.util.Collection; import java.util.Optional; import org.dashbuilder.shared.model.DashbuilderRuntimeMode; import org.dashbuilder.shared.model.RuntimeModel; import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class RuntimeModelRegistryTest { @Test public void testAcceptingNewImportsMultiple() { RuntimeModelRegistry registry = new RuntimeModelRegistryMock(DashbuilderRuntimeMode.MULTIPLE_IMPORT, false); assertTrue(registry.acceptingNewImports()); } @Test public void testNotAcceptingNewImportsStatic() { RuntimeModelRegistry registry = new RuntimeModelRegistryMock(DashbuilderRuntimeMode.STATIC, false); assertFalse(registry.acceptingNewImports()); } @Test public void testNotAcceptingNewImportsSingleAndNotEmpty() { RuntimeModelRegistry registry = new RuntimeModelRegistryMock(DashbuilderRuntimeMode.SINGLE_IMPORT, false); assertFalse(registry.acceptingNewImports()); } @Test public void testNotAcceptingNewImportsSingleAndEmpty() { RuntimeModelRegistry registry = new RuntimeModelRegistryMock(DashbuilderRuntimeMode.SINGLE_IMPORT, true); assertTrue(registry.acceptingNewImports()); } // Having classloading issues with Mockito, hence having to create this public class RuntimeModelRegistryMock implements RuntimeModelRegistry { private DashbuilderRuntimeMode mode; public RuntimeModelRegistryMock(DashbuilderRuntimeMode mode, boolean b) { super(); this.mode = mode; this.b = b; } private boolean b; @Override public Optional single() { return null; } @Override public boolean isEmpty() { return b; } @Override public DashbuilderRuntimeMode getMode() { return mode; } @Override public Optional get(String id) { return null; } @Override public void setMode(DashbuilderRuntimeMode mode) {} @Override public Optional registerFile(String filePath) { return null; } @Override public void remove(String runtimeModelid) { } @Override public Collection availableModels() { return null; } @Override public void clear() { } @Override public void unregister(String runtimeModelid) { } } } ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/resources/ds.csv ================================================ Country,Life Expectancy Macau,84.7 Japan,84.5 Singapore,83.8 Switzerland,83.6 Italy,83.4 Spain,83.4 Australia,83.3 Iceland,82.9 South Korea,82.8 Israel,82.8 Sweden,82.7 France,82.5 Malta,82.4 Canada,82.3 Norway,82.3 Luxembourg,82.1 Ireland,82.1 New Zealand,82.1 Netherlands,82.1 Greece,82.1 Portugal,81.9 Andorra,81.8 Finland,81.7 Belgium,81.5 Ascension Island,81.5 Austria,81.4 Germany,81.2 United Kingdom,81.2 Slovenia,81.2 Cyprus,80.8 Denmark,80.8 Liechtenstein,80.5 Costa Rica,80.1 Chile,80 Czech Republic,79.2 Barbados,79.1 Lebanon,78.9 United States of America,78.9 Cuba,78.6 Poland,78.5 Panama,78.3 Croatia,78.3 Turkey,78.3 United Arab Emirates,77.8 Uruguay,77.8 Oman,77.6 Slovakia,77.4 Bosnia and Herzegovina,77.3 Bahrain,77.2 Colombia,77.1 Antigua and Barbuda,76.9 Thailand,76.9 Ecuador,76.8 Montenegro,76.8 Sri Lanka,76.8 Algeria,76.7 China,76.7 Hungary,76.7 Argentina,76.5 Iran,76.5 Morocco,76.5 Peru,76.5 Tunisia,76.5 Saint Lucia,76.1 Malaysia,76.1 Romania,75.9 Serbia,75.8 Brazil,75.7 Brunei,75.7 Lithuania,75.7 North Macedonia,75.7 Kuwait,75.4 Latin America and the Caribbean,75.4 "East Asia, Southeast Asia and Oceania",75.3 Vietnam,75.3 Latvia,75.2 Honduras,75.1 Mexico,75 Saudi Arabia,75 Armenia,74.9 Bulgaria,74.9 Mauritius,74.9 Belarus,74.6 Saint Kitts and Nevis,74.6 Belize,74.5 Jamaica,74.4 Jordan,74.4 Nicaragua,74.3 Europe and Central Asia,74.2 Guatemala,74.1 Paraguay,74.1 Dominican Republic,73.9 Marshall Islands,73.9 Palestine,73.9 Bahamas,73.8 Palau,73.7 Georgia,73.6 Trinidad and Tobago,73.4 Seychelles,73.3 Kazakhstan,73.2 Samoa,73.2 El Salvador,73.1 Azerbaijan,72.9 Cabo Verde,72.8 Solomon Islands,72.8 Libya,72.7 World,72.6 Grenada,72.4 Russia,72.4 Saint Vincent and the Grenadines,72.4 Bangladesh,72.3 Venezuela,72.1 Ukraine,72 Arab States,71.9 Egypt,71.8 Moldova,71.8 Syria,71.8 Suriname,71.6 Uzbekistan,71.6 Bhutan,71.5 Indonesia,71.5 Kyrgyzstan,71.3 Bolivia,71.2 Philippines,71.1 Tajikistan,70.9 Tonga,70.8 Iraq,70.5 Nepal,70.5 Vanuatu,70.3 Sao Tome and Principe,70.2 Guyana,69.8 Mongolia,69.7 South Asia,69.7 Cambodia,69.6 India,69.4 Botswana,69.3 Timor Leste,69.3 Rwanda,68.7 Kiribati,68.1 Turkmenistan,68.1 Federated States of Micronesia,67.8 Senegal,67.7 Laos,67.6 Fiji,67.3 Pakistan,67.1 Myanmar,66.9 Madagascar,66.7 Djibouti,66.6 Ethiopia,66.2 Gabon,66.2 Yemen,66.1 Eritrea,65.9 Sudan,65.1 United Republic of Tanzania,65 Mauritania,64.7 Afghanistan,64.5 Republic of Congo,64.3 Papua New Guinea,64.3 Comoros,64.1 South Africa,63.9 Ghana,63.8 Malawi,63.8 Haiti,63.7 Liberia,63.7 Zambia,63.5 Namibia,63.4 Kenya,63.3 Uganda,63 Niger,62 Gambia,61.7 Benin,61.5 Burkina Faso,61.2 Burundi,61.2 Guinea,61.2 Sub-Saharan Africa,61.2 Zimbabwe,61.2 Angola,60.8 Togo,60.8 Democratic Republic of the Congo,60.4 Mozambique,60.2 Eswatini,59.4 Mali,58.9 Cameroon,58.9 Equatorial Guinea,58.4 Guinea-Bissau,58 South Sudan,57.6 Côte d'Ivoire,57.4 Nigeria,54.3 Sierra Leone,54.3 Chad,54 Lesotho,53.7 Central African Republic,52.8 ================================================ FILE: dashbuilder/dashbuilder-runtime/src/test/resources/ds.dset ================================================ { "uuid": "e26a81a1-5636-493c-96e0-51bc32322b17", "name": "uploaded_life_expectancy", "provider": "CSV", "isPublic": true, "cacheEnabled": false, "cacheMaxRows": 1000, "pushEnabled": false, "pushMaxSize": 1024, "refreshAlways": false, "filePath": "C:\\fakepath\\life_expectancy.csv", "separatorChar": ",", "quoteChar": "\"", "escapeChar": "\\", "datePattern": "MM-dd-yyyy HH:mm:ss", "numberPattern": "#,###.##", "allColumns": false, "columns": [ { "id": "Country", "type": "label" }, { "id": "Life Expectancy", "type": "number", "pattern": "#,###.##" } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-shared 7.75.0-SNAPSHOT dashbuilder-displayer-api jar Dashbuilder Displayer API Dashbuilder Displayer API shared between client and server. org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-json org.jboss.errai errai-common com.google.gwt.gwtmockito gwtmockito test ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/AreaChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for area charts * *
     *   DisplayerSettingsFactory.newAreaChartSettings()
     *   .title("By Product")
     *   .column("Product")
     *   .column("Total amount")
     * 
    */ public interface AreaChartSettingsBuilder extends XAxisChartSettingsBuilder { /** * Set this area chart's subtype to a simple area chart (i.e. normal non-stacked areas) * @return The DisplayerSettingsBuilder instance that is being used to configure an Area chart data displayer. */ T subType_Area(); /** * Set this area chart's subtype to a stacked area chart (i.e. stacked areas) * @return The DisplayerSettingsBuilder instance that is being used to configure an Area chart data displayer. */ T subType_StackedArea(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/BarChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for bar charts * *
     *   DisplayerSettingsFactory.newBarChartSettings()
     *   .title("By Product")
     *   .column("Product")
     *   .column("Total amount")
     *   .buildSettings()
     * 
    */ public interface BarChartSettingsBuilder extends XAxisChartSettingsBuilder { /** * @param b True if the bars of this bar chart are to be shown in 3D, false if they are to be shown flat. * @return The DisplayerSettingsBuilder instance that is being used to configure a Bar chart data displayer. */ T set3d(boolean b); /** * Set this bar chart's subtype to a simple bar chart (i.e. horizontal non-stacked bars) * @return The DisplayerSettingsBuilder instance that is being used to configure a Bar chart data displayer. */ T subType_Bar(); /** * Set this bar chart's subtype to a stacked bar chart (i.e. horizontal stacked bars) * @return The DisplayerSettingsBuilder instance that is being used to configure a Bar chart data displayer. */ T subType_StackedBar(); /** * Set this bar chart's subtype to a simple column chart (i.e. vertical non-stacked bars) * @return The DisplayerSettingsBuilder instance that is being used to configure a Bar chart data displayer. */ T subType_Column(); /** * Set this bar chart's subtype to a stacked column chart (i.e. vertical stacked bars) * @return The DisplayerSettingsBuilder instance that is being used to configure a Bar chart data displayer. */ T subType_StackedColumn(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/BubbleChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for bubble charts. * *
     *   DisplayerSettingsFactory.newBubbleChartSettings()
     *   .title("Opportunities distribution by Country ")
     *   .width(500).height(350)
     *   .margins(20, 50, 50, 0)
     *   .column(COUNTRY, "Country")
     *   .column("opps", "Number of opportunities")
     *   .column(PROBABILITY, "Average probability")
     *   .column(COUNTRY, "Country")
     *   .column(EXPECTED_AMOUNT, "Expected amount")
     *   .buildSettings());
     * 
    */ public interface BubbleChartSettingsBuilder extends XAxisChartSettingsBuilder { } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/ChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for the assembly of Chart based data displayer instances. */ public interface ChartSettingsBuilder extends DisplayerSettingsBuilder { /** * Sets the width of the chart. * @param width The width of the chart. * @return The DisplayerSettingsBuilder instance that is being used to configure a Chart data displayer. */ T width(int width); /** * Sets the height of the chart. * @param height The height of the chart. * @return The DisplayerSettingsBuilder instance that is being used to configure a Chart data displayer. */ T height(int height); /** * Set the margins for this chart. * @param top The top margin. * @param bottom The bottom margin. * @param left The left margin. * @param right The right margin. * @return The DisplayerSettingsBuilder instance that is being used to configure a Chart data displayer. */ T margins(int top, int bottom, int left, int right); /** * Hides off the char legend. * @return The DisplayerSettingsBuilder instance that is being used to configure a Chart data displayer. */ T legendOff(); /** * Turns on the char legend display. * @param position The display position. * @return The DisplayerSettingsBuilder instance that is being used to configure a Chart data displayer. */ T legendOn(String position); T legendOn(Position position); /** * Set the chart as resizable, it can change its size from the original one, defined by width and height attributes. * @param maxWidth The maximum width value. * @param maxHeight The maximum height value. * @return The DisplayerSettingsBuilder instance that is being used to configure a Chart data displayer. */ T resizableOn(int maxWidth, int maxHeight); /** * Set the chart as no resizable, it cannot change its size from the original one, defined by width and height attributes. * @return The DisplayerSettingsBuilder instance that is being used to configure a Chart data displayer. */ T resizableOff(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/ColumnSettings.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.GroupStrategy; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ColumnSettings { public static final String NUMBER_PATTERN = "#,##0.00"; public static final String EXPRESSION = "value"; public static final String DATE_PATTERN = "MMM dd, yyyy HH:mm"; public static final String DATE_YEAR = "yyyy"; public static final String DATE_MONTH = "MMM yyyy"; public static final String DATE_QUARTER = "MMM yyyy"; public static final String DATE_DAY = "dd MMM"; public static final String DATE_WEEK = "'Week' dd MMM"; public static final String DATE_HOUR = "HH'h'"; public static final String DATE_MINUTE = "mm'm'"; public static final String DATE_SECOND = "ss's'"; public static String getFixedExpression(DateIntervalType type) { if (DateIntervalType.SECOND.equals(type)) { return "value + \"\\\"\""; } if (DateIntervalType.MINUTE.equals(type)) { return "value + \"'\""; } if (DateIntervalType.HOUR.equals(type)) { return "value + \"h\""; } if (DateIntervalType.QUARTER.equals(type)) { return "\"Q\" + value"; } return "value"; } public static String getDatePattern(DateIntervalType type) { if (type.getIndex() <= DateIntervalType.SECOND.getIndex()) { return DATE_SECOND; } if (DateIntervalType.MINUTE.equals(type)) { return DATE_MINUTE; } if (DateIntervalType.HOUR.equals(type)) { return DATE_HOUR; } if (DateIntervalType.DAY.equals(type)) { return DATE_DAY; } if (DateIntervalType.WEEK.equals(type)) { return DATE_WEEK; } if (DateIntervalType.MONTH.equals(type)) { return DATE_MONTH; } if (DateIntervalType.QUARTER.equals(type)) { return DATE_QUARTER; } return DATE_YEAR; } public static ColumnSettings cloneWithDefaults(ColumnSettings columnSettings, DataColumn column) { ColumnSettings clone = columnSettings == null ? new ColumnSettings(column.getId()) : columnSettings.cloneInstance(); ColumnType columnType = column.getColumnType(); ColumnGroup columnGroup = column.getColumnGroup(); DateIntervalType intervalType = DateIntervalType.getByName(column.getIntervalType()); if (clone.columnName == null) { clone.columnName = column.getId(); } if (clone.emptyTemplate == null) { clone.emptyTemplate = "---"; } if (clone.valuePattern == null) { if (intervalType != null && columnGroup.getStrategy().equals(GroupStrategy.DYNAMIC)) { clone.valuePattern = getDatePattern(intervalType); } else if (ColumnType.DATE.equals(columnType)) { clone.valuePattern = DATE_PATTERN; } else if (ColumnType.NUMBER.equals(columnType)) { clone.valuePattern = NUMBER_PATTERN; } } if (clone.valueExpression == null) { if (intervalType != null && columnGroup.getStrategy().equals(GroupStrategy.FIXED)) { clone.valueExpression = getFixedExpression(intervalType); } else if (!ColumnType.DATE.equals(columnType)) { clone.valueExpression = EXPRESSION; } } return clone; } protected String columnId; protected String columnName; protected String valueExpression; protected String emptyTemplate; protected String valuePattern; public ColumnSettings() { } public ColumnSettings(String columnId) { this.columnId = columnId; } public String getColumnId() { return columnId; } public void setColumnId(String columnId) { this.columnId = columnId; } public String getColumnName() { return columnName; } public void setColumnName(String name) { this.columnName = name; } public String getValueExpression() { return valueExpression; } public void setValueExpression(String valueExpression) { this.valueExpression = valueExpression; } public String getValuePattern() { return valuePattern; } public void setValuePattern(String pattern) { this.valuePattern = pattern; } public String getEmptyTemplate() { return emptyTemplate; } public void setEmptyTemplate(String emptyTemplate) { this.emptyTemplate = emptyTemplate; } public String toString() { StringBuilder out = new StringBuilder(); if (columnId != null) out.append(columnId).append(" "); if (columnName != null) out.append(columnName).append(" "); if (valuePattern != null) out.append(valuePattern).append(" "); if (valueExpression != null) out.append(valueExpression).append(" "); if (emptyTemplate != null) out.append(emptyTemplate).append(" "); return out.toString(); } public ColumnSettings cloneInstance() { ColumnSettings other = new ColumnSettings(); other.columnId = columnId; other.columnName = columnName; other.valuePattern = valuePattern; other.valueExpression = valueExpression; other.emptyTemplate = emptyTemplate; return other; } public boolean equals(Object obj) { try { ColumnSettings other = (ColumnSettings) obj; if (other == null) { return false; } if (columnId != null && !columnId.equals(other.columnId)) { return false; } if (columnName != null && !columnName.equals(other.columnName)) { return false; } if (valuePattern != null && !valuePattern.equals(other.valuePattern)) { return false; } if (valueExpression != null && !valueExpression.equals(other.valueExpression)) { return false; } if (emptyTemplate != null && !emptyTemplate.equals(other.emptyTemplate)) { return false; } return true; } catch (ClassCastException e) { return false; } } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerAttributeDef.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; public class DisplayerAttributeDef { public static final DisplayerAttributeDef TYPE = new DisplayerAttributeDef("type"); public static final DisplayerAttributeDef SUBTYPE = new DisplayerAttributeDef("subtype"); public static final DisplayerAttributeDef RENDERER = new DisplayerAttributeDef("renderer"); public static final DisplayerAttributeDef COLUMN_EXPRESSION = new DisplayerAttributeDef("expression", DisplayerAttributeGroupDef.COLUMNS_GROUP); public static final DisplayerAttributeDef COLUMN_PATTERN = new DisplayerAttributeDef("pattern", DisplayerAttributeGroupDef.COLUMNS_GROUP); public static final DisplayerAttributeDef COLUMN_EMPTY = new DisplayerAttributeDef("empty", DisplayerAttributeGroupDef.COLUMNS_GROUP); public static final DisplayerAttributeDef TITLE = new DisplayerAttributeDef("title", DisplayerAttributeGroupDef.GENERAL_GROUP); public static final DisplayerAttributeDef TITLE_VISIBLE = new DisplayerAttributeDef("visible", DisplayerAttributeGroupDef.GENERAL_GROUP); /** * @deprecated Replaced by {@link #EXPORT_TO_CSV}. (Kept for backward compatibility) * @since 0.6 */ public static final DisplayerAttributeDef ALLOW_EXPORT_CSV = new DisplayerAttributeDef("allow_csv", DisplayerAttributeGroupDef.GENERAL_GROUP); /** * @deprecated Replaced by {@link #EXPORT_TO_XLS}. (Kept for backward compatibility) * @since 0.6 */ public static final DisplayerAttributeDef ALLOW_EXPORT_EXCEL = new DisplayerAttributeDef("allow_excel", DisplayerAttributeGroupDef.GENERAL_GROUP); public static final DisplayerAttributeDef EXPORT_TO_CSV = new DisplayerAttributeDef("export_csv", DisplayerAttributeGroupDef.EXPORT_GROUP); public static final DisplayerAttributeDef EXPORT_TO_XLS = new DisplayerAttributeDef("export_xls", DisplayerAttributeGroupDef.EXPORT_GROUP); public static final DisplayerAttributeDef REFRESH_STALE_DATA = new DisplayerAttributeDef("staleData", DisplayerAttributeGroupDef.REFRESH_GROUP); public static final DisplayerAttributeDef REFRESH_INTERVAL = new DisplayerAttributeDef("interval", DisplayerAttributeGroupDef.REFRESH_GROUP); public static final DisplayerAttributeDef FILTER_ENABLED = new DisplayerAttributeDef("enabled", DisplayerAttributeGroupDef.FILTER_GROUP); public static final DisplayerAttributeDef FILTER_SELFAPPLY_ENABLED = new DisplayerAttributeDef("selfapply", DisplayerAttributeGroupDef.FILTER_GROUP); public static final DisplayerAttributeDef FILTER_NOTIFICATION_ENABLED = new DisplayerAttributeDef("notification", DisplayerAttributeGroupDef.FILTER_GROUP); public static final DisplayerAttributeDef FILTER_LISTENING_ENABLED = new DisplayerAttributeDef("listening", DisplayerAttributeGroupDef.FILTER_GROUP); public static final DisplayerAttributeDef SELECTOR_WIDTH = new DisplayerAttributeDef("width", DisplayerAttributeGroupDef.SELECTOR_GROUP); public static final DisplayerAttributeDef SELECTOR_MULTIPLE = new DisplayerAttributeDef("multiple", DisplayerAttributeGroupDef.SELECTOR_GROUP); public static final DisplayerAttributeDef SELECTOR_SHOW_INPUTS = new DisplayerAttributeDef("inputs_show", DisplayerAttributeGroupDef.SELECTOR_GROUP); public static final DisplayerAttributeDef CHART_WIDTH = new DisplayerAttributeDef("width", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeDef CHART_HEIGHT = new DisplayerAttributeDef("height", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeDef CHART_RESIZABLE = new DisplayerAttributeDef("resizable", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeDef CHART_MAX_WIDTH = new DisplayerAttributeDef("maxWidth", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeDef CHART_MAX_HEIGHT = new DisplayerAttributeDef("maxHeight", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeDef CHART_BGCOLOR = new DisplayerAttributeDef("bgColor", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeDef CHART_3D = new DisplayerAttributeDef("3d", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeDef CHART_MARGIN_TOP = new DisplayerAttributeDef("top", DisplayerAttributeGroupDef.CHART_MARGIN_GROUP); public static final DisplayerAttributeDef CHART_MARGIN_BOTTOM = new DisplayerAttributeDef("bottom", DisplayerAttributeGroupDef.CHART_MARGIN_GROUP); public static final DisplayerAttributeDef CHART_MARGIN_LEFT = new DisplayerAttributeDef("left", DisplayerAttributeGroupDef.CHART_MARGIN_GROUP); public static final DisplayerAttributeDef CHART_MARGIN_RIGHT = new DisplayerAttributeDef("right", DisplayerAttributeGroupDef.CHART_MARGIN_GROUP); public static final DisplayerAttributeDef CHART_SHOWLEGEND = new DisplayerAttributeDef("show", DisplayerAttributeGroupDef.CHART_LEGEND_GROUP); public static final DisplayerAttributeDef CHART_LEGENDPOSITION = new DisplayerAttributeDef("position", DisplayerAttributeGroupDef.CHART_LEGEND_GROUP); public static final DisplayerAttributeDef TABLE_PAGESIZE = new DisplayerAttributeDef("pageSize", DisplayerAttributeGroupDef.TABLE_GROUP); public static final DisplayerAttributeDef TABLE_WIDTH = new DisplayerAttributeDef("width", DisplayerAttributeGroupDef.TABLE_GROUP); public static final DisplayerAttributeDef TABLE_SORTENABLED = new DisplayerAttributeDef("enabled", DisplayerAttributeGroupDef.TABLE_SORT_GROUP); public static final DisplayerAttributeDef TABLE_SORTCOLUMNID = new DisplayerAttributeDef("columnId", DisplayerAttributeGroupDef.TABLE_SORT_GROUP); public static final DisplayerAttributeDef TABLE_SORTORDER = new DisplayerAttributeDef("order", DisplayerAttributeGroupDef.TABLE_SORT_GROUP); public static final DisplayerAttributeDef TABLE_COLUMN_PICKER_ENABLED = new DisplayerAttributeDef("show_column_picker", DisplayerAttributeGroupDef.TABLE_GROUP); public static final DisplayerAttributeDef XAXIS_SHOWLABELS = new DisplayerAttributeDef("labels_show", DisplayerAttributeGroupDef.XAXIS_GROUP); public static final DisplayerAttributeDef XAXIS_TITLE = new DisplayerAttributeDef("title", DisplayerAttributeGroupDef.XAXIS_GROUP); public static final DisplayerAttributeDef XAXIS_LABELSANGLE = new DisplayerAttributeDef("labels_angle", DisplayerAttributeGroupDef.XAXIS_GROUP); public static final DisplayerAttributeDef YAXIS_SHOWLABELS = new DisplayerAttributeDef("labels_show", DisplayerAttributeGroupDef.YAXIS_GROUP); public static final DisplayerAttributeDef YAXIS_TITLE = new DisplayerAttributeDef("title", DisplayerAttributeGroupDef.YAXIS_GROUP); public static final DisplayerAttributeDef METER_START = new DisplayerAttributeDef("start", DisplayerAttributeGroupDef.METER_GROUP); public static final DisplayerAttributeDef METER_WARNING = new DisplayerAttributeDef("warning", DisplayerAttributeGroupDef.METER_GROUP); public static final DisplayerAttributeDef METER_CRITICAL = new DisplayerAttributeDef("critical", DisplayerAttributeGroupDef.METER_GROUP); public static final DisplayerAttributeDef METER_END = new DisplayerAttributeDef("end", DisplayerAttributeGroupDef.METER_GROUP); public static final DisplayerAttributeDef DONUT_HOLE_TITLE = new DisplayerAttributeDef("hole_title", DisplayerAttributeGroupDef.DONUT_GROUP); public static final DisplayerAttributeDef HTML_TEMPLATE = new DisplayerAttributeDef("html", DisplayerAttributeGroupDef.HTML_GROUP); public static final DisplayerAttributeDef JS_TEMPLATE = new DisplayerAttributeDef("javascript", DisplayerAttributeGroupDef.HTML_GROUP); public static final DisplayerAttributeDef MAP_COLOR_SCHEME = new DisplayerAttributeDef("color_scheme", DisplayerAttributeGroupDef.MAP_GROUP); public static final DisplayerAttributeDef EXTERNAL_COMPONENT_ID = new DisplayerAttributeDef("external_component_id"); public static final DisplayerAttributeDef EXTERNAL_COMPONENT_PARTITION = new DisplayerAttributeDef("external_component_partition"); protected String id; protected DisplayerAttributeGroupDef parent; public DisplayerAttributeDef() { } public DisplayerAttributeDef( String id ) { this( id, null ); } public DisplayerAttributeDef( String id, DisplayerAttributeGroupDef parent ) { this.id = id; if (parent != null) { parent.addChild(this); } } public String getFullId() { return parent != null ? parent.getFullId() + "." + id : id; } public DisplayerAttributeDef getParent() { return parent; } public void setParent(DisplayerAttributeGroupDef parent) { this.parent = parent; } @Override public boolean equals( Object obj ) { if ( obj == null ) { return false; } if ( !( obj.getClass().getName().equalsIgnoreCase(this.getClass().getName()) ) ) { return false; } DisplayerAttributeDef that = (DisplayerAttributeDef) obj; return that.getFullId().equalsIgnoreCase( this.getFullId() ); } @Override public int hashCode() { int result = 23; result = 31 * result + getFullId().hashCode(); return result; } @Override public String toString() { return getFullId(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerAttributeGroupDef.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import java.util.HashSet; import java.util.Set; public class DisplayerAttributeGroupDef extends DisplayerAttributeDef { // ROOT-GROUPS public static final DisplayerAttributeGroupDef GENERAL_GROUP = new DisplayerAttributeGroupDef( "general" ); public static final DisplayerAttributeGroupDef COLUMNS_GROUP = new DisplayerAttributeGroupDef( "columns" ); public static final DisplayerAttributeGroupDef REFRESH_GROUP = new DisplayerAttributeGroupDef( "refresh" ); public static final DisplayerAttributeGroupDef FILTER_GROUP = new DisplayerAttributeGroupDef( "filter" ); public static final DisplayerAttributeGroupDef SELECTOR_GROUP = new DisplayerAttributeGroupDef( "selector" ); public static final DisplayerAttributeGroupDef CHART_GROUP = new DisplayerAttributeGroupDef( "chart" ); public static final DisplayerAttributeGroupDef TABLE_GROUP = new DisplayerAttributeGroupDef( "table" ); public static final DisplayerAttributeGroupDef AXIS_GROUP = new DisplayerAttributeGroupDef( "axis" ); public static final DisplayerAttributeGroupDef METER_GROUP = new DisplayerAttributeGroupDef( "meter" ); public static final DisplayerAttributeGroupDef DONUT_GROUP = new DisplayerAttributeGroupDef( "donut" ); public static final DisplayerAttributeGroupDef HTML_GROUP = new DisplayerAttributeGroupDef( "html" ); public static final DisplayerAttributeGroupDef EXPORT_GROUP = new DisplayerAttributeGroupDef( "export" ); public static final DisplayerAttributeGroupDef MAP_GROUP = new DisplayerAttributeGroupDef( "map" ); // SUBGROUPS public static final DisplayerAttributeGroupDef CHART_MARGIN_GROUP = new DisplayerAttributeGroupDef( "margin", DisplayerAttributeGroupDef.CHART_GROUP); public static final DisplayerAttributeGroupDef CHART_LEGEND_GROUP = new DisplayerAttributeGroupDef( "legend", DisplayerAttributeGroupDef.CHART_GROUP ); public static final DisplayerAttributeGroupDef TABLE_SORT_GROUP = new DisplayerAttributeGroupDef( "sort", DisplayerAttributeGroupDef.TABLE_GROUP ); public static final DisplayerAttributeGroupDef XAXIS_GROUP = new DisplayerAttributeGroupDef( "x", DisplayerAttributeGroupDef.AXIS_GROUP ); public static final DisplayerAttributeGroupDef YAXIS_GROUP = new DisplayerAttributeGroupDef( "y", DisplayerAttributeGroupDef.AXIS_GROUP ); private Set children = new HashSet(); public DisplayerAttributeGroupDef() { } public DisplayerAttributeGroupDef( String id ) { super( id ); } public DisplayerAttributeGroupDef( String id, DisplayerAttributeGroupDef parent ) { super( id, parent ); } public Set getChildren() { return children; } public DisplayerAttributeGroupDef addChild(DisplayerAttributeDef member) { children.add(member); member.setParent(this); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerConstraints.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.dashbuilder.dataset.DataSetLookupConstraints; import org.dashbuilder.dataset.ValidationError; /** * Every Displayer implementation use this class to specify what are the supported DisplayerSettings attributes * as well as the supported data sets in order to fit the displayer needs. */ public class DisplayerConstraints { protected DataSetLookupConstraints dataSetLookupConstraints; protected Set supportedEditorAttributes; protected Set excludedEditorAttributes; protected Set supportedEditorAttrStrings; protected boolean supportingComponentAttributes; public DisplayerConstraints(DataSetLookupConstraints dataSetLookupConstraints) { this.dataSetLookupConstraints = dataSetLookupConstraints; supportedEditorAttributes = new HashSet<>(); supportedEditorAttrStrings = new HashSet<>(); excludedEditorAttributes = new HashSet<>(); } public DisplayerConstraints supportingComponentAttributes(boolean supportingComponentAttributes) { this.supportingComponentAttributes = supportingComponentAttributes; return this; } public DisplayerConstraints supportsAttribute(DisplayerAttributeDef attributeDef) { // Discard excluded attributes if (!excludedEditorAttributes.contains(attributeDef)) { // Support the attribute and all its ancestors. DisplayerAttributeDef _attr = attributeDef; while (_attr != null) { supportedEditorAttributes.add(_attr); supportedEditorAttrStrings.add(_attr.getFullId()); _attr = _attr.getParent(); } // ... and all its descendants as well. if (attributeDef instanceof DisplayerAttributeGroupDef) { for (DisplayerAttributeDef member : ((DisplayerAttributeGroupDef) attributeDef).getChildren()) { supportsAttribute(member); } } } return this; } public DisplayerConstraints excludeAttribute(DisplayerAttributeDef attributeDef) { excludedEditorAttributes.add(attributeDef); supportedEditorAttributes.remove(attributeDef); supportedEditorAttrStrings.remove(attributeDef.getFullId()); return this; } public Set getSupportedAttributes() { return supportedEditorAttributes; } public DataSetLookupConstraints getDataSetLookupConstraints() { return dataSetLookupConstraints; } public DisplayerConstraints setDataSetLookupConstraints(DataSetLookupConstraints dataSetLookupConstraints) { this.dataSetLookupConstraints = dataSetLookupConstraints; return this; } public void removeUnsupportedAttributes(DisplayerSettings displayerSettings) { String componentId = displayerSettings.getComponentId(); if (componentId != null) { Map settingsMap = displayerSettings.getSettingsFlatMap(); for (String setting : new HashSet<>(settingsMap.keySet())) { if (!supportedEditorAttrStrings.contains(setting) && !setting.startsWith(componentId)) { displayerSettings.removeDisplayerSetting(setting); } } } } public ValidationError check(DisplayerSettings settings) { if (dataSetLookupConstraints == null) { return createValidationError(ERROR_DATASET_LOOKUP_CONSTRAINTS_NOT_FOUND); } if (settings.getDataSet() != null) { ValidationError error = dataSetLookupConstraints.check(settings.getDataSet()); if (error != null) return error; } else if (settings.getDataSetLookup() != null) { ValidationError error = dataSetLookupConstraints.check(settings.getDataSetLookup()); if (error != null) return error; } return null; } public static final int ERROR_DATASET_LOOKUP_CONSTRAINTS_NOT_FOUND = 301; protected ValidationError createValidationError(int error) { switch (error) { case ERROR_DATASET_LOOKUP_CONSTRAINTS_NOT_FOUND: return new ValidationError(error, "Missing DataSetLookupContraints instance"); } return new ValidationError(error); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerSettings.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.dashbuilder.dataset.DataColumn; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.sort.SortOrder; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class DisplayerSettings { protected String UUID; protected DataSet dataSet; protected DataSetLookup dataSetLookup; protected List columnSettingsList = new ArrayList(); protected Map settings = new HashMap(30); public DisplayerSettings() {} public DisplayerSettings(DisplayerType displayerType) { this(); setType(displayerType); } public DisplayerSettings(DisplayerType displayerType, DisplayerSubType subType) { this(displayerType); setSubtype(subType); } public DisplayerSettings cloneInstance() { DisplayerSettings clone = new DisplayerSettings(); clone.UUID = UUID; clone.settings = new HashMap(settings); clone.columnSettingsList = new ArrayList(); for (ColumnSettings columnSettings : columnSettingsList) { clone.columnSettingsList.add(columnSettings.cloneInstance()); } if (dataSet != null) { clone.dataSet = dataSet.cloneInstance(); } if (dataSetLookup != null) { clone.dataSetLookup = dataSetLookup.cloneInstance(); } return clone; } public boolean equals(Object obj) { try { DisplayerSettings other = (DisplayerSettings) obj; if (other == this) { return true; } if (other == null) { return false; } if (UUID != null && !UUID.equals(other.UUID)) { return false; } if (dataSet != null && !dataSet.equals(other.dataSet)) { return false; } if (dataSetLookup != null && !dataSetLookup.equals(other.dataSetLookup)) { return false; } if (columnSettingsList.size() != other.columnSettingsList.size()) { return false; } for (int i = 0; i < columnSettingsList.size(); i++) { if (!columnSettingsList.get(i).equals(other.columnSettingsList.get(i))) { return false; } } if (settings.size() != other.settings.size()) { return false; } for (String setting : settings.keySet()) { if (!settings.get(setting).equals(other.settings.get(setting))) { return false; } } return true; } catch (ClassCastException e) { return false; } } public List getColumnSettingsList() { return columnSettingsList; } public void setColumnSettingsList(List columnSettingsList) { if (columnSettingsList != null) { this.columnSettingsList = columnSettingsList; } else { this.columnSettingsList.clear(); } } public void removeColumnSettings(String columnId) { Iterator it = columnSettingsList.iterator(); while (it.hasNext()) { ColumnSettings columnSettings = it.next(); if (columnSettings.getColumnId().equals(columnId)) { it.remove(); } } } public ColumnSettings getColumnSettings(String columnId) { for (ColumnSettings columnSettings : columnSettingsList) { if (columnSettings.getColumnId().equals(columnId)) return columnSettings; } return null; } public ColumnSettings getColumnSettings(DataColumn column) { ColumnSettings sourceSettings = getColumnSettings(column.getId()); return ColumnSettings.cloneWithDefaults(sourceSettings, column); } public void setColumnName(String columnId, String name) { ColumnSettings columnSettings = getColumnSettings(columnId); if (columnSettings == null) columnSettingsList.add(columnSettings = new ColumnSettings(columnId)); columnSettings.setColumnName(name); } public void setColumnValueExpression(String columnId, String expression) { ColumnSettings columnSettings = getColumnSettings(columnId); if (columnSettings == null) columnSettingsList.add(columnSettings = new ColumnSettings(columnId)); columnSettings.setValueExpression(expression); } public void setColumnValuePattern(String columnId, String pattern) { ColumnSettings columnSettings = getColumnSettings(columnId); if (columnSettings == null) columnSettingsList.add(columnSettings = new ColumnSettings(columnId)); columnSettings.setValuePattern(pattern); } public void setColumnEmptyTemplate(String columnId, String template) { ColumnSettings columnSettings = getColumnSettings(columnId); if (columnSettings == null) columnSettingsList.add(columnSettings = new ColumnSettings(columnId)); columnSettings.setEmptyTemplate(template); } private String getSettingPath(DisplayerAttributeDef displayerAttributeDef) { return displayerAttributeDef.getFullId(); } private int parseInt(String value, int defaultValue) { if (value == null || value.trim().length() == 0) return defaultValue; return Integer.parseInt(value); } private long parseLong(String value, long defaultValue) { if (value == null || value.trim().length() == 0) return defaultValue; return Long.parseLong(value); } private boolean parseBoolean(String value) { return parseBoolean(value, false); } private boolean parseBoolean(String value, boolean defaultValue) { if (value == null || value.trim().length() == 0) return defaultValue; return Boolean.parseBoolean(value); } private String parseString(String value) { if (value == null || value.trim().length() == 0) return ""; return value; } public String getUUID() { return UUID; } public void setUUID(String UUID) { this.UUID = UUID; } public DataSet getDataSet() { return dataSet; } public void setDataSet(DataSet dataSet) { this.dataSet = dataSet; } public DataSetLookup getDataSetLookup() { return dataSetLookup; } public void setDataSetLookup(DataSetLookup dataSetLookup) { this.dataSetLookup = dataSetLookup; } // 'Generic' getter method public String getDisplayerSetting(DisplayerAttributeDef displayerAttributeDef) { return settings.get(getSettingPath(displayerAttributeDef)); } // 'Generic' setter method public void setDisplayerSetting(DisplayerAttributeDef displayerAttributeDef, String value) { settings.put(getSettingPath(displayerAttributeDef), value); } // 'Generic' setter method public void setDisplayerSetting(String displayerAttributeDef, String value) { settings.put(displayerAttributeDef, value); } // 'Generic' remove method public void removeDisplayerSetting(DisplayerAttributeDef displayerAttributeDef) { settings.remove(getSettingPath(displayerAttributeDef)); } // 'Generic' remove method public void removeDisplayerSetting(DisplayerAttributeGroupDef displayerAttributeGroup) { for (DisplayerAttributeDef attributeDef : displayerAttributeGroup.getChildren()) { settings.remove(getSettingPath(attributeDef)); } } // 'Generic' remove method public void removeDisplayerSetting(String displayerAttributeDef) { settings.remove(displayerAttributeDef); } public Map getSettingsFlatMap() { return settings; } public void setSettingsFlatMap(Map settings) { this.settings = settings; } public DisplayerType getType() { String strType = settings.get(getSettingPath(DisplayerAttributeDef.TYPE)); return DisplayerType.getByName(strType); } public void setType(DisplayerType displayerType) { settings.put(getSettingPath(DisplayerAttributeDef.TYPE), displayerType.toString()); } public DisplayerSubType getSubtype() { String strSubtype = settings.get(getSettingPath(DisplayerAttributeDef.SUBTYPE)); return DisplayerSubType.getByName(strSubtype); } public void setSubtype(DisplayerSubType subtype) { if (subtype != null) settings.put(getSettingPath(DisplayerAttributeDef.SUBTYPE), subtype.toString()); else settings.remove(getSettingPath(DisplayerAttributeDef.SUBTYPE)); } public String getRenderer() { return settings.get(getSettingPath(DisplayerAttributeDef.RENDERER)); } public void setRenderer(String renderer) { settings.put(getSettingPath(DisplayerAttributeDef.RENDERER), renderer); } public String getTitle() { return parseString(settings.get(getSettingPath(DisplayerAttributeDef.TITLE))); } public void setTitle(String title) { settings.put(getSettingPath(DisplayerAttributeDef.TITLE), title); } public boolean isTitleVisible() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.TITLE_VISIBLE))); } public void setTitleVisible(boolean titleVisible) { settings.put(getSettingPath(DisplayerAttributeDef.TITLE_VISIBLE), Boolean.toString(titleVisible)); } public boolean isCSVExportAllowed() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.ALLOW_EXPORT_CSV))) || parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.EXPORT_TO_CSV))); } public void setCSVExportAllowed(boolean csvExportAllowed) { settings.put(getSettingPath(DisplayerAttributeDef.EXPORT_TO_CSV), Boolean.toString(csvExportAllowed)); } public boolean isExcelExportAllowed() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.ALLOW_EXPORT_EXCEL))) || parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.EXPORT_TO_XLS))); } public void setExcelExportAllowed(boolean excelExportAllowed) { settings.put(getSettingPath(DisplayerAttributeDef.EXPORT_TO_XLS), Boolean.toString(excelExportAllowed)); } public int getRefreshInterval() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.REFRESH_INTERVAL)), -1); } public void setRefreshInterval(int refreshInSeconds) { settings.put(getSettingPath(DisplayerAttributeDef.REFRESH_INTERVAL), Integer.toString(refreshInSeconds)); } public boolean isRefreshStaleData() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.REFRESH_STALE_DATA))); } public void setRefreshStaleData(boolean refresh) { settings.put(getSettingPath(DisplayerAttributeDef.REFRESH_STALE_DATA), Boolean.toString(refresh)); } public boolean isFilterEnabled() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.FILTER_ENABLED))); } public void setFilterEnabled(boolean filterEnabled) { settings.put(getSettingPath(DisplayerAttributeDef.FILTER_ENABLED), Boolean.toString(filterEnabled)); } public boolean isFilterSelfApplyEnabled() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.FILTER_SELFAPPLY_ENABLED))); } public void setFilterSelfApplyEnabled(boolean filterSelfApplyEnabled) { settings.put(getSettingPath(DisplayerAttributeDef.FILTER_SELFAPPLY_ENABLED), Boolean.toString(filterSelfApplyEnabled)); } public boolean isFilterNotificationEnabled() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.FILTER_NOTIFICATION_ENABLED))); } public void setFilterNotificationEnabled(boolean filterNotificationEnabled) { settings.put(getSettingPath(DisplayerAttributeDef.FILTER_NOTIFICATION_ENABLED), Boolean.toString(filterNotificationEnabled)); } public boolean isFilterListeningEnabled() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.FILTER_LISTENING_ENABLED))); } public void setFilterListeningEnabled(boolean filterListeningEnabled) { settings.put(getSettingPath(DisplayerAttributeDef.FILTER_LISTENING_ENABLED), Boolean.toString(filterListeningEnabled)); } public int getSelectorWidth() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.SELECTOR_WIDTH)), -1); } public void setSelectorWidth(int filterWidth) { settings.put(getSettingPath(DisplayerAttributeDef.SELECTOR_WIDTH), Integer.toString(filterWidth)); } public boolean isSelectorMultiple() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.SELECTOR_MULTIPLE))); } public void setSelectorMultiple(boolean filterMultiple) { settings.put(getSettingPath(DisplayerAttributeDef.SELECTOR_MULTIPLE), Boolean.toString(filterMultiple)); } public boolean isSelectorInputsEnabled() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.SELECTOR_SHOW_INPUTS)), true); } public void setSelectorInputsEnabled(boolean enabled) { settings.put(getSettingPath(DisplayerAttributeDef.SELECTOR_SHOW_INPUTS), Boolean.toString(enabled)); } public int getChartWidth() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_WIDTH)), 500); } public void setChartWidth(int chartWidth) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_WIDTH), Integer.toString(chartWidth)); } public String getChartBackgroundColor() { return parseString(settings.get(getSettingPath(DisplayerAttributeDef.CHART_BGCOLOR))); } public void setChartBackgroundColor(String color) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_BGCOLOR), color); } public int getChartHeight() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_HEIGHT)), 300); } public void setChartHeight(int chartHeight) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_HEIGHT), Integer.toString(chartHeight)); } public int getChartMarginTop() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_TOP)), 0); } public void setChartMarginTop(int chartMarginTop) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_TOP), Integer.toString(chartMarginTop)); } public int getChartMarginBottom() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_BOTTOM)), 0); } public void setChartMarginBottom(int chartMarginBottom) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_BOTTOM), Integer.toString(chartMarginBottom)); } public int getChartMarginLeft() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_LEFT)), 0); } public void setChartMarginLeft(int chartMarginLeft) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_LEFT), Integer.toString(chartMarginLeft)); } public int getChartMarginRight() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_RIGHT)), 0); } public void setChartMarginRight(int chartMarginRight) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_MARGIN_RIGHT), Integer.toString(chartMarginRight)); } public int getChartMaxWidth() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_MAX_WIDTH)), 600); } public void setChartMaxWidth(int chartWidth) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_MAX_WIDTH), Integer.toString(chartWidth)); } public int getChartMaxHeight() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.CHART_MAX_HEIGHT)), 400); } public void setChartMaxHeight(int chartHeight) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_MAX_HEIGHT), Integer.toString(chartHeight)); } public void setResizable(boolean resizable) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_RESIZABLE), Boolean.toString(resizable)); } public boolean isResizable() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.CHART_RESIZABLE))); } public boolean isChartShowLegend() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.CHART_SHOWLEGEND))); } public void setChartShowLegend(boolean chartShowLegend) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_SHOWLEGEND), Boolean.toString(chartShowLegend)); } public Position getChartLegendPosition() { Position pos = Position.getByName(settings.get(getSettingPath(DisplayerAttributeDef.CHART_LEGENDPOSITION))); if (pos == null) return Position.RIGHT; return pos; } public void setChartLegendPosition(Position chartLegendPosition) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_LEGENDPOSITION), chartLegendPosition.toString()); } public int getTablePageSize() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.TABLE_PAGESIZE)), 10); } public void setTablePageSize(int tablePageSize) { settings.put(getSettingPath(DisplayerAttributeDef.TABLE_PAGESIZE), Integer.toString(tablePageSize)); } public int getTableWidth() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.TABLE_WIDTH)), 0); } public void setTableWidth(int tableWidth) { settings.put(getSettingPath(DisplayerAttributeDef.TABLE_WIDTH), Integer.toString(tableWidth)); } public boolean isTableSortEnabled() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.TABLE_SORTENABLED))); } public void setTableSortEnabled(boolean tableSortEnabled) { settings.put(getSettingPath(DisplayerAttributeDef.TABLE_SORTENABLED), Boolean.toString(tableSortEnabled)); } public void setTableColumnPickerEnabled(boolean tableColumnPickerEnabled) { settings.put(getSettingPath(DisplayerAttributeDef.TABLE_COLUMN_PICKER_ENABLED), Boolean.toString(tableColumnPickerEnabled)); } public String getTableDefaultSortColumnId() { return parseString(settings.get(getSettingPath(DisplayerAttributeDef.TABLE_SORTCOLUMNID))); } public void setTableDefaultSortColumnId(String tableDefaultSortColumnId) { settings.put(getSettingPath(DisplayerAttributeDef.TABLE_SORTCOLUMNID), tableDefaultSortColumnId); } public SortOrder getTableDefaultSortOrder() { SortOrder order = SortOrder.getByName(settings.get(getSettingPath(DisplayerAttributeDef.TABLE_SORTORDER))); if (order == null) return SortOrder.ASCENDING; return order; } public void setTableDefaultSortOrder(SortOrder tableDefaultSortOrder) { settings.put(getSettingPath(DisplayerAttributeDef.TABLE_SORTORDER), tableDefaultSortOrder.toString()); } public boolean isTableColumnPickerEnabled() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.TABLE_COLUMN_PICKER_ENABLED)), true); } public boolean isXAxisShowLabels() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.XAXIS_SHOWLABELS))); } public void setXAxisShowLabels(boolean axisShowLabels) { settings.put(getSettingPath(DisplayerAttributeDef.XAXIS_SHOWLABELS), Boolean.toString(axisShowLabels)); } public int getXAxisLabelsAngle() { return parseInt(settings.get(getSettingPath(DisplayerAttributeDef.XAXIS_LABELSANGLE)), 0); } public void setXAxisLabelsAngle(int axisLabelsAngle) { settings.put(getSettingPath(DisplayerAttributeDef.XAXIS_LABELSANGLE), Integer.toString(axisLabelsAngle)); } public String getXAxisTitle() { return parseString(settings.get(getSettingPath(DisplayerAttributeDef.XAXIS_TITLE))); } public void setXAxisTitle(String axisTitle) { settings.put(getSettingPath(DisplayerAttributeDef.XAXIS_TITLE), axisTitle); } public boolean isYAxisShowLabels() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.YAXIS_SHOWLABELS))); } public void setYAxisShowLabels(boolean axisShowLabels) { settings.put(getSettingPath(DisplayerAttributeDef.YAXIS_SHOWLABELS), Boolean.toString(axisShowLabels)); } // public int getYAxisLabelsAngle() { // return parseInt( settings.get( getSettingPath( DisplayerAttributeDef.YAXIS_LABELSANGLE ) ), 10 ); // } // // public void setYAxisLabelsAngle( int axisLabelsAngle ) { // settings.put( getSettingPath( DisplayerAttributeDef.YAXIS_LABELSANGLE ), Integer.toString( axisLabelsAngle ) ); // } public String getYAxisTitle() { return parseString(settings.get(getSettingPath(DisplayerAttributeDef.YAXIS_TITLE))); } public void setYAxisTitle(String axisTitle) { settings.put(getSettingPath(DisplayerAttributeDef.YAXIS_TITLE), axisTitle); } public long getMeterStart() { return parseLong(settings.get(getSettingPath(DisplayerAttributeDef.METER_START)), 0); } public void setMeterStart(long meterStart) { settings.put(getSettingPath(DisplayerAttributeDef.METER_START), Long.toString(meterStart)); } public long getMeterWarning() { return parseLong(settings.get(getSettingPath(DisplayerAttributeDef.METER_WARNING)), 60); } public void setMeterWarning(long meterWarning) { settings.put(getSettingPath(DisplayerAttributeDef.METER_WARNING), Long.toString(meterWarning)); } public long getMeterCritical() { return parseLong(settings.get(getSettingPath(DisplayerAttributeDef.METER_CRITICAL)), 90); } public void setMeterCritical(long meterCritical) { settings.put(getSettingPath(DisplayerAttributeDef.METER_CRITICAL), Long.toString(meterCritical)); } public long getMeterEnd() { return parseLong(settings.get(getSettingPath(DisplayerAttributeDef.METER_END)), 100); } public void setMeterEnd(long meterEnd) { settings.put(getSettingPath(DisplayerAttributeDef.METER_END), Long.toString(meterEnd)); } public String getDonutHoleTitle() { return settings.get(getSettingPath(DisplayerAttributeDef.DONUT_HOLE_TITLE)); } public void setDonutHoleTitle(String holeTitle) { settings.put(getSettingPath(DisplayerAttributeDef.DONUT_HOLE_TITLE), holeTitle); } public boolean isChart3D() { return parseBoolean(settings.get(getSettingPath(DisplayerAttributeDef.CHART_3D))); } public void setChart3D(boolean barchartThreeDimension) { settings.put(getSettingPath(DisplayerAttributeDef.CHART_3D), Boolean.toString(barchartThreeDimension)); } public void setHtmlTemplate(String htmlTemplate) { settings.put(getSettingPath(DisplayerAttributeDef.HTML_TEMPLATE), htmlTemplate); } public void setJsTemplate(String jsTemplate) { settings.put(getSettingPath(DisplayerAttributeDef.JS_TEMPLATE), jsTemplate); } public String getHtmlTemplate() { return parseString(settings.get(getSettingPath(DisplayerAttributeDef.HTML_TEMPLATE))); } public String getJsTemplate() { return parseString(settings.get(getSettingPath(DisplayerAttributeDef.JS_TEMPLATE))); } public void setMapColorScheme(MapColorScheme colorScheme) { settings.put(getSettingPath(DisplayerAttributeDef.MAP_COLOR_SCHEME), colorScheme.toString()); } public MapColorScheme getMapColorScheme() { return MapColorScheme.from(settings.get(getSettingPath(DisplayerAttributeDef.MAP_COLOR_SCHEME))); } public String getComponentId() { return settings.get(getSettingPath(DisplayerAttributeDef.EXTERNAL_COMPONENT_ID)); } public String setComponentId(String componentId) { return settings.put(getSettingPath(DisplayerAttributeDef.EXTERNAL_COMPONENT_ID), componentId); } public void setComponentProperty(String key, String value) { String componentId = getComponentId(); if (componentId != null) { String newParamKey = componentPrefix(componentId, key); settings.put(newParamKey, value); } } public String getComponentProperty(String key) { String componentId = getComponentId(); if (componentId == null) { return null; } String newKey = componentPrefix(componentId, key); return settings.get(newKey); } public Map getComponentProperties() { String componentId = getComponentId(); if (componentId == null) { return Collections.emptyMap(); } return settings.entrySet() .stream() .filter(e -> e.getKey().startsWith(componentId)) .collect(Collectors.toMap(e -> removeComponentPrefix(componentId, e.getKey()), Map.Entry::getValue)); } public String getComponentPartition() { return settings.get(getSettingPath(DisplayerAttributeDef.EXTERNAL_COMPONENT_PARTITION)); } public String setComponentPartition(String componentPartition) { return settings.put(getSettingPath(DisplayerAttributeDef.EXTERNAL_COMPONENT_PARTITION), componentPartition); } private String componentPrefix(String componentId, String key) { return componentId + "." + key; } private String removeComponentPrefix(String componentId, String key) { return key.replaceAll(componentId + ".", ""); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookupBuilder; /** * A DisplayerSettingsBuilder allows for the assembly of a DisplayerSettings instance in a friendly manner. * *
     *   DisplayerSettingsFactory.newBarChartSettings()
     *   .title("By Product")
     *   .titleVisible(false)
     *   .margins(10, 50, 100, 100)
     *   .column("Product")
     *   .column("Total amount")
     *   .horizontal()
     *   .buildSettings();
     * 
    * * @see DisplayerSettings */ public interface DisplayerSettingsBuilder extends DataSetLookupBuilder { /** * Set the DisplayerSettings' UUID. * * @param uuid The UUID of the DisplayerSettings that is being assembled. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T uuid(String uuid); /** * Set a direct reference to the source data set that will be used by the Displayer that is being assembled. *

    When using this dataset provided mode the data set lookup operations set (if any): filter, group & sort will not be taking into account). * * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. * @see org.dashbuilder.dataset.DataSet */ T dataset(DataSet dataSet); /** * Sets the caption that will be shown for this particular visualization of the data. * @param title The caption to be shown * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T title(String title); /** * Set whether the caption should be visible or not. * @param visible True if the caption is to be visible, false if not. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T titleVisible(boolean visible); /** * Set the background color for the displayer. * @param backgroundColor The background color code. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T backgroundColor(String backgroundColor); /** * Set the renderer that will be used for visualizing this DisplayerSettings. * @param renderer The identifier of the renderer. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T renderer(String renderer); /** * Set the DisplayerSettings' subtype. * * @param displayerSubType The displayer's subtype. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T subtype(DisplayerSubType displayerSubType); /** * Enable the ability to select/filter values (or range of values) within the data displayer. * *

    Usually, in a dashboard there exists a unique coordinator which takes cares of propagate all the data * selection events among the other displayers. If enabled then there exists also the ability to configure how to * interact with other displayers in the same dashboard.

    * @param applySelf If true then any filter request issued within the data displayer will be applied to the own displayer. * @param notifyOthers If true then any filter request issued within the data displayer will be propagated to other interested displayers. * @param receiveFromOthers If true then the data displayer will listen for filter requests coming from other displayers. * * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T filterOn(boolean applySelf, boolean notifyOthers, boolean receiveFromOthers); /** * Disable the ability to select/filter values (or range of values) within the displayer. * * @param receiveFromOthers If true then the data displayer will listen for filter requests coming from other displayers. * @see DisplayerSettingsBuilder#filterOn DisplayerSettingsBuilder's filterOn method. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T filterOff(boolean receiveFromOthers); /** * Force the displayer to redraw only when data becomes stale. * * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T refreshOn(); /** * Force the displayer to redraw every time interval. * * @param seconds The refresh time frame in seconds. If < 0 then periodic refresh is disabled. * @param onStale Refresh when the data becomes stale. * * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T refreshOn(int seconds, boolean onStale); /** * Switch off the automatic refresh. * * @see DisplayerSettingsBuilder#refreshOn DisplayerSettingsBuilder's refreshOn method. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T refreshOff(); /** * Defines the display name for the last specified data set column. * * NOTE: This method can only be called right after a call to DataSetLookupBuilder#column(...). * * @param name The column display name. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T format(String name); /** * Defines the display format for the last specified data set column.Every data set value will be formatted * according to the specified pattern parameter which defines the string format of the data set value. * Examples: *
      *
    • format("Amount", "$ #,###.##") => "$ 10,450.5"
    • *
    • format("Amount", "$ #,### K") => "$ 450 K"
    • *
    * * NOTE: This method can only be called right after a call to DataSetLookupBuilder#column(...). * * @param name The column display name. * @param pattern The standard java DecimalFormat and DateFormat can be used used for both number and date columns. * @see java.text.DecimalFormat * @see java.text.SimpleDateFormat * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T format(String name, String pattern); /** * Defines the display format for the specified data set column. Every data set value will be formatted * according to the specified pattern parameter which defines the string format of the data set value. * Examples: *
      *
    • format("Amount", "$ #,###.##") => "$ 10,450.5"
    • *
    • format("Amount", "$ #,### K") => "$ 450 K"
    • *
    * * @param columnId The column identifier. * @param name The column display name. * @param pattern The standard java DecimalFormat and DateFormat are used for both number and date columns. * @see java.text.DecimalFormat * @see java.text.SimpleDateFormat * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T format(String columnId, String name, String pattern); /** * Defines a mathematical expression used to calculate the real values to display for the last specified data set * column. * *

    For numeric columns the expression can be any basic math expression where the value keyword represent * the source data set value and any of the basic math operators "/ * + -" are allowed. Examples: *

      *
    • format("Amount", "$ #,###.##").expression("value") => "$ 10,450.5"
    • *
    • format("Amount", "$ #,###.##").expression("value-1") => "$ 10,449.5"
    • *
    • format("Amount", "$ #,##0.00 K").expression("value/1000") => "$ 10.45 K"
    • *
    * *

    For text columns you can manipulate the string using any javascript statement: Examples

    *
      *
    • format("Quarter").expression("["1st Q", "2nd Q", "3rd Q", "4th Q"][value+1]") => "3rd Q" (value=1 in a date fixed grouped column)
    • *
    • format("3 chars").expression("value.substring(0, 3) + "...") => "Dav..." it takes the first 3 chars only
    • *
    * * NOTE: This method can only be called right after a call to DataSetLookupBuilder#column(...) * * @param expression The expression used to calculate the value to display * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T expression(String expression); /** * Sames as expression(String expression) but using the specified column. * * @param columnId The column identifier. * @param expression The expression used to calculate the value to display * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T expression(String columnId, String expression); /** *

    Support for user-provided HTML templates. For instance, a metric displayer could be configured as follows:

    * *
         * {@code 
    *

    ${title}

    *

    ${value}

    *
    * }
    * * Notice that, references (like "${value.ref}" in the example above) can be added to any of the HTML elements so that they can be referenced from the Javascript template. * See {@link #jsTemplate(String)} for further details. * * @param html The HTML template used to render the displayer. The following enumeration contains all the available variables: *
      *
    • id: An identifier that it is unique among all the displayers
    • *
    • title: The metric title
    • *
    • value: The formatted value
    • *
    • value.raw: The raw value
    • *
    • width: The metric width
    • *
    • height: The metric height
    • *
    • marginTop: The top margin
    • *
    • marginBottom: The bottom margin
    • *
    • marginLeft: The left margin
    • *
    • marginRight: The right margin
    • *
    • bgColor: The background color
    • *
    • isFilterEnabled: true or false depending whether the filter setting is enabled (see {@link #filterOn(boolean, boolean, boolean)})
    • *
    • isFilterOn: true or false depending whether the filter function is currently on or of
    • *
    * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T htmlTemplate(String html); /** * Specifies the JS template that is invoked every time the displayer is drawn. * *

    Notice, HTML elements tagged as "${...}" can be referenced from the JS template. For instance, given the following * HTML template:

    * *
         * {@code 
    *

    ${title}

    *

    ${value}

    *
    * }
    * *

    It is possible to implement some conditional into the JS so that the color of the text displayed depends on its value:

    * *
         * {@code ${valref}.style.color= ${value.raw} > 1000 ? "red" : "black";
         *  }
    * * where the "${valref}" is the identifier of the HTML element holding the value. * * @param js A JS template. Notice, the same variables supported in {@link #htmlTemplate(String)} can be used in the JS. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T jsTemplate(String js); /** * @return The DisplayerSettings instance that has been configured. * @see DisplayerSettings */ DisplayerSettings buildSettings(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerSettingsFactory.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import org.dashbuilder.displayer.impl.AreaChartSettingsBuilderImpl; import org.dashbuilder.displayer.impl.BarChartSettingsBuilderImpl; import org.dashbuilder.displayer.impl.BubbleChartSettingsBuilderImpl; import org.dashbuilder.displayer.impl.ExternalDisplayerSettingsBuilderImpl; import org.dashbuilder.displayer.impl.LineChartSettingsBuilderImpl; import org.dashbuilder.displayer.impl.MapChartSettingsBuilderImpl; import org.dashbuilder.displayer.impl.MeterChartSettingsBuilderImpl; import org.dashbuilder.displayer.impl.MetricSettingsBuilderImpl; import org.dashbuilder.displayer.impl.PieChartSettingsBuilderImpl; import org.dashbuilder.displayer.impl.SelectorDisplayerSettingsBuilderImpl; import org.dashbuilder.displayer.impl.TableDisplayerSettingsBuilderImpl; /** * Factory class for creating DisplayerSettingsBuilder instances. */ public final class DisplayerSettingsFactory { public static BarChartSettingsBuilder newBarChartSettings() { return new BarChartSettingsBuilderImpl(); } public static PieChartSettingsBuilder newPieChartSettings() { return new PieChartSettingsBuilderImpl(); } public static AreaChartSettingsBuilder newAreaChartSettings() { return new AreaChartSettingsBuilderImpl(); } public static LineChartSettingsBuilder newLineChartSettings() { return new LineChartSettingsBuilderImpl(); } public static BubbleChartSettingsBuilder newBubbleChartSettings() { return new BubbleChartSettingsBuilderImpl(); } public static MapChartSettingsBuilder newMapChartSettings() { return new MapChartSettingsBuilderImpl(); } public static TableDisplayerSettingsBuilder newTableSettings() { return new TableDisplayerSettingsBuilderImpl(); } public static MeterChartSettingsBuilder newMeterChartSettings() { return new MeterChartSettingsBuilderImpl(); } public static SelectorDisplayerSettingsBuilder newSelectorSettings() { return new SelectorDisplayerSettingsBuilderImpl(); } public static MetricSettingsBuilder newMetricSettings() { return new MetricSettingsBuilderImpl(); } public static ExternalDisplayerSettingsBuilder newExternalDisplayerSettings() { return new ExternalDisplayerSettingsBuilderImpl(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerSubType.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; public enum DisplayerSubType { LINE, SMOOTH, AREA, AREA_STACKED, // STEPPED, BAR, BAR_STACKED, COLUMN, COLUMN_STACKED, PIE, PIE_3D, DONUT, MAP_REGIONS, MAP_MARKERS, METRIC_CARD, METRIC_CARD2, METRIC_PLAIN_TEXT, METRIC_QUOTA, SELECTOR_DROPDOWN, SELECTOR_SLIDER, SELECTOR_LABELS; public static DisplayerSubType getByName(String str) { if (str == null) return null; try { return valueOf(str.toUpperCase()); } catch (Exception e) { return null; } } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/DisplayerType.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import java.util.ArrayList; import java.util.List; import static org.dashbuilder.displayer.DisplayerSubType.*; /** * An enumeration for the different types of displayers. */ public enum DisplayerType { /** * Bar Chart */ BARCHART(BAR, BAR_STACKED, COLUMN, COLUMN_STACKED), /** * Pie Chart */ PIECHART(PIE, PIE_3D, DONUT), /** * Area Chart */ AREACHART(AREA, AREA_STACKED/*, STEPPED*/), /** * Line Chart */ LINECHART(LINE, SMOOTH), /** * Bubble Chart */ BUBBLECHART(), /** * Meter Chart */ METERCHART(), /** * Table reports */ TABLE(), /** * Map */ MAP(MAP_REGIONS, MAP_MARKERS), /** * Selector */ SELECTOR(SELECTOR_DROPDOWN, SELECTOR_LABELS, SELECTOR_SLIDER), /** * Metric */ METRIC(METRIC_CARD, METRIC_CARD2, METRIC_QUOTA, METRIC_PLAIN_TEXT), /** * External Component Displayer */ EXTERNAL_COMPONENT(); DisplayerType(DisplayerSubType... subtypes) { for (DisplayerSubType displayerSubType : subtypes) { this.subtypes.add(displayerSubType); } } private List subtypes = new ArrayList<>(); public static DisplayerType getByName(String str) { try { return valueOf(str.toUpperCase()); } catch (Exception e) { return null; } } public List getSubTypes() { return subtypes; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/ExternalDisplayerSettingsBuilder.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for external components * */ public interface ExternalDisplayerSettingsBuilder extends ChartSettingsBuilder { /** * Set the external component id. * @param id * The component Id * @return * This builder instance */ T componentId(String id); /** * Set an external component property * @param key * The parameter key * @param value * The parameter value * @return * this builder instance */ T componentProperty(String key, String value); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/LineChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for line charts * *
     *   DisplayerSettingsFactory.newLineChartSettings()
     *   .title("By Product")
     *   .column("Product")
     *   .column("Total amount")
     * 
    */ public interface LineChartSettingsBuilder extends XAxisChartSettingsBuilder { /** * Set this line chart's subtype to a simple line chart * @return The DisplayerSettingsBuilder instance that is being used to configure a Line chart data displayer. */ T subType_Line(); /** * Set this line chart's subtype to a smooth line chart (i.e. a line chart without sharp edges) * @return The DisplayerSettingsBuilder instance that is being used to configure a Line chart data displayer. */ T subType_SmoothLine(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/MapChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for map charts * *
     *   DisplayerSettingsFactory.newMapChartSettings()
     *   .title("By Country")
     *   .column("Country")
     *   .column("Total amount")
     * 
    */ public interface MapChartSettingsBuilder extends XAxisChartSettingsBuilder { /** * Set this map chart's subtype to a region map chart (i.e. a Map chart that highlights certain regions) * @return The DisplayerSettingsBuilder instance that is being used to configure a Map chart data displayer. */ T subType_Region_Map(); /** * Set this map chart's subtype to a marker map chart (i.e. a Map chart that shows a magnitude indication for certain regions) * @return The DisplayerSettingsBuilder instance that is being used to configure a Map chart data displayer. */ T subType_Marker_Map(); /** * Set this map color scheme. * @param colorScheme * @return The DisplayerSettingsBuilder instance that is being used to configure a Map chart data displayer. */ T colorScheme(MapColorScheme colorScheme); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/MapColorScheme.java ================================================ package org.dashbuilder.displayer; import java.util.stream.Stream; public enum MapColorScheme { RED, GREEN, BLUE; public static MapColorScheme from(String value) { return Stream.of(values()) .filter(v -> v.toString().equalsIgnoreCase(value)) .findFirst().orElseGet(() -> GREEN); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/MeterChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for meter charts * *
     *   DisplayerSettingsFactory.newMeterChartSettings()
     *   .title("Sales goal")
     *   .titleVisible(true)
     *   .width(250).height(250)
     *   .meter(0, 15000000, 25000000, 35000000)
     *   .column("Total amount")
     *   .buildSettings());
     * 
    */ public interface MeterChartSettingsBuilder extends ChartSettingsBuilder { /** * Set specific the configuration parameters for this meter chart. * @param start The start of the meter scale * @param warning The warning level, any value above this level will be shown in orange on the meter chart. * Values below this level are shown in green. * @param critical The critical level, any value above this level will be shown in red on the meter chart. * @param end The end of the meter scale. * @return The DisplayerSettingsBuilder instance that is being used to configure a Meter data displayer. */ T meter(long start, long warning, long critical, long end); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/MetricSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for meter charts * *
     *   DisplayerSettingsFactory.newMetricSettings()
     *   .dataset("sales")
     *   .column("amount", "sum", "Total amount")
     *   .title("Total Sales")
     *   .titleVisible(true)
     *   .titlePosition("bottom")
     *   .width(250).height(200)
     *   .metric(0, 0, 0, 100000)
     *   .buildSettings());
     * 
    */ public interface MetricSettingsBuilder extends ChartSettingsBuilder { /** * Set specific the configuration parameters for this metric chart. * *

    All the reference values specified start, warning, critical, and end can be used to customize how the * metric is displayed according its current value.

    * * @return The DisplayerSettingsBuilder instance that is being used to configure a Meter data displayer. */ T metric(long start, long warning, long critical, long end); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/PieChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for pie charts * *
     *   DisplayerSettingsFactory.newPieChartSettings()
     *   .title("By Product")
     *   .column("Product")
     *   .column("Total amount")
     * 
    */ public interface PieChartSettingsBuilder extends XAxisChartSettingsBuilder { /** * Set this pie chart's subtype to a simple pie chart * @return The DisplayerSettingsBuilder instance that is being used to configure a Pie chart data displayer. */ T subType_Pie(); /** * Set this pie chart's subtype to a 3D pie chart * @return The DisplayerSettingsBuilder instance that is being used to configure a Pie chart data displayer. */ T subType_Pie_3d(); /** * Set this pie chart's subtype to a donut-like simple pie chart (i.e. a pie chart with a hole in its center) * @return The DisplayerSettingsBuilder instance that is being used to configure a Pie chart data displayer. */ T subType_Donut(); /** * Set this pie chart's subtype to a donut-like simple pie chart (i.e. a pie chart with a hole in its center) * and, in addition, with the label to assign inside the donut graph hole. * @return The DisplayerSettingsBuilder instance that is being used to configure a Pie chart data displayer. */ T subType_Donut(String holeLabel); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/Position.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /* * Generic enum for displayer element positioning purposes. */ public enum Position { BOTTOM, TOP, LEFT, RIGHT, IN; public static Position getByName(String str) { try { return valueOf(str.toUpperCase()); } catch (Exception e) { return null; } } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/SelectorDisplayerSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A displayer settings builder for selectors * *
     *   DisplayerSettingsFactory.newSelectorSettings()
     *   .dataset("products")
     *   .group("product")
     *   .count("items")
     *   .title("Product selector")
     *   .column("Product")
     *   .column("Number of items")
     * 
    */ public interface SelectorDisplayerSettingsBuilder extends DisplayerSettingsBuilder { /** * Sets the width of the selector. * @param width The width of selector. * @return The DisplayerSettingsBuilder instance that is being used to configure a selector. */ T width(int width); /** * Set the margins for this selector. * @param top The top margin. * @param bottom The bottom margin. * @param left The left margin. * @param right The right margin. * @return The DisplayerSettingsBuilder instance that is being used to configure the selector. */ T margins(int top, int bottom, int left, int right); /** * Enables or disables the selection of multiple entries * @param multiple The multiple selection flag. * @return The DisplayerSettingsBuilder instance that is being used to configure a selector. */ T multiple(boolean multiple); /** * Set this selector chart's subtype to a selector Drop Down * @return The DisplayerSettingsBuilder instance that is being used to configure a selector. */ T subType_Dropdown(); /** * Set this selector chart's subtype to a selector Slider. Used with dates and numeric values. * @return The DisplayerSettingsBuilder instance that is being used to configure a selector. */ T subType_Slider(); /** * Set this selector chart's subtype to a selector Labels. where labels will allow users to select a value * @return The DisplayerSettingsBuilder instance that is being used to configure a selector. */ T subType_Labels(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/TableDisplayerSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; import org.dashbuilder.dataset.sort.SortOrder; /** * A displayer settings builder for tables * *
     *   DisplayerSettingsFactory.newTableSettings()
     *   .title("List of Opportunities")
     *   .tablePageSize(20)
     *   .tableOrderEnabled(true)
     *   .tableOrderDefault("amount", "desc")
     *   .buildSettings()
     * 
    */ public interface TableDisplayerSettingsBuilder extends DisplayerSettingsBuilder { /** * Sets the page size (i.e. the number of rows per page) for this table displayer. * @param pageSize The page size. * @return The DisplayerSettingsBuilder instance that is being used to configure a Table data displayer. */ T tablePageSize(int pageSize); /** * If true, it enables the table columns to be ordered. * @param enabled True to enable, false to disable. * @return The DisplayerSettingsBuilder instance that is being used to configure a Table data displayer. */ T tableOrderEnabled(boolean enabled); /** * Set the default ordering column. * @param columnId The identifier of the column by which the table should by default be ordered. * @param order The sort order to apply on the specified column. * @return The DisplayerSettingsBuilder instance that is being used to configure a Table data displayer. * @see org.dashbuilder.dataset.sort.SortOrder */ T tableOrderDefault(String columnId, SortOrder order); /** * Set the default ordering column. * @param columnId The identifier of the column by which the table should by default be ordered. * @param order The sort order to apply on the specified column, as a String (accepted values are "asc" and "desc". * @return The DisplayerSettingsBuilder instance that is being used to configure a Table data displayer. */ T tableOrderDefault(String columnId, String order); /** * Set the table total width. * @param tableWidth The total table width, in pixels. * @return The DisplayerSettingsBuilder instance that is being used to configure a Table data displayer. */ T tableWidth(int tableWidth); /** * If true, it enables to show/hide the table columns by means of a column picker widget. * @param enabled True to enable, false to disable. * @return The DisplayerSettingsBuilder instance that is being used to configure a Table data displayer. */ T tableColumnPickerEnabled(boolean enabled); /** * If true, makes the table with full width and responsible * @param enabled True to enable, false to disable. * @return The DisplayerSettingsBuilder instance that is being used to configure a Table data displayer. */ T resizable(boolean enabled); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/XAxisChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer; /** * A common base interface for al charts that are axis-based. */ public interface XAxisChartSettingsBuilder extends ChartSettingsBuilder { /** * Set the X axis title. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T xAxisTitle(String title); /** * Set the X axis labels display angle (from 0 to 360). * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T xAxisAngle(int angle); /** * Set the Y axis title. * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T yAxisTitle(String title); /** * Set if the Y axis labels should be displayed * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T yAxisShowLabels(boolean axisShowLabels); /** * Set if the X axis labels should be displayed * @return The DisplayerSettingsBuilder instance that is being used to configure a DisplayerSettings. */ T xAxisShowLabels(boolean axisShowLabels); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalColumn.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class ExternalColumn { @JsProperty String name; @JsProperty String type; ExternalColumnSettings settings; @JsOverlay public static ExternalColumn of(String name, String type, ExternalColumnSettings settings) { ExternalColumn column = new ExternalColumn(); column.name = name; column.type = type; column.settings = settings; return column; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalColumnSettings.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class ExternalColumnSettings { @JsProperty String columnId; @JsProperty String columnName; @JsProperty String valueExpression; @JsProperty String emptyTemplate; @JsProperty String valuePattern; @JsOverlay public static ExternalColumnSettings of(String columnId, String columnName, String valueExpression, String emptyTemplate, String valuePattern) { ExternalColumnSettings settings = new ExternalColumnSettings(); settings.columnId = columnId; settings.columnName = columnName; settings.valueExpression = valueExpression; settings.emptyTemplate = emptyTemplate; settings.valuePattern = valuePattern; return settings; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalComponentFunction.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import java.util.Map; import java.util.function.Consumer; public interface ExternalComponentFunction { default String getName() { return this.getClass().getSimpleName(); } void exec(Map params, Consumer onFinish, Consumer onError); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalComponentMessage.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import java.util.Map; import elemental2.core.JsMap; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class ExternalComponentMessage { JsMap properties; // Change this when @JsEnum is supported. String type; @JsOverlay static ExternalComponentMessage create(String messageType, Map properties) { ExternalComponentMessage message = new ExternalComponentMessage(); message.properties = new JsMap<>(); message.type = messageType; properties.forEach(message::setProperty); return message; } @JsOverlay public final void setProperty(String key, Object value) { properties.set(key, value); } @JsOverlay public final Object getProperty(String key) { return properties != null ? properties.get(key) : null; } @JsOverlay public final String getType() { return type; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalComponentMessageHelper.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import java.util.Collections; import java.util.Map; import java.util.Optional; import jsinterop.base.Js; /** * Helper to deal with External Component Messages. * */ public class ExternalComponentMessageHelper { /** * Message when a requested function is not found */ public static final String FUNCTION_NOT_FOUND = "Function not found."; /** * Message when a function is executed with success */ public static final String FUNCTION_CALL_SUCESS = "Function called with success"; /** * Message when a message is of type FUNCTION_CALL, but the request to call the function is not found. */ public static final String FUNCTION_CALL_REQUEST_NOT_FOUND = "You must provide a function request to call a function."; /** * Default message when there was an error executing the function. */ public static final String FUNCTION_EXECUTION_ERROR_FOUND = "There was an error executing the function"; /** * The property that should be used by components to find its unique ID during Runtime. */ static final String COMPONENT_RUNTIME_ID_PROP = "component_id"; /** * Inbound property to define the dataset to be consumed by components. */ static final String DATA_SET_PROP = "dataSet"; /** * Outbound property to define the filter request. Should be used with messages of type Filter Request. */ static final String FILTER_PROP = "filter"; /** * Outbound property to define the name of a function to be invoked. */ static final String FUNCTION_CALL_PROP = "functionCallRequest"; /** * Inbound property to define the result of a function call. */ static final String FUNCTION_RESPONSE_PROP = "functionResponse"; /** * Inbound property to define the result of a function call. */ static final String CONFIGURATION_ISSUE_PROP = "configurationIssue"; /** * Extract filter request from messages coming from the component. * * @param message * The message sent by the component. * @return * An optional containing the filter extracted from the message. */ public Optional filterRequest(ExternalComponentMessage message) { Object filterProp = message.getProperty(FILTER_PROP); if (filterProp != null) { ExternalFilterRequest filterRequest = Js.cast(filterProp); return Optional.ofNullable(filterRequest); } return Optional.empty(); } /** * * Retrieves a function call object from a message. * * @param message */ public Optional functionCallRequest(ExternalComponentMessage message) { Object functionCallObj = message.getProperty(FUNCTION_CALL_PROP); if (functionCallObj != null) { FunctionCallRequest functionCallRequest = Js.cast(functionCallObj); return Optional.ofNullable(functionCallRequest); } return Optional.empty(); } /** * Builds a message that contains dataset and component properties. * @param ds * The dataset that will be sent to client * @param componentProperties * All the component properties * @return * The message ready to be sent to the user. */ public ExternalComponentMessage newDataSetMessage(ExternalDataSet ds, Map componentProperties) { ExternalComponentMessage message = ExternalComponentMessage.create(ExternalComponentMessageType.DATASET.name(), componentProperties); message.setProperty(DATA_SET_PROP, ds); return message; } /** * Creates a message of type INIT, which is the first message sent to the component. * @param componentProperties * The initial properties. * @return * The message ready to be sent. */ public ExternalComponentMessage newInitMessage(Map componentProperties) { return ExternalComponentMessage.create(ExternalComponentMessageType.INIT.name(), componentProperties); } public ExternalComponentMessage newFunctionError(FunctionCallRequest functionCallRequest, String errorMessage) { Map props = Collections.singletonMap(FUNCTION_RESPONSE_PROP, FunctionResponse.create(functionCallRequest, FunctionResultType.ERROR.name(), FUNCTION_EXECUTION_ERROR_FOUND, errorMessage)); return ExternalComponentMessage.create(ExternalComponentMessageType.FUNCTION_RESPONSE.name(), props); } /** * * Produces a message to respond function call requests here the function could not be found. * @param functionCallRequest * @return */ public ExternalComponentMessage newFunctionNotFound(FunctionCallRequest functionCallRequest) { Map props = Collections.singletonMap(FUNCTION_RESPONSE_PROP, FunctionResponse.create(functionCallRequest, FunctionResultType.NOT_FOUND.name(), FUNCTION_NOT_FOUND, null)); return ExternalComponentMessage.create(ExternalComponentMessageType.FUNCTION_RESPONSE.name(), props); } /** * Generate messages for function call message types that does not specify a function call request. * @return */ public ExternalComponentMessage newFunctionRequestNotFound() { Map props = Collections.singletonMap(FUNCTION_RESPONSE_PROP, FunctionResponse.create(null, FunctionResultType.ERROR.name(), FUNCTION_CALL_REQUEST_NOT_FOUND, null)); return ExternalComponentMessage.create(ExternalComponentMessageType.FUNCTION_RESPONSE.name(), props); } /** * * Messages to sent when a function is called with success * * @param functionCallRequest * @param result * The function execution result. * @return */ public ExternalComponentMessage newFunctionSuccess(FunctionCallRequest functionCallRequest, Object result) { Map props = Collections.singletonMap(FUNCTION_RESPONSE_PROP, FunctionResponse.create(functionCallRequest, FunctionResultType.SUCCESS.name(), FUNCTION_CALL_SUCESS, result)); return ExternalComponentMessage.create(ExternalComponentMessageType.FUNCTION_RESPONSE.name(), props); } /** * * Add the component runtime ID to a message * @param message * The message which the ID should be set * @param componentId * The component unique ID. It should be used by components to send messages to DB. */ public void withId(ExternalComponentMessage message, String componentId) { message.setProperty(COMPONENT_RUNTIME_ID_PROP, componentId); } /** * Extract the component Id from a message. * @param message * The target message to have the component id removed. * @return * An optional containing the component id. */ public Optional getComponentId(ExternalComponentMessage message) { return getValue(COMPONENT_RUNTIME_ID_PROP, message); } public Optional getConfigurationIssue(ExternalComponentMessage message) { return getValue(CONFIGURATION_ISSUE_PROP, message); } /** * * Check if the given message is an INIT message. * @param message * The message to be checked. * @return * true if it is a message of type INIT. */ public boolean isInit(ExternalComponentMessage message) { String type = verifyTypeNotNull(message); return ExternalComponentMessageType.INIT.name().equals(type); } public ExternalComponentMessageType messageType(ExternalComponentMessage message) { String type = verifyTypeNotNull(message); return ExternalComponentMessageType.valueOf(type); } private String verifyTypeNotNull(ExternalComponentMessage message) { String type = message.getType(); if (type == null) { throw new IllegalArgumentException("Message type cannot be null."); } return type; } private Optional getValue(String valueKey, ExternalComponentMessage message) { Object valueObj = message.getProperty(valueKey); if (valueObj != null) { String componentId = valueObj.toString(); return Optional.ofNullable(componentId); } return Optional.empty(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalComponentMessageType.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; /** * External Component Message types * */ public enum ExternalComponentMessageType { // DB Sent messages FUNCTION_RESPONSE, DATASET, INIT, // Component Sent messages FUNCTION_CALL, FILTER, FIX_CONFIGURATION, CONFIGURATION_OK, READY; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalDataSet.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import elemental2.core.JsArray; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; /** * DataSet representation for external Components. * */ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class ExternalDataSet { @JsProperty JsArray columns; @JsProperty JsArray> data; @JsOverlay public static ExternalDataSet of(ExternalColumn[] columns, String[][] data) { ExternalDataSet ds = new ExternalDataSet(); ds.columns = new JsArray<>(); ds.data = new JsArray<>(); for(ExternalColumn column : columns) { ds.columns.push(column); } for (String[] line: data) { JsArray lineArray = new JsArray<>(); for (String v : line) { lineArray.push(v); } ds.data.push(lineArray); } return ds; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/ExternalFilterRequest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class ExternalFilterRequest { @JsProperty public native boolean isReset(); @JsProperty public native int getRow(); @JsProperty public native int getColumn(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/FunctionCallRequest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import elemental2.core.JsMap; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class FunctionCallRequest { @JsProperty public native String getFunctionName(); @JsProperty public native JsMap getParameters(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/FunctionResponse.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class FunctionResponse { FunctionCallRequest request; String resultType; String message; Object result; @JsOverlay public static FunctionResponse create(FunctionCallRequest request, String resultType, String message, Object result) { FunctionResponse response = new FunctionResponse(); response.request = request; response.resultType = resultType; response.message = message; response.result = result; return response; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/external/FunctionResultType.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; /** * Values for a function result. * */ public enum FunctionResultType { /** * Used when a function is successfully invoked. */ SUCCESS, /** * Some error happened when executing the function. */ ERROR, /** * The function was not found. */ NOT_FOUND; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/AbstractChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.ChartSettingsBuilder; import org.dashbuilder.displayer.Position; public abstract class AbstractChartSettingsBuilder extends AbstractDisplayerSettingsBuilder implements ChartSettingsBuilder { public T width(int width) { displayerSettings.setChartWidth( width ); return (T) this; } public T height(int height) { displayerSettings.setChartHeight( height ); return (T) this; } public T margins(int top, int bottom, int left, int right) { displayerSettings.setChartMarginTop(top); displayerSettings.setChartMarginBottom(bottom); displayerSettings.setChartMarginLeft(left); displayerSettings.setChartMarginRight(right); return (T) this; } public T legendOff() { displayerSettings.setChartShowLegend(false); return (T) this; } public T legendOn(Position position) { return legendOn(position.name()); } public T legendOn(String position) { displayerSettings.setChartShowLegend(true); displayerSettings.setChartLegendPosition(Position.getByName(position)); return (T) this; } public T resizableOn(int maxWidth, int maxHeight) { displayerSettings.setResizable(true); displayerSettings.setChartMaxWidth(maxWidth); displayerSettings.setChartMaxHeight(maxHeight); return (T) this; } public T resizableOff() { displayerSettings.setResizable(false); return (T) this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/AbstractDisplayerSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import java.util.List; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetOp; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.dataset.impl.AbstractDataSetLookupBuilder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsBuilder; import org.dashbuilder.displayer.DisplayerSubType; /** * Base class for DisplayerSettingsBuilder implementations. */ public abstract class AbstractDisplayerSettingsBuilder extends AbstractDataSetLookupBuilder implements DisplayerSettingsBuilder { protected DisplayerSettings displayerSettings = createDisplayerSettings(); protected abstract DisplayerSettings createDisplayerSettings(); public T uuid(String uuid) { displayerSettings.setUUID(uuid); return (T) this; } public T dataset(DataSet dataSet) { displayerSettings.setDataSet(dataSet); return (T) this; } public T title(String title) { displayerSettings.setTitle(title); return (T) this; } public T titleVisible(boolean visible) { displayerSettings.setTitleVisible(visible); return (T) this; } public T allowCsvExport(boolean allowCsvExport) { displayerSettings.setCSVExportAllowed(allowCsvExport); return (T) this; } public T allowExcelExport(boolean allowExcelExport) { displayerSettings.setExcelExportAllowed(allowExcelExport); return (T) this; } public T backgroundColor(String backgroundColor) { displayerSettings.setChartBackgroundColor(backgroundColor); return (T) this; } public T xAxisTitle(String title) { displayerSettings.setXAxisShowLabels(true); displayerSettings.setXAxisTitle(title); return (T) this; } public T xAxisAngle(int angle) { displayerSettings.setXAxisLabelsAngle(angle); return (T) this; } public T yAxisTitle(String title) { displayerSettings.setYAxisShowLabels(true); displayerSettings.setYAxisTitle(title); return (T) this; } public T yAxisShowLabels(boolean show) { displayerSettings.setYAxisShowLabels(show); return (T) this; } public T xAxisShowLabels(boolean show) { displayerSettings.setXAxisShowLabels(show); return (T) this; } public T renderer(String renderer) { displayerSettings.setRenderer(renderer); return (T) this; } @Override public T subtype(DisplayerSubType displayerSubType) { displayerSettings.setSubtype(displayerSubType); return (T) this; } public T filterOn(boolean applySelf, boolean notifyOthers, boolean receiveFromOthers) { displayerSettings.setFilterEnabled(true); displayerSettings.setFilterSelfApplyEnabled(applySelf); displayerSettings.setFilterNotificationEnabled(notifyOthers); displayerSettings.setFilterListeningEnabled(receiveFromOthers); return (T) this; } public T filterOff(boolean receiveFromOthers) { displayerSettings.setFilterEnabled(false); displayerSettings.setFilterListeningEnabled(receiveFromOthers); return (T) this; } public T refreshOn() { displayerSettings.setRefreshInterval(-1); displayerSettings.setRefreshStaleData(true); return (T) this; } public T refreshOn(int seconds, boolean staleData) { displayerSettings.setRefreshInterval(seconds); displayerSettings.setRefreshStaleData(staleData); return (T) this; } public T refreshOff() { displayerSettings.setRefreshInterval(-1); return (T) this; } public T format(String name) { return format(name, null); } public T format(String name, String pattern) { DataSetOp op = getCurrentOp(); if (op == null || !(op instanceof DataSetGroup)) { throw new RuntimeException("column(...) must be called first."); } DataSetGroup gOp = (DataSetGroup) getCurrentOp(); List columns = gOp.getGroupFunctions(); if (columns.isEmpty()) { throw new RuntimeException("column(...) must be called first."); } GroupFunction lastColumn = columns.get(columns.size() - 1); return format(lastColumn.getColumnId(), name, pattern); } public T format(String columnId, String name, String pattern) { displayerSettings.setColumnName(columnId, name); displayerSettings.setColumnValuePattern(columnId, pattern); return (T) this; } public T expression(String expression) { DataSetOp op = getCurrentOp(); if (op == null || !(op instanceof DataSetGroup)) { throw new RuntimeException("column(...) must be called first."); } DataSetGroup gOp = (DataSetGroup) getCurrentOp(); List columns = gOp.getGroupFunctions(); if (columns.isEmpty()) { throw new RuntimeException("column(...) must be called first."); } GroupFunction lastColumn = columns.get(columns.size() - 1); return expression(lastColumn.getColumnId(), expression); } public T expression(String columnId, String expression) { displayerSettings.setColumnValueExpression(columnId, expression); return (T) this; } public T htmlTemplate(String html) { displayerSettings.setHtmlTemplate(html); return (T) this; } public T jsTemplate(String onDrawJs) { displayerSettings.setJsTemplate(onDrawJs); return (T) this; } public DisplayerSettings buildSettings() { displayerSettings.setDataSetLookup(super.buildLookup()); return displayerSettings; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/AbstractSelectorSettingsBuilder.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.SelectorDisplayerSettingsBuilder; public abstract class AbstractSelectorSettingsBuilder extends AbstractDisplayerSettingsBuilder implements SelectorDisplayerSettingsBuilder { @Override public T width(int width) { displayerSettings.setSelectorWidth(width); return (T) this; } @Override public T margins(int top, int bottom, int left, int right) { displayerSettings.setChartMarginTop(top); displayerSettings.setChartMarginBottom(bottom); displayerSettings.setChartMarginLeft(left); displayerSettings.setChartMarginRight(right); return (T) this; } @Override public T multiple(boolean multiple) { displayerSettings.setSelectorMultiple(multiple); return (T) this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/AbstractXAxisChartSettingsBuilder.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.XAxisChartSettingsBuilder; public abstract class AbstractXAxisChartSettingsBuilder extends AbstractChartSettingsBuilder { } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/AreaChartSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.AreaChartSettingsBuilder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; public class AreaChartSettingsBuilderImpl extends AbstractXAxisChartSettingsBuilder implements AreaChartSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.AREACHART, DisplayerSubType.AREA); } @Override public AreaChartSettingsBuilderImpl subType_Area() { displayerSettings.setSubtype(DisplayerSubType.AREA); return this; } @Override public AreaChartSettingsBuilderImpl subType_StackedArea() { displayerSettings.setSubtype(DisplayerSubType.AREA_STACKED); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/BarChartSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.BarChartSettingsBuilder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; public class BarChartSettingsBuilderImpl extends AbstractXAxisChartSettingsBuilder implements BarChartSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.BARCHART, DisplayerSubType.BAR); } public BarChartSettingsBuilderImpl set3d(boolean b) { displayerSettings.setChart3D(b); return this; } @Override public BarChartSettingsBuilderImpl subType_Bar() { displayerSettings.setSubtype(DisplayerSubType.BAR); return this; } @Override public BarChartSettingsBuilderImpl subType_StackedBar() { displayerSettings.setSubtype(DisplayerSubType.BAR_STACKED); return this; } @Override public BarChartSettingsBuilderImpl subType_Column() { displayerSettings.setSubtype(DisplayerSubType.COLUMN); return this; } @Override public BarChartSettingsBuilderImpl subType_StackedColumn() { displayerSettings.setSubtype(DisplayerSubType.COLUMN_STACKED); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/BubbleChartSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.BubbleChartSettingsBuilder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; public class BubbleChartSettingsBuilderImpl extends AbstractChartSettingsBuilder implements BubbleChartSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings( DisplayerType.BUBBLECHART ); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/ExternalDisplayerSettingsBuilderImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.ExternalDisplayerSettingsBuilder; public class ExternalDisplayerSettingsBuilderImpl extends AbstractChartSettingsBuilder implements ExternalDisplayerSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.EXTERNAL_COMPONENT); } @Override public ExternalDisplayerSettingsBuilderImpl componentId(String id) { this.displayerSettings.setComponentId(id); return this; } @Override public ExternalDisplayerSettingsBuilderImpl componentProperty(String key, String value) { this.displayerSettings.setComponentProperty(key, value); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/LineChartSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.LineChartSettingsBuilder; import org.dashbuilder.displayer.DisplayerSettings; public class LineChartSettingsBuilderImpl extends AbstractXAxisChartSettingsBuilder implements LineChartSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.LINECHART, DisplayerSubType.LINE); } @Override public LineChartSettingsBuilderImpl subType_Line() { displayerSettings.setSubtype(DisplayerSubType.LINE); return this; } @Override public LineChartSettingsBuilderImpl subType_SmoothLine() { displayerSettings.setSubtype(DisplayerSubType.SMOOTH); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/MapChartSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.MapChartSettingsBuilder; import org.dashbuilder.displayer.MapColorScheme; public class MapChartSettingsBuilderImpl extends AbstractXAxisChartSettingsBuilder implements MapChartSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.MAP, DisplayerSubType.MAP_REGIONS); } @Override public MapChartSettingsBuilderImpl subType_Region_Map() { displayerSettings.setSubtype(DisplayerSubType.MAP_REGIONS); return this; } @Override public MapChartSettingsBuilderImpl subType_Marker_Map() { displayerSettings.setSubtype(DisplayerSubType.MAP_MARKERS); return this; } @Override public MapChartSettingsBuilderImpl colorScheme(MapColorScheme colorScheme) { displayerSettings.setMapColorScheme(colorScheme); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/MeterChartSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.MeterChartSettingsBuilder; public class MeterChartSettingsBuilderImpl extends AbstractChartSettingsBuilder implements MeterChartSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings( DisplayerType.METERCHART ); } public MeterChartSettingsBuilderImpl meter(long start, long warning, long critical, long end) { displayerSettings.setMeterStart(start); displayerSettings.setMeterWarning(warning); displayerSettings.setMeterCritical(critical); displayerSettings.setMeterEnd(end); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/MetricSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.MetricSettingsBuilder; public class MetricSettingsBuilderImpl extends AbstractChartSettingsBuilder implements MetricSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings( DisplayerType.METRIC ); } public MetricSettingsBuilderImpl metric(long start, long warning, long critical, long end) { displayerSettings.setMeterStart(start); displayerSettings.setMeterWarning(warning); displayerSettings.setMeterCritical(critical); displayerSettings.setMeterEnd(end); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/PieChartSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.PieChartSettingsBuilder; public class PieChartSettingsBuilderImpl extends AbstractXAxisChartSettingsBuilder implements PieChartSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.PIECHART, DisplayerSubType.PIE); } public PieChartSettingsBuilderImpl set3d(boolean b) { displayerSettings.setChart3D(b); return this; } @Override public PieChartSettingsBuilderImpl subType_Pie() { displayerSettings.setSubtype(DisplayerSubType.PIE); return this; } @Override public PieChartSettingsBuilderImpl subType_Pie_3d() { displayerSettings.setSubtype(DisplayerSubType.PIE_3D); return this; } @Override public PieChartSettingsBuilderImpl subType_Donut() { displayerSettings.setSubtype(DisplayerSubType.DONUT); return this; } @Override public PieChartSettingsBuilderImpl subType_Donut(String holeLabel) { displayerSettings.setSubtype(DisplayerSubType.DONUT); displayerSettings.setDonutHoleTitle(holeLabel); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/SelectorDisplayerSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.SelectorDisplayerSettingsBuilder; public class SelectorDisplayerSettingsBuilderImpl extends AbstractSelectorSettingsBuilder implements SelectorDisplayerSettingsBuilder { protected DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.SELECTOR, DisplayerSubType.SELECTOR_DROPDOWN); } @Override public SelectorDisplayerSettingsBuilderImpl subType_Dropdown() { displayerSettings.setSubtype(DisplayerSubType.SELECTOR_DROPDOWN); return this; } @Override public SelectorDisplayerSettingsBuilderImpl subType_Slider() { displayerSettings.setSubtype(DisplayerSubType.SELECTOR_SLIDER); return this; } @Override public SelectorDisplayerSettingsBuilderImpl subType_Labels() { displayerSettings.setSubtype(DisplayerSubType.SELECTOR_LABELS); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/impl/TableDisplayerSettingsBuilderImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.impl; import org.dashbuilder.dataset.sort.SortOrder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.TableDisplayerSettingsBuilder; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class TableDisplayerSettingsBuilderImpl extends AbstractDisplayerSettingsBuilder implements TableDisplayerSettingsBuilder { public DisplayerSettings createDisplayerSettings() { return new DisplayerSettings(DisplayerType.TABLE); } public TableDisplayerSettingsBuilderImpl tablePageSize(int pageSize) { displayerSettings.setTablePageSize(pageSize); return this; } public TableDisplayerSettingsBuilderImpl tableOrderEnabled(boolean enabled) { displayerSettings.setTableSortEnabled(enabled); return this; } public TableDisplayerSettingsBuilderImpl tableOrderDefault(String columnId, SortOrder order) { displayerSettings.setTableDefaultSortColumnId(columnId); displayerSettings.setTableDefaultSortOrder(order); return this; } public TableDisplayerSettingsBuilderImpl tableOrderDefault(String columnId, String order) { return tableOrderDefault(columnId, SortOrder.getByName(order)); } public TableDisplayerSettingsBuilderImpl tableWidth(int tableWidth) { displayerSettings.setTableWidth(tableWidth); return this; } public TableDisplayerSettingsBuilderImpl tableColumnPickerEnabled(boolean enabled) { displayerSettings.setTableColumnPickerEnabled(enabled); return this; } @Override public TableDisplayerSettingsBuilderImpl resizable(boolean resizable) { displayerSettings.setResizable(resizable); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/displayer/json/DisplayerSettingsJSONMarshaller.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.json; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.json.DataSetJSONMarshaller; import org.dashbuilder.dataset.json.DataSetLookupJSONMarshaller; import org.dashbuilder.displayer.ColumnSettings; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.json.Json; import org.dashbuilder.json.JsonArray; import org.dashbuilder.json.JsonObject; import org.dashbuilder.json.JsonString; import org.dashbuilder.json.JsonValue; public class DisplayerSettingsJSONMarshaller { private static final String DATASET_PREFIX = "dataSet"; private static final String DATASET_LOOKUP_PREFIX = "dataSetLookup"; private static final String COLUMNS_PREFIX = "columns"; private static final String COLUMN_ID = "id"; private static final String COLUMN_NAME = "name"; private static final String COLUMN_EXPRESSION = "expression"; private static final String COLUMN_PATTERN = "pattern"; private static final String COLUMN_EMPTY = "empty"; private static final String SETTINGS_UUID = "uuid"; private static DisplayerSettingsJSONMarshaller SINGLETON = new DisplayerSettingsJSONMarshaller(); public static DisplayerSettingsJSONMarshaller get() { return SINGLETON; } private DataSetJSONMarshaller dataSetJsonMarshaller; private DataSetLookupJSONMarshaller dataSetLookupJsonMarshaller; public DisplayerSettingsJSONMarshaller() { this(DataSetJSONMarshaller.get(), DataSetLookupJSONMarshaller.get()); } public DisplayerSettingsJSONMarshaller(DataSetJSONMarshaller dataSetJsonMarshaller, DataSetLookupJSONMarshaller dataSetLookupJsonMarshaller) { this.dataSetJsonMarshaller = dataSetJsonMarshaller; this.dataSetLookupJsonMarshaller = dataSetLookupJsonMarshaller; } public DisplayerSettings fromJsonString( String jsonString ) { DisplayerSettings ds = new DisplayerSettings(); if (!isBlank(jsonString)) { JsonObject parseResult = Json.parse(jsonString); if ( parseResult != null ) { // UUID ds.setUUID(parseResult.getString(SETTINGS_UUID)); parseResult.put(SETTINGS_UUID, (String) null); // First look if a dataset 'on-the-fly' has been specified JsonObject data = parseResult.getObject(DATASET_PREFIX); if (data != null) { DataSet dataSet = dataSetJsonMarshaller.fromJson(data); ds.setDataSet(dataSet); // Remove from the json input so that it doesn't end up in the settings map. parseResult.put(DATASET_PREFIX, (JsonValue) null); // If none was found, look for a dataset lookup definition } else if ((data = parseResult.getObject(DATASET_LOOKUP_PREFIX)) != null) { DataSetLookup dataSetLookup = dataSetLookupJsonMarshaller.fromJson(data); ds.setDataSetLookup(dataSetLookup); // Remove from the json input so that it doesn't end up in the settings map. parseResult.put(DATASET_LOOKUP_PREFIX, (JsonValue) null); } else { throw new RuntimeException("Displayer settings dataset lookup not specified"); } // Parse the columns settings JsonArray columns = parseResult.getArray(COLUMNS_PREFIX); if (columns != null) { List columnSettingsList = parseColumnsFromJson(columns); ds.setColumnSettingsList(columnSettingsList); // Remove from the json input so that it doesn't end up in the settings map. parseResult.put(COLUMNS_PREFIX, (JsonValue) null); } // Now parse all other settings ds.setSettingsFlatMap( parseSettingsFromJson(parseResult)); } } return ds; } public String toJsonString(DisplayerSettings displayerSettings) { return toJsonObject(displayerSettings).toString(); } public JsonObject toJsonObject( DisplayerSettings displayerSettings ) { JsonObject json = Json.createObject(); // UUID json.put(SETTINGS_UUID, displayerSettings.getUUID()); for (Map.Entry entry : displayerSettings.getSettingsFlatMap().entrySet()) { setNodeValue(json, entry.getKey(), entry.getValue()); } // Data set DataSetLookup dataSetLookup = displayerSettings.getDataSetLookup(); DataSet dataSet = displayerSettings.getDataSet(); if (dataSet != null) { json.put(DATASET_PREFIX, dataSetJsonMarshaller.toJson(dataSet)); } else if (dataSetLookup != null) { json.put(DATASET_LOOKUP_PREFIX, dataSetLookupJsonMarshaller.toJson(dataSetLookup)); } else { throw new RuntimeException("Displayer settings data set lookup not specified or data set is empty."); } // Column settings List columnSettingsList = displayerSettings.getColumnSettingsList(); if (!columnSettingsList.isEmpty()) { json.put(COLUMNS_PREFIX, formatColumnSettings(columnSettingsList)); } return json; } private void setNodeValue(JsonObject node, String path, String value) { if (node == null || isBlank(path) || value == null) { return; } int separatorIndex = path.lastIndexOf('.'); String nodesPath = separatorIndex > 0 ? path.substring(0, separatorIndex) : ""; String leaf = separatorIndex > 0 ? path.substring(separatorIndex + 1) : path; JsonObject _node = findNode(node, nodesPath, true); _node.put(leaf, value); } private JsonObject findNode(JsonObject parent, String path, boolean createPath) { if (parent == null) { return null; } if (isBlank(path)) { return parent; } int separatorIndex = path.indexOf('.'); String strChildNode = separatorIndex > 0 ? path.substring(0, separatorIndex) : path; String remainingNodes = separatorIndex > 0 ? path.substring(separatorIndex + 1) : ""; JsonObject childNode = parent.getObject(strChildNode); if (childNode == null && createPath) { childNode = Json.createObject(); parent.put(strChildNode, childNode); } return findNode(childNode, remainingNodes, createPath); } private JsonArray formatColumnSettings(List columnSettingsList) { JsonArray jsonArray = Json.createArray(); for (int i=0; i parseColumnsFromJson(JsonArray columnsJsonArray) { List columnSettingsList = new ArrayList(); if (columnsJsonArray == null) { return columnSettingsList; } for (int i = 0; i < columnsJsonArray.length(); i++) { JsonObject columnJson = columnsJsonArray.getObject(i); ColumnSettings columnSettings = new ColumnSettings(); columnSettingsList.add(columnSettings); String columndId = columnJson.getString(COLUMN_ID); if (columndId == null) { throw new RuntimeException("Column settings null column id"); } columnSettings.setColumnId(columndId); columnSettings.setColumnName(columnJson.getString(COLUMN_NAME)); columnSettings.setValueExpression(columnJson.getString(COLUMN_EXPRESSION)); columnSettings.setValuePattern(columnJson.getString(COLUMN_PATTERN)); columnSettings.setEmptyTemplate(columnJson.getString(COLUMN_EMPTY)); } return columnSettingsList; } private Map parseSettingsFromJson(JsonObject settingsJson) { Map flatSettingsMap = new HashMap(30); if (settingsJson != null && settingsJson.size() > 0) { fillRecursive("", settingsJson, flatSettingsMap); } return flatSettingsMap; } private void fillRecursive(String parentPath, JsonObject json, Map settings) { String sb = isBlank(parentPath) ? "" : parentPath + "."; for (String key : json.keys()) { String path = sb + key; JsonValue value = json.get( key ); if (value instanceof JsonObject) { fillRecursive(path, (JsonObject) value, settings); } else if (value instanceof JsonString) { settings.put(path, ((JsonString) value).getString()); } } } private boolean isBlank(String str) { return str == null || str.trim().isEmpty(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/java/org/dashbuilder/renderer/RendererSettings.java ================================================ package org.dashbuilder.renderer; import org.jboss.errai.common.client.api.annotations.Portable; /** * Hold Renderer Settings. * */ @Portable public class RendererSettings { private final String defaultRenderer; private final boolean offline; public RendererSettings() { this.defaultRenderer = ""; this.offline = false; } public RendererSettings(String defaultRenderer, boolean offline) { this.defaultRenderer = defaultRenderer; this.offline = offline; } /** * The UUID of the renderer that should be used by default.
    * It can be set using org.dashbuilder.renderer.default. * * @return The selected default renderer UUID */ public String getDefaultRenderer() { return defaultRenderer; } /** * When true renderers that can't work offline are discarded.
    * It can be set org.dashbuilder.renderer.offline. * * @return The offline flag value */ public boolean isOffline() { return offline; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/main/resources/org/dashbuilder/DisplayerAPI.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/test/java/org/dashbuilder/displayer/external/ExternalComponentMessageHelperTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.external; import java.util.Collections; import java.util.Optional; import com.google.gwtmockito.GwtMockitoTestRunner; import elemental2.core.JsMap; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import static org.dashbuilder.displayer.external.ExternalComponentMessageHelper.COMPONENT_RUNTIME_ID_PROP; import static org.dashbuilder.displayer.external.ExternalComponentMessageHelper.FILTER_PROP; import static org.dashbuilder.displayer.external.ExternalComponentMessageType.DATASET; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(GwtMockitoTestRunner.class) public class ExternalComponentMessageHelperTest { @Mock JsMap properties; @InjectMocks ExternalComponentMessage message; static private ExternalComponentMessageHelper helper; @BeforeClass public static void setup() { helper = new ExternalComponentMessageHelper(); } @Test public void testWithId() { String id = "abc"; helper.withId(message, id); verify(properties).set(eq(COMPONENT_RUNTIME_ID_PROP), eq(id)); } @Test public void testFilterRequest() { Optional filterRequestOp = helper.filterRequest(message); assertFalse(filterRequestOp.isPresent()); ExternalFilterRequest request = mock(ExternalFilterRequest.class); when(properties.get(eq(FILTER_PROP))).thenReturn(request); filterRequestOp = helper.filterRequest(message); assertEquals(request, filterRequestOp.get()); } @Test public void testFunctionCallRequest() { Optional functionCallRequestOp = helper.functionCallRequest(message); assertFalse(functionCallRequestOp.isPresent()); FunctionCallRequest request = mock(FunctionCallRequest.class); when(properties.get(eq(ExternalComponentMessageHelper.FUNCTION_CALL_PROP))).thenReturn(request); functionCallRequestOp = helper.functionCallRequest(message); assertEquals(request, functionCallRequestOp.get()); } @Test public void testDataSetMessage() { ExternalDataSet ds = mock(ExternalDataSet.class); ExternalComponentMessage newDataSetMessage = helper.newDataSetMessage(ds, Collections.emptyMap()); assertEquals(DATASET.name(), newDataSetMessage.type); } @Test public void testNewInitMessage() { ExternalComponentMessage initMessage = helper.newInitMessage(Collections.emptyMap()); assertEquals(ExternalComponentMessageType.INIT.name(), initMessage.type); } @Test(expected = IllegalArgumentException.class) public void testNullMessageType() { ExternalComponentMessage message = mock(ExternalComponentMessage.class); when(message.getType()).thenReturn(null); helper.messageType(message); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-displayer-api/src/test/java/org/dashbuilder/displayer/json/DisplayerSettingsJsonTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.displayer.json; import java.util.Arrays; import java.util.Collection; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.json.JsonObject; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import static org.junit.Assert.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.dashbuilder.dataset.sort.SortOrder.DESCENDING; @RunWith(Parameterized.class) public class DisplayerSettingsJsonTest { public static final DisplayerSettings OPPS_BY_PIPELINE = DisplayerSettingsFactory.newPieChartSettings() .uuid("opps-by-pipeline") .dataset("SALES_OPPS") .group("PIPELINE") .column("PIPELINE", "Pipeline") .column(COUNT, "Number of opps") .title("salesopps_displayers_by_pipeline_title") .titleVisible(false) .width(500).height(300) .margins(10, 10, 10, 10) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_STATUS = DisplayerSettingsFactory.newPieChartSettings() .uuid("opps-by-status") .dataset("SALES_OPPS") .group("STATUS") .column("STATUS", "Status") .column("AMOUNT", SUM, "Total amount") .title("salesopps_displayers_by_status_title") .titleVisible(false) .margins(10, 10, 10, 10) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_SALESMAN = DisplayerSettingsFactory.newPieChartSettings() .uuid("opps-by-salesman") .dataset("SALES_OPPS") .group("SALES_PERSON") .column("SALES_PERSON", "Sales person") .column("AMOUNT", SUM, "Total amount") .title("salesopps_displayers_by_salesman_title") .titleVisible(false) .margins(10, 10, 10, 10) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_EXPECTED_PIPELINE = DisplayerSettingsFactory.newAreaChartSettings() .uuid("opps-expected-pipeline") .dataset("SALES_OPPS") .group("CLOSING_DATE").dynamic(24, DateIntervalType.MONTH, true) .column("CLOSING_DATE", "Closing date") .column("EXPECTED_AMOUNT", SUM, "salesopps_displayers_by_exp_pipeline_column1") .title("salesopps_displayers_by_exp_pipeline_title") .titleVisible(false) .width(500).height(300) .margins(20, 50, 100, 100) .filterOn(true, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_PRODUCT = DisplayerSettingsFactory.newBarChartSettings() .subType_Bar() .uuid("opps-by-product") .dataset("SALES_OPPS") .group("PRODUCT") .column("PRODUCT", "Product") .column("AMOUNT", SUM, "salesopps_displayers_by_product_column1") .title("salesopps_displayers_by_product_title") .titleVisible(false) .margins(10, 50, 100, 100) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_COUNTRY = DisplayerSettingsFactory.newBarChartSettings() .subType_Bar() .uuid("opps-by-country") .dataset("SALES_OPPS") .group("COUNTRY") .column("COUNTRY", "Country") .column("AMOUNT", SUM, "alesopps_displayers_by_country_column1") .title("salesopps_displayers_by_country_title") .titleVisible(false) .margins(10, 80, 100, 100) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_COUNTRY_SUMMARY = DisplayerSettingsFactory.newTableSettings() .uuid("opps-country-summary") .dataset("SALES_OPPS") .group("COUNTRY") .column("COUNTRY", "salesopps_displayers_country_summary_column1") .column("AMOUNT", SUM, "salesopps_displayers_country_summary_column2") .column(COUNT, "salesopps_displayers_country_summary_column3") .column("AMOUNT", AVERAGE, "salesopps_displayers_country_summary_column4") .column("AMOUNT", MIN, "salesopps_displayers_country_summary_column5") .column("AMOUNT", MAX, "salesopps_displayers_country_summary_column6") .title("salesopps_displayers_country_summary_title") .titleVisible(false) .tablePageSize(20) .filterOff(true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_ALLOPPS_LISTING = DisplayerSettingsFactory.newTableSettings() .uuid("opps-allopps-listing") .dataset("SALES_OPPS") .title("salesopps_displayers_all_list_title") .titleVisible(false) .tablePageSize(20) .tableOrderEnabled(true) .tableOrderDefault("AMOUNT", DESCENDING) .filterOn(true, true, true) .refreshOn() .buildSettings(); @Parameterized.Parameters public static Collection displayers() { return Arrays.asList(new Object[][]{ {OPPS_ALLOPPS_LISTING}, {OPPS_BY_COUNTRY}, {OPPS_BY_PIPELINE}, {OPPS_BY_PRODUCT}, {OPPS_BY_SALESMAN}, {OPPS_BY_STATUS}, {OPPS_COUNTRY_SUMMARY}, {OPPS_EXPECTED_PIPELINE} }); } protected DisplayerSettings displayerSettings; public DisplayerSettingsJsonTest(DisplayerSettings settings) { this.displayerSettings = settings; } @Test public void testSettingsMarshalling() { DisplayerSettingsJSONMarshaller displayerJsonMarshaller = DisplayerSettingsJSONMarshaller.get(); JsonObject _jsonObj = displayerJsonMarshaller.toJsonObject(displayerSettings); assertNotNull(_jsonObj.toString()); DisplayerSettings unmarshalled = displayerJsonMarshaller.fromJsonString(_jsonObj.toString()); assertEquals(unmarshalled, displayerSettings); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-shared 7.75.0-SNAPSHOT dashbuilder-dsl jar Dashbuilder DSL Dashbuilder Domain Script Language org.kie.soup kie-soup-dataset-api org.uberfire uberfire-layout-editor-api org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-navigation-api org.dashbuilder dashbuilder-services-api org.dashbuilder dashbuilder-kie-server-api com.google.code.gson gson org.slf4j slf4j-simple test ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/AbstractComponentBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.dsl.model.Component; import org.uberfire.ext.layout.editor.api.css.CssProperty; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; public abstract class AbstractComponentBuilder { private LayoutComponent layoutComponent; AbstractComponentBuilder() { String dragType = getDragType(); this.layoutComponent = new LayoutComponent(dragType); } public Component build() { return Component.create(this.layoutComponent); } @SuppressWarnings("unchecked") public T property(String key, String value) { this.layoutComponent.addProperty(key, value); return (T) this; } @SuppressWarnings("unchecked") public T cssProperty(CssProperty property, String value) { this.property(property.getName(), value); return (T) this; } abstract String getDragType(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/AllProcessesHeatmapBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.displayer.DisplayerSettings; public class AllProcessesHeatmapBuilder extends ExternalDisplayerBuilder { public static final String COMPONENT_ID = "processes-heatmaps-provided"; public static final String SERVER_TEMPLATE_PARAM = "serverTemplate"; public AllProcessesHeatmapBuilder(String serverTemplate, DisplayerSettings settings) { super(COMPONENT_ID, settings); this.componentProperty(SERVER_TEMPLATE_PARAM, serverTemplate); } public static AllProcessesHeatmapBuilder create(String serverTemplate, DisplayerSettings settings) { return new AllProcessesHeatmapBuilder(serverTemplate, settings); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/ComponentFactory.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.dsl.model.Component; public class ComponentFactory { private ComponentFactory() { // empty } public static Component html(String htmlCode) { return HtmlComponentBuilder.create().html(htmlCode).build(); } public static Component external(String componentId) { return ExternalComponentBuilder.create(componentId).build(); } public static Component external(String componentId, DisplayerSettings settings) { return ExternalDisplayerBuilder.create(componentId, settings).build(); } public static Component displayer(DisplayerSettings settings) { return DisplayerBuilder.create(settings).build(); } public static Component logo(String src) { return LogoBuilder.create(src).build(); } public static Component processHeatmap(String serverTemplate, String container, String process, DisplayerSettings settings) { return ProcessHeatmapBuilder.create(serverTemplate, container, process, settings).build(); } public static Component allProcessesHeatmap(String serverTemplate, DisplayerSettings settings) { return AllProcessesHeatmapBuilder.create(serverTemplate, settings).build(); } public static HtmlComponentBuilder newHtmlComponentBuilder() { return HtmlComponentBuilder.create(); } public static ExternalComponentBuilder externalBuilder(String componentId) { return ExternalComponentBuilder.create(componentId); } public static LogoBuilder logoBuilder(String src) { return LogoBuilder.create(src); } public static ProcessHeatmapBuilder processHeatmapBuilder(String serverTemplate, String container, String process, DisplayerSettings settings) { return ProcessHeatmapBuilder.create(serverTemplate, container, process, settings); } public static AllProcessesHeatmapBuilder allProcessesHeatmapBuilder(String serverTemplate, DisplayerSettings settings) { return AllProcessesHeatmapBuilder.create(serverTemplate, settings); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/DisplayerBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.dsl.model.Component; public class DisplayerBuilder extends AbstractComponentBuilder { private static final String JSON_PROP = "json"; DisplayerSettings settings; DisplayerBuilder(DisplayerSettings settings) { this.settings = settings; } public static DisplayerBuilder create(DisplayerSettings settings) { if (isInvalid(settings)) { throw new IllegalArgumentException("You must provide a data set or an UUID to build a displayer component"); } return new DisplayerBuilder(settings); } @Override public Component build() { property(JSON_PROP, DisplayerSettingsJSONMarshaller.get().toJsonString(this.settings)); return super.build(); } @Override String getDragType() { return "org.dashbuilder.client.editor.DisplayerDragComponent"; } private static boolean isInvalid(DisplayerSettings settings) { String dataSetUUID = settings.getDataSetLookup().getDataSetUUID(); return (dataSetUUID == null || dataSetUUID.trim().isEmpty()) && settings.getDataSet() == null; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/ExternalComponentBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.external.model.ExternalComponent; public class ExternalComponentBuilder extends AbstractComponentBuilder { private String componentId; ExternalComponentBuilder(String componentId) { this.componentId = componentId; property(ExternalComponent.COMPONENT_ID_KEY, this.componentId); } public static ExternalComponentBuilder create(String componentId) { return new ExternalComponentBuilder(componentId); } public ExternalComponentBuilder componentProperty(String key, String value) { property(this.componentId + "." + key, value); return this; } public ExternalComponentBuilder partition(String value) { property(ExternalComponent.COMPONENT_PARTITION_KEY, value); return this; } @Override String getDragType() { return "org.dashbuilder.client.editor.external.ExternalDragComponent"; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/ExternalDisplayerBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.external.model.ExternalComponent; public class ExternalDisplayerBuilder extends DisplayerBuilder { ExternalDisplayerBuilder(String componentId, DisplayerSettings settings) { super(settings); property(ExternalComponent.COMPONENT_ID_KEY, componentId); settings.setComponentId(componentId); } public static ExternalDisplayerBuilder create(String id, DisplayerSettings settings) { return new ExternalDisplayerBuilder(id, settings); } public ExternalDisplayerBuilder componentProperty(String key, String value) { settings.setComponentProperty(key, value); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/HtmlComponentBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; public class HtmlComponentBuilder extends AbstractComponentBuilder { private static final String DRAG_TYPE = "org.uberfire.ext.plugin.client.perspective.editor.layout.editor.HTMLLayoutDragComponent"; public static final String HTML_CODE_PROP = "HTML_CODE"; public static HtmlComponentBuilder create() { return new HtmlComponentBuilder(); } public HtmlComponentBuilder html(String html) { property(HTML_CODE_PROP, html); return this; } @Override String getDragType() { return DRAG_TYPE; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/LogoBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; public class LogoBuilder extends ExternalComponentBuilder { public static final String LOGO_ID = "logo-provided"; public static final String LOGO_URL_PROP = "src"; public static final String LOGO_WIDTH_PROP = "width"; public static final String LOGO_HEIGHT_PROP = "height"; LogoBuilder(String src) { super(LOGO_ID); src(src); } public static LogoBuilder create(String src) { return new LogoBuilder(src); } public LogoBuilder src(String src) { componentProperty(LOGO_URL_PROP, src); return this; } public LogoBuilder width(String width) { componentProperty(LOGO_WIDTH_PROP, width); return this; } public LogoBuilder height(String height) { componentProperty(LOGO_HEIGHT_PROP, height); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/component/ProcessHeatmapBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.displayer.DisplayerSettings; public class ProcessHeatmapBuilder extends ExternalDisplayerBuilder { public static final String COMPONENT_ID = "process-heatmap-provided"; public static final String SERVER_TEMPLATE_PARAM = "serverTemplate"; public static final String CONTAINER_ID_PARAM = "containerId"; public static final String PROCESS_ID_PARAM = "processId"; public ProcessHeatmapBuilder(String serverTemplate, String container, String processId, DisplayerSettings settings) { super(COMPONENT_ID, settings); this.componentProperty(SERVER_TEMPLATE_PARAM, serverTemplate); this.componentProperty(CONTAINER_ID_PARAM, container); this.componentProperty(PROCESS_ID_PARAM, processId); } public static ProcessHeatmapBuilder create(String serverTemplate, String container, String processId, DisplayerSettings settings) { return new ProcessHeatmapBuilder(serverTemplate, container, processId, settings); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/dashboard/DashboardBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.dashboard; import java.nio.file.Path; import java.util.Collections; import java.util.List; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dsl.factory.navigation.NavigationFactory; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.model.Navigation; import org.dashbuilder.dsl.model.Page; public class DashboardBuilder { private List pages = Collections.emptyList(); private List dataSets = Collections.emptyList(); private Navigation navigation = NavigationFactory.emptyNavigation(); private Path componentsPath; DashboardBuilder(List pages) { this.pages = pages; } public static DashboardBuilder newBuilder(List pages) { return new DashboardBuilder(pages); } public DashboardBuilder pages(List pages) { this.pages = pages; return this; } public DashboardBuilder dataSets(List dataSets) { this.dataSets = dataSets; return this; } public DashboardBuilder navigation(Navigation navigation) { this.navigation = navigation; return this; } public DashboardBuilder componentsPath(Path componentsPath) { this.componentsPath = componentsPath; return this; } public Dashboard build() { return Dashboard.of(pages, dataSets, navigation, componentsPath); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/dashboard/DashboardFactory.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.dashboard; import java.nio.file.Path; import java.util.List; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.model.Navigation; import org.dashbuilder.dsl.model.Page; public class DashboardFactory { private DashboardFactory() { // empty } public static DashboardBuilder dashboardBuilder(List pages) { return DashboardBuilder.newBuilder(pages); } public static Dashboard dashboard(List pages) { return DashboardBuilder.newBuilder(pages).build(); } public static Dashboard dashboard(List pages, Path componentsPath) { return DashboardBuilder.newBuilder(pages).componentsPath(componentsPath).build(); } public static Dashboard dashboard(List pages, Navigation navigation) { return DashboardBuilder.newBuilder(pages).navigation(navigation).build(); } public static Dashboard dashboard(List pages, List dataSets) { return DashboardBuilder.newBuilder(pages) .dataSets(dataSets) .build(); } public static Dashboard dashboard(List pages, List dataSets, Path componentsPath) { return DashboardBuilder.newBuilder(pages) .dataSets(dataSets) .componentsPath(componentsPath) .build(); } public static Dashboard dashboard(List pages, List dataSets, Navigation navigation) { return DashboardBuilder.newBuilder(pages) .dataSets(dataSets) .navigation(navigation) .build(); } public static Dashboard dashboard(List pages, List dataSets, Navigation navigation, Path componentsPath) { return DashboardBuilder.newBuilder(pages) .dataSets(dataSets) .navigation(navigation) .componentsPath(componentsPath) .build(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/navigation/NavigationBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.navigation; import org.dashbuilder.dsl.model.Navigation; import org.dashbuilder.dsl.model.NavigationGroup; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeImpl; public class NavigationBuilder { private NavTree navTree; private NavigationBuilder(NavTree navTree) { this.navTree = navTree; } public static NavigationBuilder newBuilder(NavigationGroup... groups) { NavTree tree = new NavTreeImpl(NavigationGroupBuilder.newBuilder("Top Group", groups).build().getNavGroup()); return new NavigationBuilder(tree); } public Navigation build() { return Navigation.of(this.navTree); } static NavigationBuilder newBuilder() { NavTree tree = new NavTreeImpl(); return new NavigationBuilder(tree); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/navigation/NavigationFactory.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.navigation; import org.dashbuilder.dsl.model.Navigation; import org.dashbuilder.dsl.model.NavigationGroup; import org.dashbuilder.dsl.model.NavigationItem; import org.dashbuilder.dsl.model.Page; public class NavigationFactory { private static final Navigation EMPTY_NAVIGATION = NavigationBuilder.newBuilder().build(); private NavigationFactory() { // empty } public static Navigation emptyNavigation() { return EMPTY_NAVIGATION; } public static Navigation navigation(NavigationGroup... rootGroups) { return NavigationBuilder.newBuilder(rootGroups).build(); } public static NavigationGroup group(String name, NavigationItem... items) { return NavigationGroupBuilder.newBuilder(name, items).build(); } public static NavigationItem item(Page page) { return NavigationItemBuilder.newBuilder(page).build(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/navigation/NavigationGroupBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.navigation; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import org.dashbuilder.dsl.model.NavigationGroup; import org.dashbuilder.dsl.model.NavigationItem; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.impl.NavGroupImpl; public class NavigationGroupBuilder { private NavGroup navGroup; private NavigationGroupBuilder(NavGroup navGroup) { this.navGroup = navGroup; } public static NavigationGroupBuilder newBuilder(String name, NavigationItem... items) { NavGroup group = new NavGroupImpl(); List navItems = Arrays.stream(items).map(NavigationItem::getNavItem).collect(Collectors.toList()); group.setName(name); group.setDescription("Some Group"); group.setId(System.currentTimeMillis() + ""); group.setChildren(navItems); group.setModifiable(false); return new NavigationGroupBuilder(group); } public NavigationGroupBuilder name(String name) { this.navGroup.setName(name); return this; } public NavigationGroupBuilder item(NavigationItem item) { navGroup.getChildren().add(item.getNavItem()); return this; } public NavigationGroup build() { return NavigationGroup.of(this.navGroup); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/navigation/NavigationItemBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.navigation; import org.dashbuilder.dsl.model.NavigationItem; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.impl.NavItemImpl; public class NavigationItemBuilder { private NavItem navItem; private NavigationItemBuilder(NavItem navItem) { this.navItem = navItem; } public static NavigationItemBuilder newBuilder(Page page) { NavItem item = new NavItemImpl(); String name = page.getLayoutTemplate().getName(); item.setId(System.currentTimeMillis() + ""); item.setName(name); item.setModifiable(false); item.setContext("resourceId=" + name + ";resourceType=PERSPECTIVE;"); return new NavigationItemBuilder(item); } public NavigationItemBuilder name(String name) { this.navItem.setName(name); return this; } public NavigationItem build() { return NavigationItem.of(this.navItem); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/page/AbstractLayoutBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import org.uberfire.ext.layout.editor.api.css.CssProperty; public abstract class AbstractLayoutBuilder { @SuppressWarnings("unchecked") public T property(String key, String value) { this.addProperty(key, value); return (T) this; } @SuppressWarnings("unchecked") public T cssProperty(CssProperty property, String value) { this.addProperty(property.getName(), value); return (T) this; } protected abstract void addProperty(String key, String value); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/page/ColumnBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import org.dashbuilder.dsl.model.Column; import org.dashbuilder.dsl.model.Component; import org.dashbuilder.dsl.model.Row; import org.uberfire.ext.layout.editor.api.editor.LayoutColumn; public class ColumnBuilder extends AbstractLayoutBuilder { private static final String DEFAULT_SPAN = "0"; LayoutColumn layoutColumn; ColumnBuilder(String span) { this.layoutColumn = new LayoutColumn(span); } public static ColumnBuilder newBuilder() { return newBuilder(DEFAULT_SPAN); } public static ColumnBuilder newBuilder(String span) { return new ColumnBuilder(span); } public ColumnBuilder row(Row row) { this.layoutColumn.addRow(row.getLayoutRow()); return this; } public ColumnBuilder rows(Row... rows) { for (Row row : rows) { this.row(row); } return this; } public ColumnBuilder component(Component component) { this.layoutColumn.add(component.getLayoutComponent()); return this; } public ColumnBuilder components(Component... components) { for (Component component : components) { component(component); } return this; } public Column build() { return Column.create(this.layoutColumn); } @Override protected void addProperty(String key, String value) { this.layoutColumn.getProperties().put(key, value); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/page/PageBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.dsl.model.Row; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate.Style; public class PageBuilder extends AbstractLayoutBuilder { LayoutTemplate layoutTemplate; private PageBuilder(String name) { this.layoutTemplate = new LayoutTemplate(name); } public static PageBuilder newBuilder(String name) { return new PageBuilder(name); } public PageBuilder name(String name) { this.layoutTemplate.setName(name); return this; } public PageBuilder style(Style style) { this.layoutTemplate.setStyle(style); return this; } public PageBuilder row(Row row) { this.layoutTemplate.addRow(row.getLayoutRow()); return this; } public PageBuilder rows(Row... rows) { for (Row row : rows) { this.row(row); } return this; } public Page build() { return Page.create(this.layoutTemplate); } @Override protected void addProperty(String key, String value) { this.layoutTemplate.addLayoutProperty(key, value); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/page/PageFactory.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.dsl.model.Column; import org.dashbuilder.dsl.model.Component; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.dsl.model.Row; import static org.dashbuilder.dsl.factory.component.ComponentFactory.displayer; import static org.dashbuilder.dsl.factory.component.ComponentFactory.html; public class PageFactory { private PageFactory() { // empty } public static PageBuilder pageBuilder(String name) { return PageBuilder.newBuilder(name); } public static RowBuilder rowBuilder(String height) { return RowBuilder.newBuilder(height); } public static ColumnBuilder columnBuilder() { return ColumnBuilder.newBuilder(); } public static ColumnBuilder columnBuilder(String span) { return ColumnBuilder.newBuilder(span); } public static ColumnBuilder columnBuilder(String span, Component... components) { return ColumnBuilder.newBuilder(span).components(components); } public static Page page(String name, Row... rows) { return PageBuilder.newBuilder(name).rows(rows).build(); } public static Column column(String span, Component... components) { return ColumnBuilder.newBuilder(span).components(components).build(); } public static Column column(Component... components) { return ColumnBuilder.newBuilder().components(components).build(); } public static Column column(Component component) { return ColumnBuilder.newBuilder().components(component).build(); } public static Column column(DisplayerSettings settings) { return ColumnBuilder.newBuilder().components(displayer(settings)).build(); } public static Column column(Row row) { return ColumnBuilder.newBuilder().row(row).build(); } public static Column column(Row... rows) { return ColumnBuilder.newBuilder().rows(rows).build(); } public static Row row(Column... columns) { return RowBuilder.newBuilder().columns(columns).build(); } /** * * Creates a column with a single html component * @param html * @return */ public static Column column(String html) { return ColumnBuilder.newBuilder().component(html(html)).build(); } /** * * Creates a row with a single column and a single html component * @param html * @return */ public static Row row(String html) { return row(html(html)); } /** * * Creates a row with a single column with the provided component * @param component * @return */ public static Row row(Component component) { return row(column(component)); } /** * * Creates a row with a single column with a displayer created with the provided settings * @param settings * @return */ public static Row row(DisplayerSettings settings) { return row(column(settings)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/factory/page/RowBuilder.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import java.util.HashMap; import org.dashbuilder.dsl.model.Column; import org.dashbuilder.dsl.model.Row; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; public class RowBuilder extends AbstractLayoutBuilder { private static final String DEFAULT_HEIGHT = "12"; LayoutRow layoutRow; private RowBuilder(String height) { this.layoutRow = new LayoutRow(height, new HashMap<>()); } public static RowBuilder newBuilder() { return newBuilder(DEFAULT_HEIGHT); } public static RowBuilder newBuilder(String height) { return new RowBuilder(height); } @Override public RowBuilder property(String key, String value) { this.layoutRow.getProperties().put(key, value); return this; } public RowBuilder columns(Column... columns) { for (Column column : columns) { this.column(column); } return this; } public RowBuilder column(Column column) { this.layoutRow.add(column.getLayoutColumn()); return this; } public Row build() { return Row.create(this.layoutRow); } @Override protected void addProperty(String key, String value) { this.layoutRow.getProperties().put(key, value); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/helper/ComponentsHelper.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.helper; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.external.service.ComponentLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; public class ComponentsHelper { private static final Logger logger = LoggerFactory.getLogger(ComponentsHelper.class); private static final Gson gson = new GsonBuilder().create(); private ComponentsHelper() { // empty } public static List listComponentsIds(Dashboard dashboard) { Optional componentsPath = dashboard.getComponentsPath(); if (!componentsPath.isPresent()) { return Collections.emptyList(); } return ComponentsHelper.listComponents(componentsPath.get()) .stream() .map(ExternalComponent::getId) .collect(Collectors.toList()); } public static List listComponents(Path componentsPath) { try (Stream walker = Files.walk(componentsPath, 1)) { return walker.filter(p -> p.toFile().isDirectory()) .map(p -> Paths.get(p.toString(), ComponentLoader.DESCRIPTOR_FILE)) .filter(f -> f.toFile().exists()) .map(ComponentsHelper::readComponent) .filter(Objects::nonNull) .collect(Collectors.toList()); } catch (IOException e) { logger.debug("Error loading external components.", e); throw new RuntimeException("Error loading components from " + componentsPath + ". Error: " + e.getMessage(), e); } } public static List listPagesComponents(List pages) { return pages.stream() .map(Page::getLayoutTemplate) .map(LayoutTemplate::getRows) .flatMap(ComponentsHelper::allLayoutComponentsStream) .map(lt -> lt.getProperties().get(ExternalComponent.COMPONENT_ID_KEY)) .filter(Objects::nonNull) .collect(Collectors.toList()); } public static Stream collectingPropertyValue(Page page, String propertyId) { return allLayoutComponentsStream(page.getLayoutTemplate().getRows()).map(lc -> lc.getProperties().get(propertyId)) .filter(Objects::nonNull); } private static Stream allLayoutComponentsStream(List row) { return row.stream() .flatMap(r -> r.getLayoutColumns().stream()) .flatMap(cl -> Stream.concat(cl.getLayoutComponents().stream(), allLayoutComponentsStream(cl.getRows()))); } private static ExternalComponent readComponent(Path file) { String id = file.getParent().toFile().getName(); try { ExternalComponent component = gson.fromJson(new FileReader(file.toFile()), ExternalComponent.class); component.setId(id); return component; } catch (FileNotFoundException e) { logger.error("Not able to read component manifest file {}. Error: {}", file, e.getMessage()); logger.debug("Error reading component file.", e); return null; } } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/Column.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import org.uberfire.ext.layout.editor.api.editor.LayoutColumn; public class Column { LayoutColumn layoutColumn; Column(LayoutColumn layoutColumn) { this.layoutColumn = layoutColumn; } public static Column create(LayoutColumn layoutColumn) { return new Column(layoutColumn); } public LayoutColumn getLayoutColumn() { return layoutColumn; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/Component.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; public class Component { LayoutComponent layoutComponent; Component(LayoutComponent layoutComponent) { this.layoutComponent = layoutComponent; } public static Component create(LayoutComponent layoutComponent) { return new Component(layoutComponent); } public LayoutComponent getLayoutComponent() { return layoutComponent; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/Dashboard.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import java.nio.file.Path; import java.util.List; import java.util.Optional; import org.dashbuilder.dataset.def.DataSetDef; public class Dashboard { private List pages; private List dataSets; private Navigation navigation; private Path componentsPath; private Dashboard(List pages, List dataSets, Navigation navigation, Path componentsPath) { this.componentsPath = componentsPath; this.pages = pages; this.dataSets = dataSets; this.navigation = navigation; } public static Dashboard of(List pages, List dataSets, Navigation navigation, Path componentsPath) { return new Dashboard(pages, dataSets, navigation, componentsPath); } public List getPages() { return pages; } public List getDataSets() { return dataSets; } public Navigation getNavigation() { return navigation; } public Optional getComponentsPath() { return Optional.ofNullable(componentsPath); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/Navigation.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import org.dashbuilder.navigation.NavTree; public class Navigation { private NavTree navTree; private Navigation(NavTree navTree) { this.navTree = navTree; } public static Navigation of(NavTree navTree) { return new Navigation(navTree); } public NavTree getNavTree() { return navTree; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/NavigationGroup.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import org.dashbuilder.navigation.NavGroup; public class NavigationGroup extends NavigationItem { private NavGroup navGroup; private NavigationGroup(NavGroup group) { super(group); this.navGroup = group; } public static NavigationGroup of(NavGroup group) { return new NavigationGroup(group); } public NavGroup getNavGroup() { return navGroup; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/NavigationItem.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import org.dashbuilder.navigation.NavItem; public class NavigationItem { private NavItem navItem; public NavigationItem(NavItem navItem) { this.navItem = navItem; } public static NavigationItem of(NavItem navItem) { return new NavigationItem(navItem); } public NavItem getNavItem() { return navItem; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/Page.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; public class Page { LayoutTemplate layoutTemplate; Page(LayoutTemplate layoutTemplate) { this.layoutTemplate = layoutTemplate; } public static Page create(LayoutTemplate layoutTemplate) { return new Page(layoutTemplate); } public LayoutTemplate getLayoutTemplate() { return layoutTemplate; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/model/Row.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.model; import org.uberfire.ext.layout.editor.api.editor.LayoutRow; public class Row { LayoutRow layoutRow; Row(LayoutRow layoutRow) { this.layoutRow = layoutRow; } public static Row create(LayoutRow layoutRow) { return new Row(layoutRow); } public LayoutRow getLayoutRow() { return layoutRow; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/serialization/DashboardExporter.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.serialization; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; import io.netty.util.internal.shaded.org.jctools.queues.MessagePassingQueue.Consumer; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.serialization.impl.DashboardZipSerializer; import org.dashbuilder.dsl.validation.DashboardValidator; import org.dashbuilder.dsl.validation.ValidationResult; import org.dashbuilder.dsl.validation.ValidationResult.ValidationResultType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DashboardExporter { private static final Logger logger = LoggerFactory.getLogger(DashboardExporter.class); private static final DashboardExporter INSTANCE = new DashboardExporter(); DashboardValidator validator = DashboardValidator.get(); public enum ExportType { ZIP } private DashboardExporter() { // empty } public static DashboardExporter get() { return INSTANCE; } public void export(Dashboard dashboard, String path, ExportType type) { export(dashboard, Paths.get(path), type); } public void export(Dashboard dashboard, Path path, ExportType type) { DashboardSerializer serializer = serializerFor(type); validate(dashboard); Path temp = createTempDashboardFile(); try (FileOutputStream fos = new FileOutputStream(temp.toFile())) { serializer.serialize(dashboard, fos); Files.move(temp, path, StandardCopyOption.REPLACE_EXISTING); } catch (FileNotFoundException e) { throw new IllegalArgumentException("File not found: " + path, e); } catch (IOException e) { throw new RuntimeException("Error writing to file " + path, e); } finally { try { Files.deleteIfExists(temp); } catch (IOException e) { logger.error("Error deleting temp file", e); } } } private Path createTempDashboardFile() { try { return Files.createTempFile("dashboard", ".zip"); } catch (IOException e) { throw new RuntimeException("Error creating temp file to export dashboard", e); } } void validate(Dashboard dashboard) { List results = validator.validate(dashboard); printResult(results, ValidationResultType.ERROR, logger::error); printResult(results, ValidationResultType.WARNING, logger::warn); printResult(results, ValidationResultType.SUCCESS, logger::info); if (results.stream().anyMatch(p -> p.getType() == ValidationResultType.ERROR)) { throw new IllegalArgumentException("There are validation errors, check logs for more details"); } } private void printResult(List results, ValidationResultType type, Consumer printer) { results.stream() .filter(v -> v.getType() == type) .map(Object::toString) .forEach(printer::accept); } private static DashboardZipSerializer serializerFor(ExportType type) { // only ZIP is supported at the moment switch (type) { case ZIP: return new DashboardZipSerializer(); } return new DashboardZipSerializer(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/serialization/DashboardSerializer.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.serialization; import java.io.InputStream; import java.io.OutputStream; import org.dashbuilder.dsl.model.Dashboard; public interface DashboardSerializer { /** * Serialize the provided dashboard and write the result in the provided output stream * @param dashboard * @param os * @return */ void serialize(Dashboard dashboard, OutputStream os); /** * Deserialize the incoming input stream into a Dashboard object * * Support of components and files that aren't dashboard definition may not be supported. * @param model * @return */ Dashboard deserialize(InputStream model); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/serialization/impl/DashboardZipSerializer.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.serialization.impl; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import javax.ws.rs.NotSupportedException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.json.DataSetDefJSONMarshaller; import org.dashbuilder.dsl.factory.dashboard.DashboardFactory; import org.dashbuilder.dsl.factory.navigation.NavigationFactory; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.model.Navigation; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.dsl.serialization.DashboardSerializer; import org.dashbuilder.external.model.ExternalComponent; import org.dashbuilder.navigation.json.NavTreeJSONMarshaller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; import static java.nio.charset.StandardCharsets.UTF_8; import static org.dashbuilder.dsl.helper.ComponentsHelper.listComponents; import static org.dashbuilder.dsl.helper.ComponentsHelper.listPagesComponents; public class DashboardZipSerializer implements DashboardSerializer { private static final String PATH_SEPARATOR = "/"; Logger logger = LoggerFactory.getLogger(DashboardZipSerializer.class); private static int MAX_ENTRIES = 10_000; private static final String CSV_EXT = ".csv"; private static final String DATASET_EXT = ".dset"; private static final String PLUGIN_EXT = ".plugin"; private static final String PERSPECTIVE_LAYOUT = "perspective_layout"; private static final String BASE_PATH = "dashbuilder/"; private static final String LAYOUTS_PATH = BASE_PATH + "perspectives/"; private static final String DATA_SETS_BASE = BASE_PATH + "datasets/"; private static final String COMPONENTS_BASE = BASE_PATH + "components/"; private static final String DATA_SETS_PATH = DATA_SETS_BASE + "definitions/"; private static final String NAVIGATION_PATH = BASE_PATH + "navigation/navigation/navtree.json"; private static final DataSetDefJSONMarshaller DATA_SET_MARSHALLER = new DataSetDefJSONMarshaller(new InternalDataSetProviderRegistry()); private static final Gson gson = new GsonBuilder().create(); @Override public Dashboard deserialize(InputStream model) { throw new NotSupportedException("Deserialize is not supported for ZIP Serializer"); } /** * Does not support: CSV files and components files */ Dashboard internalDeserialize(InputStream model) { Map importContent = readAllEntriesContent(model); List pages = new ArrayList<>(); List datasets = new ArrayList<>(); AtomicReference navigationRef = new AtomicReference<>(NavigationFactory.emptyNavigation()); importContent.forEach((path, content) -> { if (path.startsWith(LAYOUTS_PATH) && path.endsWith(PERSPECTIVE_LAYOUT)) { LayoutTemplate template = gson.fromJson(content, LayoutTemplate.class); pages.add(Page.create(template)); } if (path.startsWith(DATA_SETS_PATH) && path.endsWith(DATASET_EXT)) { DataSetDef def; try { def = DATA_SET_MARSHALLER.fromJson(content); datasets.add(def); } catch (Exception e) { logger.warn("Error reading dataset content {}", path); logger.debug("Error reading dataset content.", e); } } if (path.startsWith(NAVIGATION_PATH)) { navigationRef.set(Navigation.of(NavTreeJSONMarshaller.get().fromJson(content))); } }); return DashboardFactory.dashboard(pages, datasets, navigationRef.get(), null); } @Override public void serialize(Dashboard dashboard, OutputStream os) { ZipOutputStream zos = new ZipOutputStream(os); dashboard.getDataSets() .stream() .forEach(def -> writeDataSetDef(zos, def)); dashboard.getPages() .stream() .forEach(page -> writePage(zos, page)); dashboard.getDataSets() .stream() .filter(CSVDataSetDef.class::isInstance) .map(CSVDataSetDef.class::cast) .forEach(def -> writeCSVFile(zos, def)); writeNavigation(zos, dashboard.getNavigation()); writeContent(zos, DATA_SETS_BASE + "readme.md", ""); Optional componentsPathOp = dashboard.getComponentsPath(); if (componentsPathOp.isPresent()) { Path componentsPath = componentsPathOp.get(); List components = listComponents(componentsPath); listPagesComponents(dashboard.getPages()).stream() .filter(c -> components.stream() .anyMatch(comp -> comp.getId().equals(c))) .forEach(c -> writeComponent(componentsPath, c, zos)); } try { zos.close(); } catch (IOException e) { throw new RuntimeException("Error closing ZIP", e); } } private void writeCSVFile(ZipOutputStream zos, CSVDataSetDef def) { String filePath = def.getFilePath(); if (filePath != null) { Path path = Paths.get(filePath); if (path.toFile().exists()) { try { writeContent(zos, DATA_SETS_PATH + def.getUUID() + CSV_EXT, Files.readAllBytes(path)); } catch (IOException e) { logger.warn("Not able to write CSV file {} to the exported ZIP", filePath); logger.debug("Not able to write CSV", e); } } } } private void writeComponent(Path componentsPath, String componentId, ZipOutputStream zos) { final Path componentPath = componentsPath.resolve(componentId); final String componentZipPathBase = COMPONENTS_BASE + componentId + PATH_SEPARATOR; try (Stream walker = Files.walk(componentPath, 1)) { walker.filter(p -> !p.toFile().isDirectory()) .forEach(file -> { String fileName = componentZipPathBase + file.toFile().getName(); writeContent(zos, fileName, file); }); } catch (IOException e) { logger.debug("Error loading external component files.", e); throw new RuntimeException("Error loading components from " + componentsPath + ". Error: " + e.getMessage()); } } private void writeNavigation(ZipOutputStream zos, Navigation navigation) { String content = NavTreeJSONMarshaller.get().toJson(navigation.getNavTree()).toString(); writeContent(zos, NAVIGATION_PATH, content); } private void writePage(ZipOutputStream zos, Page page) { LayoutTemplate lt = page.getLayoutTemplate(); String path = LAYOUTS_PATH + lt.getName() + PATH_SEPARATOR + PERSPECTIVE_LAYOUT; String pluginPath = path + PLUGIN_EXT; String content = gson.toJson(lt); writeContent(zos, path, content); writeContent(zos, pluginPath, new Date().toString()); } private void writeDataSetDef(ZipOutputStream zos, DataSetDef def) { String path = DATA_SETS_PATH + def.getUUID() + DATASET_EXT; String content = DATA_SET_MARSHALLER.toJsonString(def); writeContent(zos, path, content); } private void writeContent(ZipOutputStream zos, String path, byte[] content) { try { zos.putNextEntry(new ZipEntry(path)); zos.write(content); zos.closeEntry(); } catch (IOException e) { logger.warn("Error writing content on path {}", path); logger.debug("Error writing content. ", e); } } private void writeContent(ZipOutputStream zos, String path, String content) { this.writeContent(zos, path, content.getBytes()); } private void writeContent(ZipOutputStream zos, String path, Path file) { try { this.writeContent(zos, path, Files.readAllBytes(file)); } catch (IOException e) { logger.info("Error reading component file {}: {}", file, e.getMessage()); logger.debug("Error reading component file", e); } } Map readAllEntriesContent(InputStream model) { Map entriesContent = new HashMap<>(); Path zipTemp; try { zipTemp = Files.createTempFile("dashboard", "zip"); Files.copy(model, zipTemp, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException("Error creating temp file", e); } try (ZipFile zipFile = new ZipFile(zipTemp.toFile())) { Enumeration entries = zipFile.entries(); int totalEntries = 0; while (entries.hasMoreElements()) { if (++totalEntries > MAX_ENTRIES) { throw new IllegalArgumentException("ZIP file contains too many entries"); } ZipEntry e = entries.nextElement(); String content = new BufferedReader(new InputStreamReader(zipFile.getInputStream(e), UTF_8)).lines() .collect(Collectors.joining("\n")); entriesContent.put(e.getName(), content); } } catch (Exception e) { throw new RuntimeException("Error reading input file", e); } try { Files.delete(zipTemp); } catch (IOException e) { logger.error("Temp file not deleted due an error", e); } return entriesContent; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/serialization/impl/InternalDataSetProviderRegistry.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.serialization.impl; import java.util.HashSet; import java.util.Set; import org.dashbuilder.dataprovider.DataSetProvider; import org.dashbuilder.dataprovider.DataSetProviderRegistry; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.kieserver.RuntimeKieServerDataSetProviderType; public class InternalDataSetProviderRegistry implements DataSetProviderRegistry { Set providers; public InternalDataSetProviderRegistry() { initProviders(); } @Override public void registerDataProvider(DataSetProvider dataProvider) { // empty } @Override public DataSetProvider getDataSetProvider(DataSetProviderType type) { // returning null because this registry will not be used in runtime, // so this method should not be called in the scope of the API return null; } @Override public Set getAvailableTypes() { return providers; } @Override public DataSetProviderType getProviderTypeByName(String name) { return providers.stream() .filter(p -> p.getName().equals(name)).findFirst() .orElseThrow(() -> new IllegalArgumentException("Provider not found: " + name)); } private void initProviders() { providers = new HashSet<>(); providers.add(DataSetProviderType.BEAN); providers.add(DataSetProviderType.CSV); providers.add(DataSetProviderType.KAFKA); providers.add(DataSetProviderType.PROMETHEUS); providers.add(DataSetProviderType.SQL); providers.add(DataSetProviderType.STATIC); providers.add(DataSetProviderType.PROMETHEUS); providers.add(new RuntimeKieServerDataSetProviderType()); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/validation/DashboardValidator.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.validation; import java.util.List; import org.dashbuilder.dsl.model.Dashboard; /** * Dashboard validation * */ public interface DashboardValidator { DashboardValidator instance = new DashboardValidatorImpl(); List validate(Dashboard dashboard); public static DashboardValidator get() { return instance; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/validation/DashboardValidatorImpl.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.validation; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.dsl.factory.navigation.NavigationFactory; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.model.Navigation; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemVisitor; import static java.lang.String.format; import static java.util.stream.Collectors.joining; import static org.dashbuilder.dsl.helper.ComponentsHelper.collectingPropertyValue; import static org.dashbuilder.dsl.helper.ComponentsHelper.listComponentsIds; import static org.dashbuilder.dsl.validation.ValidationResult.error; import static org.dashbuilder.dsl.validation.ValidationResult.success; import static org.dashbuilder.dsl.validation.ValidationResult.warning; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_ID_KEY; class DashboardValidatorImpl implements DashboardValidator { private static final String MISSING_NAVIGATION_ITEM = "Navigation item %s has no corresponding page"; private static final String DUPLICATED_GROUPS = "The Navigation constains duplicate group names"; private static final String VALID_NAVIGATION = "Navigation is valid"; private static final String NO_MISSING_DATA_SET = "No missing data set dependencies for page %s"; private static final String MISSING_DATA_SET = "The following data sets definitions used in page %s were not found: %s"; private static final String NO_MISSING_COMPONENT = "No missing component dependencies for page %s"; private static final String MISSING_COMPONENT_MESSAGE = "The following components used in page %s were not found: %s"; DisplayerSettingsJSONMarshaller displayerSettingsMarshaller = DisplayerSettingsJSONMarshaller.get(); DashboardValidatorImpl() { // empty } @Override public List validate(Dashboard dashboard) { List results = new ArrayList<>(); results.addAll(checkDataSetsDependencies(dashboard)); results.addAll(checkComponentsDependencies(dashboard)); results.addAll(checkNavigation(dashboard)); return results; } private List checkNavigation(Dashboard dashboard) { Navigation navigation = dashboard.getNavigation(); NavigationPagesVisitor visitor = new NavigationPagesVisitor(); List results = new ArrayList<>(); if (navigation == null || navigation == NavigationFactory.emptyNavigation()) { return Collections.emptyList(); } navigation.getNavTree().accept(visitor); List visitedPages = visitor.getVisitedPages(); List visitedGroups = visitor.getVisitedGroups(); if (!visitedPages.isEmpty()) { visitedPages.stream() .filter(vp -> dashboard.getPages().stream().noneMatch(p -> p.getLayoutTemplate().getName().equals(vp))) .map(vp -> error(format(MISSING_NAVIGATION_ITEM, vp))) .forEach(results::add); } if (containDuplicates(visitedGroups)) { results.add(error(DUPLICATED_GROUPS)); } if (results.isEmpty()) { results.add(ValidationResult.success(VALID_NAVIGATION)); } return results; } List checkComponentsDependencies(Dashboard dashboard) { List components = listComponentsIds(dashboard); return dashboard.getPages().stream() .map(p -> validateComponentsUsage(p, components)) .filter(Objects::nonNull) .collect(Collectors.toList()); } List checkDataSetsDependencies(Dashboard dashboard) { return dashboard.getPages().stream() .map(p -> validateDataSetsUsage(p, dashboard.getDataSets())) .filter(Objects::nonNull) .collect(Collectors.toList()); } ValidationResult validateDataSetsUsage(Page page, List dataSets) { List dataSetsDeps = findDataSetsDependencies(page); if (dataSetsDeps.isEmpty()) { return null; } Set missingDataSets = dataSetsDeps.stream() .filter(uuid -> noneMatch(dataSets, ds -> ds.getUUID().equals(uuid))) .collect(Collectors.toSet()); return missingDataSets.isEmpty() ? success(format(NO_MISSING_DATA_SET, page.getLayoutTemplate().getName())) : error(format(MISSING_DATA_SET, page.getLayoutTemplate().getName(), missingDataSets.stream() .collect(joining(", ")))); } ValidationResult validateComponentsUsage(Page page, List components) { List componentsDeps = findComponentsDependencies(page); if (componentsDeps.isEmpty()) { return null; } Set missingComponents = componentsDeps.stream() .filter(id -> noneMatch(components, cid -> cid.equals(id))) .collect(Collectors.toSet()); return missingComponents.isEmpty() ? success(format(NO_MISSING_COMPONENT, page.getLayoutTemplate().getName())) : warning(format(MISSING_COMPONENT_MESSAGE, page.getLayoutTemplate().getName(), missingComponents.stream() .collect(joining(", ")))); } private boolean noneMatch(List list, Predicate test) { return list.isEmpty() || list.stream().noneMatch(test::test); } private List findDataSetsDependencies(Page page) { return collectingPropertyValue(page, "json").map(displayerSettingsMarshaller::fromJsonString) .map(DisplayerSettings::getDataSetLookup) .filter(Objects::nonNull) .map(DataSetLookup::getDataSetUUID) .filter(Objects::nonNull) .collect(Collectors.toList()); } private List findComponentsDependencies(Page page) { return collectingPropertyValue(page, COMPONENT_ID_KEY).filter(c -> !c.endsWith("provided")) .collect(Collectors.toList()); } private boolean containDuplicates(List list) { return list.size() > list.stream().distinct().count(); } static class NavigationPagesVisitor implements NavItemVisitor { private List visitedPages; private List visitedGroups; NavigationPagesVisitor() { this.visitedPages = new ArrayList<>(); this.visitedGroups = new ArrayList<>(); } public List getVisitedPages() { return visitedPages; } @Override public void visitGroup(NavGroup group) { visitedGroups.add(group.getName()); } @Override public void visitItem(NavItem item) { visitedPages.add(item.getName()); } @Override public void visitDivider(NavDivider divider) { // empty } public List getVisitedGroups() { return visitedGroups; } } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/main/java/org/dashbuilder/dsl/validation/ValidationResult.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.validation; public class ValidationResult { public enum ValidationResultType { SUCCESS, WARNING, ERROR; } ValidationResultType type; String message; public ValidationResult(ValidationResultType type, String message) { this.type = type; this.message = message; } public static ValidationResult success(String message) { return new ValidationResult(ValidationResultType.SUCCESS, message); } public static ValidationResult warning(String message) { return new ValidationResult(ValidationResultType.WARNING, message); } public static ValidationResult error(String message) { return new ValidationResult(ValidationResultType.ERROR, message); } public ValidationResultType getType() { return type; } public String getMessage() { return message; } @Override public String toString() { return "ValidationResult [type=" + type + ", message=" + message + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/factory/component/ComponentFactoryTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.dsl.model.Component; import org.junit.Test; import static org.dashbuilder.dsl.factory.component.HtmlComponentBuilder.HTML_CODE_PROP; import static org.dashbuilder.dsl.factory.component.LogoBuilder.LOGO_ID; import static org.dashbuilder.dsl.factory.component.LogoBuilder.LOGO_URL_PROP; import static org.dashbuilder.dsl.factory.component.ProcessHeatmapBuilder.COMPONENT_ID; import static org.dashbuilder.dsl.factory.component.ProcessHeatmapBuilder.CONTAINER_ID_PARAM; import static org.dashbuilder.dsl.factory.component.ProcessHeatmapBuilder.PROCESS_ID_PARAM; import static org.dashbuilder.dsl.factory.component.ProcessHeatmapBuilder.SERVER_TEMPLATE_PARAM; import static org.dashbuilder.external.model.ExternalComponent.COMPONENT_ID_KEY; import static org.junit.Assert.assertEquals; public class ComponentFactoryTest { @Test public void testExternal() { Component external = ComponentFactory.external("test"); assertEquals("test", external.getLayoutComponent().getProperties().get(COMPONENT_ID_KEY)); } @Test public void testHtml() { Component html = ComponentFactory.html("test"); assertEquals("test", html.getLayoutComponent().getProperties().get(HTML_CODE_PROP)); } @Test public void testLogo() { Component logo = ComponentFactory.logo("src"); assertEquals(LOGO_ID, logo.getLayoutComponent().getProperties().get(COMPONENT_ID_KEY)); assertEquals("src", logo.getLayoutComponent().getProperties().get(LOGO_ID + "." + LOGO_URL_PROP)); } @Test public void testHeatmap() { DisplayerSettings settings = DisplayerSettingsFactory.newExternalDisplayerSettings().buildSettings(); Component heatmap = ComponentFactory.processHeatmap("server", "container", "process", settings); assertEquals(COMPONENT_ID, heatmap.getLayoutComponent().getProperties().get(COMPONENT_ID_KEY)); assertEquals("server", settings.getComponentProperty(SERVER_TEMPLATE_PARAM)); assertEquals("container", settings.getComponentProperty(CONTAINER_ID_PARAM)); assertEquals("process", settings.getComponentProperty(PROCESS_ID_PARAM)); } @Test public void testAllProcessesHeatmap() { DisplayerSettings settings = DisplayerSettingsFactory.newExternalDisplayerSettings().buildSettings(); Component allProcessHeatmap = ComponentFactory.allProcessesHeatmap("server", settings); assertEquals(AllProcessesHeatmapBuilder.COMPONENT_ID, allProcessHeatmap.getLayoutComponent().getProperties().get(COMPONENT_ID_KEY)); assertEquals("server", settings.getComponentProperty(AllProcessesHeatmapBuilder.SERVER_TEMPLATE_PARAM)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/factory/component/DisplayerBuilderTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.component; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.dsl.model.Component; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class DisplayerBuilderTest { @Test public void testDisplayerJson() { DisplayerSettings settings = DisplayerSettingsFactory.newAreaChartSettings() .subType_Area() .dataset("test") .buildSettings(); String json = DisplayerSettingsJSONMarshaller.get().toJsonString(settings); Component comp = DisplayerBuilder.create(settings).build(); assertEquals(json, comp.getLayoutComponent().getProperties().get("json")); } @Test(expected = IllegalArgumentException.class) public void testSettingsMissingDataSetUUID() { DisplayerSettings settings = DisplayerSettingsFactory.newAreaChartSettings() .subType_Area() .buildSettings(); DisplayerBuilder.create(settings).build(); } @Test(expected = IllegalArgumentException.class) public void testSettingsEmptyDataSetUUID() { DisplayerSettings settings = DisplayerSettingsFactory.newAreaChartSettings() .subType_Area() .dataset(" ") .buildSettings(); DisplayerBuilder.create(settings).build(); } @Test public void testWithDataSet() { DisplayerSettings settings = DisplayerSettingsFactory.newAreaChartSettings() .subType_Area() .dataset(DataSetFactory.newEmptyDataSet()) .buildSettings(); assertNotNull(DisplayerBuilder.create(settings).build()); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/factory/page/ComponentBuilderTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import org.dashbuilder.dsl.model.Column; import org.dashbuilder.dsl.model.Component; import org.junit.Test; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import static org.junit.Assert.assertEquals; public class ComponentBuilderTest { @Test public void testColumnBuilderProperties() { Column column = ColumnBuilder.newBuilder().property("key", "value").build(); assertEquals("value", column.getLayoutColumn().getProperties().get("key")); } @Test public void testColumnBuilderComponent() { LayoutComponent lt = new LayoutComponent(); Component comp = Component.create(lt); Column column = ColumnBuilder.newBuilder().component(comp).build(); assertEquals(lt, column.getLayoutColumn().getLayoutComponents().get(0)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/factory/page/PageBuilderTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import org.dashbuilder.dsl.model.Column; import org.dashbuilder.dsl.model.Component; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.dsl.model.Row; import org.junit.Test; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import static org.junit.Assert.assertEquals; public class PageBuilderTest { @Test public void testPageBuilderProperties() { String name = "pageName"; Page page = PageBuilder.newBuilder(name).property("key", "value").build(); assertEquals(name, page.getLayoutTemplate().getName()); assertEquals("value", page.getLayoutTemplate().getLayoutProperties().get("key")); } @Test public void testPageBuilderComponent() { LayoutComponent lt = new LayoutComponent(); Component comp = Component.create(lt); Column column = ColumnBuilder.newBuilder().component(comp).build(); Row row = RowBuilder.newBuilder().column(column).build(); Page page = PageBuilder.newBuilder("test").row(row).build(); assertEquals(lt, page.getLayoutTemplate() .getRows().get(0) .getLayoutColumns().get(0) .getLayoutComponents().get(0)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/factory/page/RowBuilderTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.factory.page; import org.dashbuilder.dsl.model.Column; import org.dashbuilder.dsl.model.Component; import org.dashbuilder.dsl.model.Row; import org.junit.Test; import org.uberfire.ext.layout.editor.api.editor.LayoutComponent; import static org.junit.Assert.assertEquals; public class RowBuilderTest { @Test public void testRowBuilderProperties() { Row row = RowBuilder.newBuilder().property("key", "value").build(); assertEquals("value", row.getLayoutRow().getProperties().get("key")); } @Test public void testRowBuilderComponent() { LayoutComponent lt = new LayoutComponent(); Component comp = Component.create(lt); Column column = ColumnBuilder.newBuilder().component(comp).build(); Row row = RowBuilder.newBuilder().column(column).build(); assertEquals(lt, row.getLayoutRow().getLayoutColumns().get(0).getLayoutComponents().get(0)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/serialization/DashboardExporterTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.serialization; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.junit.Test; import static java.util.Arrays.asList; import static org.dashbuilder.dsl.factory.component.ComponentFactory.displayer; import static org.dashbuilder.dsl.factory.dashboard.DashboardFactory.dashboard; import static org.dashbuilder.dsl.factory.page.PageFactory.page; import static org.dashbuilder.dsl.factory.page.PageFactory.row; public class DashboardExporterTest { @Test(expected = IllegalArgumentException.class) public void testBadExportShouldThrowException() { DisplayerSettings settings = DisplayerSettingsFactory.newAreaChartSettings().subType_Area().dataset("missing").buildSettings(); DashboardExporter.get().validate(dashboard(asList(page("test", row(displayer(settings)))))); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/serialization/impl/DashboardZipSerializerTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.serialization.impl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.Position; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.model.Navigation; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.navigation.json.NavTreeJSONMarshaller; import org.junit.Before; import org.junit.Test; import org.uberfire.ext.layout.editor.api.css.CssProperty; import static java.util.Arrays.asList; import static org.dashbuilder.dataset.def.DataSetDefFactory.newCSVDataSetDef; import static org.dashbuilder.displayer.DisplayerSettingsFactory.newLineChartSettings; import static org.dashbuilder.displayer.DisplayerSettingsFactory.newSelectorSettings; import static org.dashbuilder.dsl.factory.component.ComponentFactory.external; import static org.dashbuilder.dsl.factory.dashboard.DashboardFactory.dashboard; import static org.dashbuilder.dsl.factory.navigation.NavigationFactory.group; import static org.dashbuilder.dsl.factory.navigation.NavigationFactory.item; import static org.dashbuilder.dsl.factory.navigation.NavigationFactory.navigation; import static org.dashbuilder.dsl.factory.page.PageFactory.page; import static org.dashbuilder.dsl.factory.page.PageFactory.pageBuilder; import static org.dashbuilder.dsl.factory.page.PageFactory.row; import static org.junit.Assert.assertEquals; public class DashboardZipSerializerTest { String csvFilePath = this.getClass().getResource("/data/un_world_pop_medium_variant.csv").getFile(); private DashboardZipSerializer serializer; @Before public void before() { serializer = new DashboardZipSerializer(); } @Test public void testExportedStaticFiles() throws IOException { DataSetDef def = newCSVDataSetDef().uuid("myDs") .filePath(csvFilePath) .separatorChar(',') .quoteChar('"') .column("Year", ColumnType.NUMBER) .cacheOff() .buildDef(); Page page = page("My Page", row(external("comp1"))); Path componentsPath = Paths.get(this.getClass().getResource("/components").getFile()); ByteArrayOutputStream out = new ByteArrayOutputStream(); serializer.serialize(dashboard(asList(page), asList(def), componentsPath), out); Map content = serializer.readAllEntriesContent(new ByteArrayInputStream(out.toByteArray())); assertEquals(read("/components/comp1/manifest.json"), content.get("dashbuilder/components/comp1/manifest.json")); assertEquals(read("/components/comp1/index.html"), content.get("dashbuilder/components/comp1/index.html")); assertEquals(read("/components/comp1/index.js"), content.get("dashbuilder/components/comp1/index.js")); assertEquals(read("/data/un_world_pop_medium_variant.csv"), content.get("dashbuilder/datasets/definitions/myDs.csv")); } @Test public void testExportedZip() throws Exception { DataSetDef def = newCSVDataSetDef().uuid(UUID.randomUUID().toString()) .filePath(csvFilePath) .separatorChar(',') .quoteChar('"') .buildDef(); DisplayerSettings filterByYear = newSelectorSettings().subtype(DisplayerSubType.SELECTOR_SLIDER) .width(1200) .filterOn(false, true, false) .dataset(def.getUUID()) .column("Year") .buildSettings(); DisplayerSettings evolutionChart = newLineChartSettings().subType_SmoothLine() .dataset(def.getUUID()) .width(1200) .legendOn(Position.IN) .xAxisAngle(0) .margins(0, 30, 0, 0) .filterOn(false, false, true) .group("Year") .column("Year") .expression("parseInt(value)") .column("PopTotal", AggregateFunctionType.SUM, "Total") .column("PopFemale", AggregateFunctionType.SUM, "Female") .column("PopMale", AggregateFunctionType.SUM, "Male") .buildSettings(); Page page = pageBuilder("Population").cssProperty(CssProperty.MARGIN_LEFT, "10px") .rows(row("

    Population growth until 2100

    "), row(filterByYear), row(evolutionChart)) .build(); Navigation navigation = navigation(group("Test Group", item(page))); Dashboard db = dashboard(asList(page), asList(def), navigation); String navTreeString = NavTreeJSONMarshaller.get().toJson(navigation.getNavTree()).toString(); ByteArrayOutputStream out = new ByteArrayOutputStream(); serializer.serialize(db, out); Dashboard deserialized = serializer.internalDeserialize(new ByteArrayInputStream(out.toByteArray())); assertEquals(page.getLayoutTemplate().getName(), deserialized.getPages().get(0).getLayoutTemplate().getName()); assertEquals(def.getUUID(), deserialized.getDataSets().get(0).getUUID()); assertEquals(navTreeString, NavTreeJSONMarshaller.get().toJson(deserialized.getNavigation().getNavTree()).toString()); } private String read(String path) throws IOException { return Files.readAllLines(Paths.get(this.getClass().getResource(path).getFile())).stream().collect(Collectors.joining("\n")); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/java/org/dashbuilder/dsl/validation/DashboardValidatorImplTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dsl.validation; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.dsl.model.Dashboard; import org.dashbuilder.dsl.model.Page; import org.dashbuilder.dsl.validation.ValidationResult.ValidationResultType; import org.junit.Before; import org.junit.Test; import static java.util.Arrays.asList; import static org.dashbuilder.dataset.def.DataSetDefFactory.newStaticDataSetDef; import static org.dashbuilder.displayer.DisplayerSettingsFactory.newAreaChartSettings; import static org.dashbuilder.displayer.DisplayerSettingsFactory.newExternalDisplayerSettings; import static org.dashbuilder.dsl.factory.component.ComponentFactory.displayer; import static org.dashbuilder.dsl.factory.component.ComponentFactory.external; import static org.dashbuilder.dsl.factory.dashboard.DashboardFactory.dashboard; import static org.dashbuilder.dsl.factory.navigation.NavigationFactory.group; import static org.dashbuilder.dsl.factory.navigation.NavigationFactory.item; import static org.dashbuilder.dsl.factory.navigation.NavigationFactory.navigation; import static org.dashbuilder.dsl.factory.page.PageFactory.page; import static org.dashbuilder.dsl.factory.page.PageFactory.row; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class DashboardValidatorImplTest { private DashboardValidatorImpl impl; private Path componentsPath; @Before public void before() throws IOException { impl = new DashboardValidatorImpl(); componentsPath = Paths.get(this.getClass().getResource("/components").getFile()); } @Test public void testMissingDataSet() { DisplayerSettings settings = newAreaChartSettings().subType_Area().dataset("nonExisting").buildSettings(); Page page = page("abc", row(displayer(settings))); Dashboard dashboard = dashboard(asList(page)); List results = impl.validate(dashboard); ValidationResult result = results.get(0); assertEquals(1, results.size()); assertEquals("The following data sets definitions used in page abc were not found: nonExisting", result.getMessage()); assertEquals(ValidationResult.ValidationResultType.ERROR, result.getType()); } @Test public void testDataSetFound() { DataSetDef def = newStaticDataSetDef().uuid("myds").buildDef(); DisplayerSettings settings = newAreaChartSettings().subType_Area().dataset(def.getUUID()).buildSettings(); Page page = page("abc", row(displayer(settings))); Dashboard dashboard = dashboard(asList(page), asList(def)); List results = impl.validate(dashboard); ValidationResult result = results.get(0); assertEquals(1, results.size()); assertEquals("No missing data set dependencies for page abc", result.getMessage()); assertEquals(ValidationResult.ValidationResultType.SUCCESS, result.getType()); } @Test public void testMissingComponent() { DisplayerSettings settings = DisplayerSettingsFactory.newExternalDisplayerSettings().buildSettings(); Page page = page("abc", row(external("missingComp", settings))); Dashboard dashboard = dashboard(asList(page)); List results = impl.validate(dashboard); ValidationResult result = results.get(0); assertEquals(1, results.size()); assertEquals("The following components used in page abc were not found: missingComp", result.getMessage()); assertEquals(ValidationResult.ValidationResultType.WARNING, result.getType()); } @Test public void testExistingComponent() { DisplayerSettings settings = newExternalDisplayerSettings().buildSettings(); Page page = page("abc", row(external("comp1", settings))); Dashboard dashboard = dashboard(asList(page), componentsPath); List results = impl.validate(dashboard); assertEquals(1, results.size()); assertEquals("No missing component dependencies for page abc", results.get(0).getMessage()); } @Test public void testMissingNavigationItem() { Page page = page("page"); Page page2 = page("page2"); Dashboard dashboard = dashboard(asList(page), navigation(group("test", item(page2)))); List results = impl.validate(dashboard); ValidationResult result = results.get(0); assertEquals(1, results.size()); assertEquals("Navigation item page2 has no corresponding page", result.getMessage()); assertEquals(ValidationResult.ValidationResultType.ERROR, result.getType()); } @Test public void testNavigationWithMissingGroup() { Page page = page("page"); Dashboard dashboard = dashboard(asList(page), navigation(group("test", item(page)), group("test", item(page)))); List results = impl.validate(dashboard); ValidationResult result = results.get(0); assertEquals(1, results.size()); assertEquals("The Navigation constains duplicate group names", result.getMessage()); assertEquals(ValidationResult.ValidationResultType.ERROR, result.getType()); } @Test public void testNavigationCorrect() { Page page = page("page"); Dashboard dashboard = dashboard(asList(page), navigation(group("test", item(page)))); List results = impl.validate(dashboard); ValidationResult result = results.get(0); assertEquals(1, results.size()); assertEquals("Navigation is valid", result.getMessage()); assertEquals(ValidationResult.ValidationResultType.SUCCESS, result.getType()); } @Test public void testSuccessfulValidation() { DataSetDef def = newStaticDataSetDef().uuid("myds").buildDef(); DisplayerSettings settings = newAreaChartSettings().subType_Area().dataset(def.getUUID()).buildSettings(); DisplayerSettings externalSettings = newExternalDisplayerSettings().buildSettings(); Page page = page("abc", row(external("comp1", externalSettings)), row(displayer(settings))); Dashboard dashboard = dashboard(asList(page), asList(def), navigation(group("test", item(page))), componentsPath); List results = impl.validate(dashboard); assertEquals(3, results.size()); assertTrue(results.stream().allMatch(r -> r.type == ValidationResultType.SUCCESS)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/resources/components/comp1/index.html ================================================

    Comp1

    ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/resources/components/comp1/index.js ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function sayHello() { alert("NEVER, it is just the beginning!") } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/resources/components/comp1/manifest.json ================================================ { "name": "My Component1" } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-dsl/src/test/resources/data/un_world_pop_medium_variant.csv ================================================ "Year","PopMale","PopFemale","PopTotal","PopDensity" 1950,1266259.556,1270171.462,2536431.018,19.497 1951,1290237.638,1293796.589,2584034.227,19.863 1952,1313854.565,1317007.125,2630861.69,20.223 1953,1337452.786,1340156.275,2677609.061,20.582 1954,1361313.834,1363532.92,2724846.754,20.945 1955,1385658.299,1387361.616,2773019.915,21.316 1956,1410643.208,1411800.046,2822443.254,21.695 1957,1436364.62,1436941.438,2873306.058,22.086 1958,1462864.322,1462822.358,2925686.68,22.489 1959,1490141.399,1489434.748,2979576.147,22.903 1960,1518186.702,1516763.013,3034949.715,23.329 1961,1547019.353,1544824.16,3091843.513,23.766 1962,1576718.903,1573701.858,3150420.761,24.216 1963,1607439.247,1603561.699,3211000.946,24.682 1964,1639369.328,1634608.944,3273978.272,25.166 1965,1672618.879,1666964.631,3339583.51,25.671 1966,1707237.638,1700684.993,3407922.631,26.196 1967,1743114.222,1735655.882,3478770.104,26.74 1968,1779990.92,1771608.516,3551599.436,27.3 1969,1817510.8,1808170.165,3625680.965,27.87 1970,1855390.166,1845046.876,3700437.042,28.444 1971,1893576.318,1882183.712,3775760.03,29.023 1972,1932065.884,1919584.704,3851650.588,29.607 1973,1970688.779,1957091.74,3927780.519,30.192 1974,2009259.494,1994534.684,4003794.178,30.776 1975,2047666.026,2031814.448,4079480.474,31.358 1976,2085824.453,2068842.374,4154666.827,31.936 1977,2123811.87,2105694.049,4229505.919,32.511 1978,2161887.592,2142646.007,4304533.599,33.088 1979,2200418.504,2180087.681,4380506.185,33.672 1980,2239689.027,2218314.439,4458003.466,34.268 1981,2279673.275,2257323.344,4536996.619,34.875 1982,2320329.605,2297056.921,4617386.526,35.493 1983,2361892.584,2337676.603,4699569.187,36.124 1984,2404645.374,2379366.143,4784011.517,36.773 1985,2448724.603,2422197.063,4870921.666,37.442 1986,2494279.319,2466288.681,4960568,38.131 1987,2541075.233,2511446.765,5052521.998,38.837 1988,2588387.929,2557038.065,5145425.994,39.552 1989,2635233.492,2602207.942,5237441.434,40.259 1990,2680895.262,2646335.779,5327231.041,40.949 1991,2725113.179,2689176.204,5414289.383,41.618 1992,2768050.729,2730869.164,5498919.893,42.269 1993,2809940.82,2771656.778,5581597.598,42.904 1994,2851196.996,2811953.432,5663150.428,43.531 1995,2892141.549,2852071.381,5744212.93,44.154 1996,2932815.962,2892075.969,5824891.931,44.774 1997,2973160.99,2931884.657,5905045.647,45.391 1998,3013295.709,2971498.366,5984794.075,46.004 1999,3053349.42,3010889.613,6064239.033,46.614 2000,3093433.858,3050059.948,6143493.806,47.223 2001,3133601.761,3089024.77,6222626.531,47.832 2002,3173900.449,3127872.723,6301773.172,48.44 2003,3214422.031,3166763.11,6381185.141,49.051 2004,3255262.626,3205896.765,6461159.391,49.665 2005,3296485.267,3245421.689,6541906.956,50.286 2006,3338132.929,3285384.988,6623517.917,50.913 2007,3380183.02,3325763.623,6705946.643,51.547 2008,3422546.382,3366542.29,6789088.672,52.186 2009,3465089.423,3407677.565,6872766.988,52.829 2010,3507703.635,3449119.953,6956823.588,53.475 2011,3550332.593,3490861.575,7041194.168,54.124 2012,3592963.006,3532864.951,7125827.957,54.774 2013,3635575.332,3575006.709,7210582.041,55.426 2014,3678161.837,3617128.922,7295290.759,56.077 2015,3720696.374,3659100.593,7379796.967,56.727 2016,3763157.221,3700864.713,7464021.934,57.374 2017,3805469.093,3742389.807,7547858.9,58.018 2018,3847487.861,3783603.252,7631091.113,58.658 2019,3889034.611,3824433.594,7713468.205,59.291 2020,3929973.953,3864824.776,7794798.729,59.917 2021,3970238.39,3904727.342,7874965.732,60.533 2022,4009829.762,3944122.815,7953952.577,61.14 2023,4048771.753,3983028.585,8031800.338,61.738 2024,4087120.942,4021484.313,8108605.255,62.329 2025,4124919.51,4059517.943,8184437.453,62.912 2026,4162157.763,4097118.888,8259276.651,63.487 2027,4198812.392,4134265.926,8333078.318,64.054 2028,4234898.159,4170965.142,8405863.301,64.614 2029,4270434.917,4207225.806,8477660.723,65.166 2030,4305436.923,4243050.448,8548487.371,65.71 2031,4339910.899,4278438.555,8618349.454,66.247 2032,4373852.542,4313375.331,8687227.873,66.777 2033,4407252.206,4347831.306,8755083.512,67.298 2034,4440095.078,4381767.627,8821862.705,67.811 2035,4472370.475,4415153.754,8887524.229,68.316 2036,4504074.999,4447973.886,8952048.885,68.812 2037,4535212.764,4480224.852,9015437.616,69.299 2038,4565789.971,4511903.674,9077693.645,69.778 2039,4595815.916,4543012.646,9138828.562,70.248 2040,4625296.608,4573550.774,9198847.382,70.709 2041,4654233.007,4603512.476,9257745.483,71.162 2042,4682621.46,4632886.693,9315508.153,71.606 2043,4710457.197,4661661.05,9372118.247,72.041 2044,4737734.143,4689821.239,9427555.382,72.467 2045,4764446.974,4717356.298,9481803.272,72.884 2046,4790594.206,4744260.467,9534854.673,73.292 2047,4816175.052,4770532.697,9586707.749,73.691 2048,4841185.259,4796172.061,9637357.32,74.08 2049,4865620.226,4821179.92,9686800.146,74.46 2050,4889476.137,4845557.763,9735033.9,74.831 2051,4912753.77,4869307.988,9782061.758,75.192 2052,4935453.691,4892431.75,9827885.441,75.544 2053,4957572.608,4914928.954,9872501.562,75.887 2054,4979106.4,4936798.851,9915905.251,76.221 2055,5000054.515,4958044.231,9958098.746,76.545 2056,5020416.864,4978668.303,9999085.167,76.86 2057,5040200.141,4998681.121,10038881.262,77.166 2058,5059417.113,5018100.967,10077518.08,77.463 2059,5078085.161,5036951.199,10115036.36,77.752 2060,5096218.399,5055251.284,10151469.683,78.032 2061,5113824.311,5073012.898,10186837.209,78.304 2062,5130906.26,5090242.78,10221149.04,78.567 2063,5147469.268,5106949.736,10254419.004,78.823 2064,5163517.276,5123141.078,10286658.354,79.071 2065,5179054.658,5138824.657,10317879.315,79.311 2066,5194087.269,5154010.81,10348098.079,79.543 2067,5208621.301,5168709.529,10377330.83,79.768 2068,5222662.003,5182928.529,10405590.532,79.985 2069,5236214.417,5196674.719,10432889.136,80.195 2070,5249283.714,5209955.787,10459239.501,80.398 2071,5261875.63,5222779.228,10484654.858,80.593 2072,5273995.495,5235154.907,10509150.402,80.781 2073,5285647.053,5247095.808,10532742.861,80.963 2074,5296833.337,5258616.666,10555450.003,81.137 2075,5307558.352,5269729.843,10577288.195,81.305 2076,5317828.46,5280445.712,10598274.172,81.466 2077,5327650.719,5290770.19,10618420.909,81.621 2078,5337030.84,5300705.979,10637736.819,81.77 2079,5345975.152,5310253.081,10656228.233,81.912 2080,5354490.414,5319414.04,10673904.454,82.048 2081,5362581.26,5328192.075,10690773.335,82.177 2082,5370256.1,5336596.326,10706852.426,82.301 2083,5377530.581,5344640.794,10722171.375,82.419 2084,5384423.298,5352342.146,10736765.444,82.531 2085,5390949.038,5359713.315,10750662.353,82.638 2086,5397115.414,5366758.609,10763874.023,82.739 2087,5402924.365,5373477.654,10776402.019,82.835 2088,5408377.091,5379871.857,10788248.948,82.927 2089,5413472.043,5385941.323,10799413.366,83.012 2090,5418208.072,5391684.231,10809892.303,83.093 2091,5422585.514,5397097.129,10819682.643,83.168 2092,5426605.849,5402175.11,10828780.959,83.238 2093,5430270.716,5406911.361,10837182.077,83.303 2094,5433580.881,5411297.917,10844878.798,83.362 2095,5436535.751,5415324.394,10851860.145,83.416 2096,5439132.293,5418979.294,10858111.587,83.464 2097,5441365.752,5422249.024,10863614.776,83.506 2098,5443228.989,5425118.647,10868347.636,83.542 2099,5444712.816,5427571.318,10872284.134,83.573 2100,5445805.463,5429588.256,10875393.719,83.596 ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/.gitignore ================================================ node_modules/ dist/ coverage/ target/ ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/README.md ================================================ Dashbuilder JS == This package provides the public Dashbuilder Components API along with internal supported components. It is packaged as a JAR and consumed by components API to expose the internal components. ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: [ "default", [ "jest-junit", { /* * Removes spaces from test titles and makes first * letter of each word capitalized. * * unit test -> UnitTest * * See junit.xml report for resulting look. */ titleTemplate: (vars) => { var str = vars.title.toLowerCase(); str = str.split(' '); for (var i = 0; i < str.length; i++) { str[i] = str[i].charAt(0).toUpperCase() + str[i].slice(1); } var result = str.join(''); return result.replace(','); } } ] ], moduleDirectories: ["node_modules", "packages/*"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/package.json ================================================ { "name": "dashbuilder-components", "version": "0.0.0", "description": "", "license": "Apache-2.0", "main": "./dist/dashbuilder-components.js", "types": "./dist/index.d.ts", "private": true, "workspaces": [ "packages/*" ], "dependencies": { "@types/react": "^16.8.8", "@types/react-dom": "^16.8.2", "react": "^16.12.0", "react-dom": "^16.12.0" }, "scripts": { "init": "yarn install --force", "build:fast": "yarn workspaces run build:fast", "build:prod": "yarn workspaces run build:prod" }, "jest-junit": { "outputDirectory": "./target", "suiteName": "org.dashbuilder.components.tests", "suiteNameTemplate": "{filename}", "classNameTemplate": "org.dashbuilder.components.tests.{filename}.{classname}" }, "devDependencies": { "@babel/core": "^7.7.2", "@babel/preset-env": "^7.7.1", "@babel/preset-react": "^7.7.0", "@testing-library/jest-dom": "^5.3.0", "@testing-library/react": "^10.0.2", "@testing-library/react-hooks": "^3.2.1", "@types/jest": "^25.2.3", "@types/mocha": "^5.2.7", "@types/node": "^12.12.5", "@types/react": "^16.8.8", "@types/react-dom": "^16.8.2", "@types/react-router": "^5.1.1", "@types/react-router-dom": "^5.1.1", "babel-loader": "^8.0.6", "circular-dependency-plugin": "^5.2.0", "clean-webpack-plugin": "^0.1.19", "copy-webpack-plugin": "^5.1.0", "cross-var": "^1.1.0", "css-loader": "^3.2.0", "jest": "^25.2.7", "jest-junit": "^9.0.0", "jest-webextension-mock": "^3.5.0", "node-sass": "^7.0.0", "null-loader": "^3.0.0", "prettier": "^1.19.1", "style-loader": "^1.0.0", "ts-jest": "^25.5.1", "ts-loader": "^6.2.1", "tslint": "^5.12.1", "tslint-config-prettier": "^1.15.0", "tslint-react": "^3.6.0", "typescript": "^3.8.3", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.11.3", "webpack-merge": "^5.0.9", "webpack-node-externals": "^1.7.2" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/package.json ================================================ { "name": "@dashbuilder-js/component-api", "version": "0.2.0", "description": "Dashbuilder API to create external visual components.", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --verbose --silent --passWithNoTests", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "start": "webpack-dev-server -d --host 0.0.0.0" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/ComponentApi.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { DataSet } from "./dataset"; import { BrowserComponentBus } from "./controller/BrowserComponentBus"; import { DashbuilderComponentController } from "./controller/DashbuilderComponentController"; import { DashbuilderComponentDispatcher } from "./controller/DashbuilderComponentDispatcher"; import { ComponentBus, ComponentController } from "./controller"; export class ComponentApi { private bus: ComponentBus; private controller: DashbuilderComponentController; private listener: DashbuilderComponentDispatcher; constructor() { this.bus = new BrowserComponentBus(); this.controller = new DashbuilderComponentController(this.bus); this.listener = new DashbuilderComponentDispatcher(this.bus, this.controller); this.listener.init(); } public getComponentController( onInit?: (params: Map) => void, onDataSet?: (dataSet: DataSet, params?: Map) => void ): ComponentController { if (onInit) { this.controller.setOnInit(onInit); } if (onDataSet) { this.controller.setOnDataSet(onDataSet); } return this.controller; } public restart() { this.destroy(); this.listener.init(); } public destroy() { this.listener.stop(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/__tests__/api.test.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ComponentBus } from "../controller"; import { ComponentApi } from "../ComponentApi"; import { ColumnType, DataSet, FilterRequest } from "../dataset"; import { FunctionCallRequest, FunctionResponse, FunctionResultType } from "../function"; import { ComponentMessage, MessageType } from "../message"; import { MessageProperty } from "../message/MessageProperty"; import { DashbuilderComponentController } from "../controller/DashbuilderComponentController"; const controller = new ComponentApi().getComponentController() as DashbuilderComponentController; const sampleDataSet: DataSet = { columns: [ { name: "Name", type: ColumnType.LABEL, settings: { columnId: "name", columnName: "Name", valueExpression: "value", emptyTemplate: "---" } }, { name: "Age", type: ColumnType.NUMBER, settings: { columnId: "age", columnName: "age", valueExpression: "value", emptyTemplate: "---", valuePattern: "#,##0.00" } } ], data: [["John", "32"]] }; describe("[Controller API] Callbacks", () => { it("INIT Callback without params", async () => { const handleInit = jest.fn(); controller.setOnInit(handleInit); await postInitMessage(new Map()); expect(handleInit).toHaveBeenCalledTimes(1); }); it("INIT Callback with params", async () => { const handleInit = jest.fn(); const params = new Map(); params.set("hello", "world"); controller.setOnInit(handleInit); await postInitMessage(params); expect(handleInit).toHaveBeenCalledWith(params); }); it("DataSet Callback", async () => { const handleDataSet = jest.fn(); controller.setOnDataSet(handleDataSet); await postDataSetMessage(); expect(handleDataSet).toHaveBeenCalledWith(sampleDataSet, expect.any(Map)); }); }); describe("[Controller API] Sending Requests", () => { const bus = mockBus(); const componentId = "42"; beforeAll(() => { const params = new Map(); params.set(MessageProperty.COMPONENT_ID, componentId); controller.init(params); controller.setComponentBus(bus); }); it("Configuration Issues", async () => { const configIssue = "some configuration issue."; const params = new Map(); const expected: ComponentMessage = { type: MessageType.FIX_CONFIGURATION, properties: params }; params.set(MessageProperty.CONFIGURATION_ISSUE, configIssue); controller.requireConfigurationFix(configIssue); await delay(0); expect(bus.send).toBeCalledWith(componentId, expected); }); it("Configuration Fixed", async () => { const message: ComponentMessage = { type: MessageType.CONFIGURATION_OK, properties: new Map() }; controller.configurationOk(); await delay(0); expect(bus.send).toBeCalledWith(componentId, message); }); it("Filter", async () => { const filterRequest: FilterRequest = { column: 1, reset: false, row: 1 }; const props = new Map(); props.set(MessageProperty.FILTER, filterRequest); const message: ComponentMessage = { type: MessageType.FILTER, properties: props }; controller.filter(filterRequest); expect(bus.send).toBeCalledWith(componentId, message); }); }); describe("[Controller API] Function Calls", () => { it("Function Success", async () => { const functionCall = buildFunctionCallRequest(); const callPromise = controller.callFunction(functionCall); await delay(0); const result = "SUCCESS RESULT"; const response = buildFunctionResponse(functionCall, result, FunctionResultType.SUCCESS); window.postMessage(response, window.location.origin); return expect(callPromise).resolves.toBe(result); }); it("Function Success", async () => { const functionCall = buildFunctionCallRequest(); const callPromise = controller.callFunction(functionCall); await delay(0); const result = "SUCCESS RESULT"; const response = buildFunctionResponse(functionCall, result, FunctionResultType.SUCCESS); window.postMessage(response, window.location.origin); return expect(callPromise).resolves.toBe(result); }); it("Function Not Found", async () => { const functionCall = buildFunctionCallRequest(); const callPromise = controller.callFunction(functionCall); await delay(0); const message = "NOT FOUND RESULT"; const response = buildFunctionResponse(functionCall, "", FunctionResultType.NOT_FOUND, message); window.postMessage(response, window.location.origin); return expect(callPromise).rejects.toBe(message); }); it("Function Execution Error", async () => { const functionCall = buildFunctionCallRequest(); const callPromise = controller.callFunction(functionCall); await delay(0); const message = "ERROR RESULT"; const response = buildFunctionResponse(functionCall, "", FunctionResultType.ERROR, message); window.postMessage(response, window.location.origin); return expect(callPromise).rejects.toBe(message); }); }); function buildFunctionCallRequest(): FunctionCallRequest { const functionParams = new Map(); functionParams.set("test", "test"); return { functionName: "test function name", parameters: functionParams }; } const delay = (ms: number) => { return new Promise(res => setTimeout(res, ms)); }; async function postDataSetMessage() { const params = new Map(); params.set("dataSet", sampleDataSet); const datasetMsg: ComponentMessage = { type: MessageType.DATASET, properties: params }; await postMessage(datasetMsg); } async function postInitMessage(params: Map) { const init: ComponentMessage = { type: MessageType.INIT, properties: params }; await postMessage(init); } async function postMessage(message: ComponentMessage) { window.postMessage(message, window.location.origin); await delay(0); } function mockBus(): ComponentBus { return { destroy: jest.fn(), start: jest.fn(), send: jest.fn(), setListener: jest.fn() }; } function buildFunctionResponse( _request: FunctionCallRequest, _result: string, _type: FunctionResultType, _message?: string ) { // sends the response here const functionResponse: FunctionResponse = { message: _message || "success", resultType: _type, result: _result, request: _request }; const params = new Map(); const functionResponseMessage: ComponentMessage = { type: MessageType.FUNCTION_RESPONSE, properties: params }; params.set(MessageProperty.FUNCTION_RESPONSE, functionResponse); return functionResponseMessage; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/controller/BrowserComponentBus.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ComponentMessage, MessageProperty } from "../message"; import { ComponentBus } from "./ComponentBus"; export class BrowserComponentBus implements ComponentBus { private listener: (message: ComponentMessage) => void; private readonly messageListener = (e: MessageEvent) => { this.listener(e.data as ComponentMessage); }; public start() { window.addEventListener("message", this.messageListener, false); } public send(componentId: string, message: ComponentMessage): void { console.debug("[BrowserComponentBus] Sending Message"); console.debug(message); message.properties.set(MessageProperty.COMPONENT_ID, componentId); window.parent.postMessage(message, window.location.href); } public setListener(onMessage: (message: ComponentMessage) => void): void { this.listener = onMessage; } public destroy(): void { window.removeEventListener("message", this.messageListener, false); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/controller/ComponentBus.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ComponentMessage } from "../message"; export interface ComponentBus { start(): void; send(componentId: string, message: ComponentMessage): void; setListener(onMessage: (message: ComponentMessage) => void): void; destroy(): void; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/controller/ComponentController.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { DataSet, FilterRequest } from "../dataset"; import { FunctionCallRequest } from "../function"; /* * Controls component lifecycle and allows component communicate with Dashbuilder */ export interface ComponentController { /* * Set on init callback */ setOnInit(onInit: (params: Map) => void): void; /* * Sets the method to be called when dashbuilder sends a dataset update after a filter or when using pooling. * Params is optional and is basically the same params sent after onInit */ setOnDataSet(onDataSet: (dataSet: DataSet, params?: Map) => void): void; /* * Components must send ready their finish their setup (unless it is sent automatically by the controller implementation) */ ready(): void; /* * Components can call this if the dataset or any other configuration is wrong. The message can detail what is wrong. */ requireConfigurationFix(message: string): void; /* * Components must call this after the configuration is fixed by users. */ configurationOk(): void; /* * Used to send a filter request to Dashbuilder */ filter(filterRequest: FilterRequest): void; /* * Calls a function and returns a Promise that will be fulfilled when the response is received from DB. */ callFunction(functionCallRequest: FunctionCallRequest): Promise; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/controller/DashbuilderComponentController.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { DataSet, FilterRequest } from "../dataset"; import { FunctionCallRequest, FunctionResponse, FunctionResultType } from "../function"; import { MessageType } from "../message"; import { MessageProperty } from "../message/MessageProperty"; import { ComponentBus } from "./ComponentBus"; import { ComponentController } from "./ComponentController"; interface FunctionCallbacks { onSucess: (result: any) => void; onError: (message: string) => void; } export class DashbuilderComponentController implements ComponentController { private callbacks: Map = new Map(); constructor(private bus: ComponentBus, private componentId?: string) { // no op } public onInit: (params: Map) => void = p => { console.debug("Received INIT."); console.debug(p); }; public onDataSet: (dataSet: DataSet, params?: Map) => void = ds => { console.debug("Received DataSet."); console.debug(ds); }; public init(params: Map) { this.componentId = params.get(MessageProperty.COMPONENT_ID); this.onInit(params); } public setOnDataSet(onDataSet: (dataSet: DataSet, params?: Map) => void) { this.onDataSet = onDataSet; } public setOnInit(onInit: (params: Map) => void) { this.onInit = onInit; } public ready(): void { // do nothing because it is not support ATM } public requireConfigurationFix(message: string): void { const props = new Map(); props.set(MessageProperty.CONFIGURATION_ISSUE, message); this.bus.send(this.componentId!, { type: MessageType.FIX_CONFIGURATION, properties: props }); } public configurationOk(): void { this.bus.send(this.componentId!, { type: MessageType.CONFIGURATION_OK, properties: new Map() }); } public filter(filterRequest: FilterRequest): void { const props = new Map(); props.set(MessageProperty.FILTER, filterRequest); this.bus.send(this.componentId!, { type: MessageType.FILTER, properties: props }); } public callFunction(functionCallRequest: FunctionCallRequest): Promise { const props = new Map(); props.set(MessageProperty.FUNCTION_CALL, functionCallRequest); this.bus.send(this.componentId!, { type: MessageType.FUNCTION_CALL, properties: props }); return new Promise((resolve, error) => { const key = this.buildFunctionKey(functionCallRequest); this.callbacks.set(key, { onSucess: resolve, onError: error }); }); } public receiveFunctionResponse(functionResponse: FunctionResponse): void { const key = this.buildFunctionKey(functionResponse.request); const functionCallbacks = this.callbacks.get(key); if (functionCallbacks) { if ( functionResponse.resultType === FunctionResultType.ERROR || functionResponse.resultType === FunctionResultType.NOT_FOUND ) { functionCallbacks.onError(functionResponse.message); } else { functionCallbacks.onSucess(functionResponse.result); } } else { console.warn("Callbacks for function call not found. Key: " + key); } this.callbacks.delete(key); } public setComponentBus(bus: ComponentBus) { this.bus = bus; } private buildFunctionKey(functionRequest: FunctionCallRequest): string { return functionRequest.functionName; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/controller/DashbuilderComponentDispatcher.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { DataSet } from "../dataset"; import { FunctionResponse } from "../function"; import { ComponentMessage, MessageType } from "../message"; import { MessageProperty } from "../message/MessageProperty"; import { ComponentBus } from "./ComponentBus"; import { DashbuilderComponentController } from "./DashbuilderComponentController"; import { InternalComponentDispatcher } from "./InternalComponentListener"; export class DashbuilderComponentDispatcher implements InternalComponentDispatcher { private componentId: string; constructor(private readonly bus: ComponentBus, public readonly componentController: DashbuilderComponentController) { // no op } private readonly messageDispatcher = (message: ComponentMessage) => { if (message.type === MessageType.INIT) { this.componentId = message.properties.get(MessageProperty.COMPONENT_ID); this.componentController.init(message.properties); } if (message.type === MessageType.DATASET) { const dataSet = message.properties.get(MessageProperty.DATASET) as DataSet; this.componentController.onDataSet(dataSet, message.properties); } if (message.type === MessageType.FUNCTION_RESPONSE) { const functionResponse = message.properties.get(MessageProperty.FUNCTION_RESPONSE) as FunctionResponse; this.componentController.receiveFunctionResponse(functionResponse); } }; public isAutoReady(): boolean { // READY not implemented at the moment return true; } public init(): void { this.bus.setListener(this.messageDispatcher); this.bus.start(); } public sendMessage(componentMessage: ComponentMessage): void { componentMessage.properties.set(MessageProperty.COMPONENT_ID, this.componentId); window.parent.postMessage(componentMessage, window.location.href); } public stop(): void { this.bus.destroy(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/controller/InternalComponentListener.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ComponentMessage } from "../message"; import { DashbuilderComponentController } from "./DashbuilderComponentController"; /* * Listener with methods that should not be exposed to components */ export interface InternalComponentDispatcher { /* * The component controller responsible to be the component's entry point to interact with Dashbuilder */ componentController: DashbuilderComponentController | undefined; /** * Starts waiting for messages to dispatch */ init(): void; /* * Sends a message to Dashbuilder */ sendMessage(componentMessage: ComponentMessage): void; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/controller/index.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./ComponentController"; export * from "./ComponentBus" ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/dataset/Column.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ColumnType } from "./ColumnType"; import { ColumnSettings } from "./ColumnSettings"; export interface Column { name: string; type: ColumnType; settings: ColumnSettings; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/dataset/ColumnSettings.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export interface ColumnSettings { columnId: string; columnName: string; valueExpression: string; emptyTemplate: string; valuePattern?: string; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/dataset/ColumnType.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export enum ColumnType { TEXT = "TEXT", LABEL = "LABEL", DATE = "DATE", NUMBER = "NUMBER" } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/dataset/DataSet.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Column } from "./Column"; export interface DataSet { columns: Column[]; data: string[][]; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/dataset/FilterRequest.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export interface FilterRequest { reset: boolean; row: number; column: number; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/dataset/index.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./ColumnSettings"; export * from "./ColumnType"; export * from "./Column"; export * from "./DataSet"; export * from "./FilterRequest"; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/function/FunctionCallRequest.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export interface FunctionCallRequest { functionName: string; parameters: Map; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/function/FunctionResponse.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { FunctionCallRequest } from "./FunctionCallRequest"; import { FunctionResultType } from "./FunctionResultType"; export interface FunctionResponse { request: FunctionCallRequest; resultType: FunctionResultType; message: string; result: any; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/function/FunctionResultType.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export enum FunctionResultType { SUCCESS = "SUCCESS", ERROR = "ERROR", NOT_FOUND = "NOT_FOUND" } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/function/index.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./FunctionCallRequest"; export * from "./FunctionResponse"; export * from "./FunctionResultType"; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/index.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./message"; export * from "./dataset"; export * from "./function"; export * from "./controller"; export * from "./ComponentApi"; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/message/ComponentMessage.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { MessageProperty } from "./MessageProperty"; import { MessageType } from "./MessageType"; export interface ComponentMessage { type: MessageType; properties: Map; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/message/MessageProperty.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Component Message Properties definition. */ export enum MessageProperty { COMPONENT_ID = "component_id", DATASET = "dataSet", CONFIGURATION_ISSUE = "configurationIssue", FILTER = "filter", FUNCTION_CALL = "functionCallRequest", FUNCTION_RESPONSE = "functionResponse" } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/message/MessageType.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export enum MessageType { INIT = "INIT", DATASET = "DATASET", FUNCTION_RESPONSE = "FUNCTION_RESPONSE", FUNCTION_CALL = "FUNCTION_CALL", FILTER = "FILTER", FIX_CONFIGURATION = "FIX_CONFIGURATION", CONFIGURATION_OK = "CONFIGURATION_OK", READY = "READY" } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/src/message/index.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./MessageType"; export * from "./MessageProperty" export * from "./ComponentMessage"; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-api/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { return merge(common, { entry: { index: "./src/index.ts" }, output: { libraryTarget: "commonjs2" } }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-dev/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-dev/package.json ================================================ { "name": "@dashbuilder-js/component-dev", "version": "0.2.0", "description": "", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --verbose --silent --passWithNoTests", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "start": "webpack-dev-server -d --host 0.0.0.0" }, "dependencies": { "@dashbuilder-js/component-api": "0.1.0" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-dev/src/ComponentDevPane.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; export interface DevPaneProps { sendInit: () => void; sendDataSet: () => void; } export function ComponentDevPane(props: DevPaneProps) { return (
    ); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-dev/src/index.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { ComponentDevPane } from "./ComponentDevPane"; import { DataSet, MessageProperty, ComponentMessage, MessageType, FunctionResponse, FunctionCallRequest, FunctionResultType } from "@dashbuilder-js/component-api"; const DEV_FILE = "/manifest.dev.json"; const COMP_ID = 42; let initMessage: ComponentMessage; let dataSetMessage: ComponentMessage; let functions: FunctionDef[]; interface Prop { key: string; value: string; } interface FunctionDef { name: string; response: string; params: Prop[]; } interface ComponentDevConfiguration { init: Prop[]; functions: FunctionDef[]; dataSet: DataSet; } function handleDevConf(text: string) { const devConf = JSON.parse(text) as ComponentDevConfiguration; const devPane = document.createElement("div"); document.body.prepend(devPane); ReactDOM.render( sendMessage(dataSetMessage)} sendInit={() => sendMessage(initMessage)} />, devPane ); window.addEventListener("message", e => { const message = e.data as ComponentMessage; if (message.type === MessageType.FUNCTION_CALL) { respondFunctionCall(message); } }); functions = devConf.functions; createInit(devConf); createDataSet(devConf); setTimeout(() => { sendMessage(initMessage); setTimeout(() => { sendMessage(dataSetMessage); }, 100); }, 100); } function respondFunctionCall(message: ComponentMessage) { const functionCall = message.properties.get(MessageProperty.FUNCTION_CALL) as FunctionCallRequest; const functionName = functionCall.functionName; const confResponse = functions ? functions.filter(f => f.name === functionName).filter(f => paramsMatch(functionCall.parameters, f.params))[0] : undefined; console.debug("[COMPONENT DEV] Function response: "); console.debug(confResponse); let functionResponse: FunctionResponse; if (confResponse === undefined) { functionResponse = { message: "Function not found", request: functionCall, resultType: FunctionResultType.NOT_FOUND, result: undefined }; } else if (confResponse.response === "ERROR") { functionResponse = { message: "Function Error!", request: functionCall, resultType: FunctionResultType.ERROR, result: undefined }; } else { functionResponse = { message: "Success!", request: functionCall, resultType: FunctionResultType.SUCCESS, result: confResponse.response }; } const props = new Map(); props.set(MessageProperty.FUNCTION_RESPONSE, functionResponse); sendMessage({ type: MessageType.FUNCTION_RESPONSE, properties: props }); } function createInit(devConf: ComponentDevConfiguration) { const props = new Map(); devConf.init.forEach(prop => props.set(prop.key, prop.value)); initMessage = { type: MessageType.INIT, properties: props }; } function createDataSet(devConf: ComponentDevConfiguration) { const props = new Map(); devConf.init.forEach(prop => props.set(prop.key, prop.value)); props.set(MessageProperty.DATASET, devConf.dataSet); dataSetMessage = { type: MessageType.DATASET, properties: props }; } function paramsMatch(requestParams: Map, devParams: Prop[]): boolean { const devParamsEmpty = !devParams || devParams.length === 0; const requestParamsEmpty = !requestParams || requestParams.size === 0; const allMatch = devParams && requestParams ? !devParamsEmpty && devParams.every(p => requestParams.get(p.key) === p.value) : false; return (devParamsEmpty && requestParamsEmpty) || allMatch; } function sendMessage(message: ComponentMessage) { console.debug("[COMPONENT DEV] Sending Message"); console.debug(message); message.properties.set(MessageProperty.COMPONENT_ID, COMP_ID); window.postMessage(message, window.location.href); } export class ComponentDev { public start() { fetch(DEV_FILE) .then(r => r.text()) .then(text => handleDevConf(text)) .catch(e => console.log("Not able to load manifest DEV file: " + e)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-dev/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/component-dev/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { return merge(common, { entry: { index: "./src/index.tsx" }, output: { libraryTarget: "commonjs2" } }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-base/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-base/package.json ================================================ { "name": "@dashbuilder-js/heatmap-base", "version": "0.1.0", "description": "", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --silent --verbose --passWithNoTests", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "debug": "node --inspect-brk ../../node_modules/jest/bin/jest.js -i", "start": "webpack-dev-server -d --host 0.0.0.0" }, "dependencies": { "@types/heatmap.js": "^2.0.36", "heatmap.js": "2.0.5" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-base/src/SvgHeatmap.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { useCallback, useEffect, createRef, useState } from "react"; import * as heatmap from "heatmap.js"; export interface SvgNodeValue { nodeId: string; value: number; } interface NodeInfo { x: number; y: number; size: number; } interface HeatData { x: number; y: number; value: number; radius?: number; } const reduce = (data: HeatData[], reducer: (v1: number, v2: number) => number) => data.length > 0 ? data.map(d => d.value).reduce((d1, d2) => reducer(d1, d2)) : 0; function createHeatmap(parent: HTMLElement, heatData: HeatData[]) { return heatmap .create({ container: parent }) .setData({ max: reduce(heatData, Math.max), min: reduce(heatData, Math.min), data: heatData }); } const getNodeInfo = (el: HTMLElement): NodeInfo => { const bounds = el.getBoundingClientRect(); const radius = Math.sqrt((bounds.width * bounds.height) / 4); return { x: (bounds.left + bounds.right) / 2, y: (bounds.top + bounds.bottom) / 2, size: radius }; }; export interface SvgHeatmapProps { svgNodesValues: SvgNodeValue[]; svgContent: string; width?: string; height?: string; } export function SvgHeatmap(props: SvgHeatmapProps) { const parentRef = createRef(); const [svgHeatmap, setSvgHeatmap] = useState>(); const [repaint, setRepaint] = useState(false); useEffect(() => { if (props.svgContent) { const heatmapContainer = parentRef.current!; heatmapContainer.innerHTML = props.svgContent; const svg = heatmapContainer.querySelector("svg")!; svg.style.width = "100%"; svg.style.height = "auto"; setSvgHeatmap(createHeatmap(heatmapContainer, [])); } }, [props.svgContent]); useEffect(() => { if (svgHeatmap && props.svgNodesValues && props.svgNodesValues.length > 0) { const values = props.svgNodesValues .filter(n => document.getElementById(n.nodeId)) .map(nodeValue => { const node = document.getElementById(nodeValue.nodeId); const nodeInfo = getNodeInfo(node!); return { x: Math.ceil(nodeInfo.x), y: Math.ceil(nodeInfo.y), radius: nodeInfo.size, value: nodeValue.value }; }); if (values.length > 0) { svgHeatmap.setData({ min: values.map(d => d.value).reduce((d1, d2) => Math.min(d1, d2)), max: values.map(d => d.value).reduce((d1, d2) => Math.max(d1, d2)), data: values }); } svgHeatmap.repaint(); } }, [svgHeatmap, props.svgNodesValues, repaint]); const onResize = useCallback(() => setRepaint(previous => !previous), [repaint]); useEffect(() => { window.addEventListener("resize", onResize, false); return () => window.removeEventListener("resize", onResize, false); }, [repaint]); return
    ; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-base/src/__tests__/svgHeatmap.test.disabled ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { render } from "@testing-library/react"; import { SVGHeatmap } from "../SVGHeatmap"; const svg = ` `; test("svg heatmap component with node values", () => { const heatmapResult = render( ); const canvas = heatmapResult.container.getElementsByTagName("canvas")[0] as HTMLCanvasElement; expect(canvas).toBeTruthy(); expect(canvas.toDataURL("image/jpg")).toBe( "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAAX0lEQVR4nO3RsQ3AIBAEwX9cgvsvFUHMOzcgzYQXnbQ5nhhRZI+sG/9ouw+wEuQwghzmG+SNvuEHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwG0mpkMEGmNamG8AAAAASUVORK5CYII=" ); }); test("svg heatmap component without values", () => { const heatmapResult = render(); const canvas = heatmapResult.container.getElementsByTagName("canvas")[0] as HTMLCanvasElement; expect(canvas).toBeTruthy(); expect(canvas.toDataURL("image/jpg")).toBe( "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAABmJLR0QA/wD/AP+gvaeTAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC" ); }); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-base/src/index.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from "./SvgHeatmap"; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-base/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-base/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const nodeExternals = require("webpack-node-externals"); const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { return merge(common, { entry: { index: "./src/index.tsx" }, output: { libraryTarget: "commonjs2" }, externals: [nodeExternals({ modulesDir: "../../node_modules" })] }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/package.json ================================================ { "name": "@dashbuilder-js/heatmap-component", "version": "0.1.0", "description": "", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --silent --verbose --passWithNoTests", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "start": "webpack-dev-server -d --host 0.0.0.0" }, "dependencies": { "@dashbuilder-js/component-api": "0.2.0", "@dashbuilder-js/heatmap-base": "0.1.0" }, "devDependencies": { "@dashbuilder-js/component-dev": "0.2.0" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/src/SVGHeatmapComponent.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { useEffect, useState } from "react"; import { SvgHeatmap, SvgNodeValue } from "@dashbuilder-js/heatmap-base"; import { ColumnType, DataSet } from "@dashbuilder-js/component-api"; import { ComponentController } from "@dashbuilder-js/component-api/dist/controller/ComponentController"; const SVG_CONTENT_PARAM = "svgContent"; const SVG_URL_PARAM = "svgUrl"; const NOT_ENOUGH_COLUMNS_MSG = "Heatmap expects 2 columns: Node ID (TEXT or Label) and value (NUMBER)"; const INVALID_COLUMNS_TYPE_MSG = "Wrong columns type. First column should be TEXT or LABEL and second column NUMBER."; const MISSING_PARAM_MSG = "You must provide either a SVG URL or the SVG Content."; const notEmpty = (param?: string) => param !== undefined && param.trim() !== ""; const validateDataSet = (ds: DataSet): string | undefined => { if (ds.columns.length < 2) { return NOT_ENOUGH_COLUMNS_MSG; } if ( (ds.columns[0].type !== ColumnType.TEXT && ds.columns[0].type !== ColumnType.LABEL) || ds.columns[1].type !== ColumnType.NUMBER ) { return INVALID_COLUMNS_TYPE_MSG; } }; const validateParams = (params: Map) => { const svgContent = params.get(SVG_CONTENT_PARAM); const svgUrl = params.get(SVG_URL_PARAM) as string; if (!(svgContent || svgUrl)) { return MISSING_PARAM_MSG; } }; const extractNodeInfo = (dataset: string[][]): SvgNodeValue[] => dataset.map(row => ({ nodeId: row[0], value: +row[1] })); interface AppState { svgContent?: string; data: SvgNodeValue[]; errorMessage?: string; } interface Props { controller: ComponentController; } export function SVGHeatmapComponent(props: Props) { const [appState, setAppState] = useState({ data: [] }); const onDataset = (ds: DataSet, params: Map) => { const validationMessage = validateDataSet(ds) || validateParams(params); if (validationMessage) { props.controller.requireConfigurationFix(validationMessage); setAppState(previousState => ({ ...previousState, errorMessage: validationMessage })); return; } props.controller.configurationOk(); const userSvgContent = params.get(SVG_CONTENT_PARAM); const svgUrl = params.get(SVG_URL_PARAM); if (notEmpty(userSvgContent)) { setAppState(previousState => ({ ...previousState, data: extractNodeInfo(ds.data), svgContent: userSvgContent })); } else { fetch(svgUrl) .then(r => r.text()) .then(urlSvgContent => setAppState(previousState => ({ ...previousState, data: extractNodeInfo(ds.data), svgContent: urlSvgContent })) ) .catch(e => setAppState(previousState => ({ ...previousState, data: [], svgContent: undefined, errorMessage: e })) ); } }; useEffect(() => props.controller.setOnDataSet(onDataset), [appState.data]); return appState?.errorMessage ? ( {appState.errorMessage} ) : ( ); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/src/index-dev.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { ComponentDev } from "@dashbuilder-js/component-dev"; import { ComponentApi } from "@dashbuilder-js/component-api"; import { SVGHeatmapComponent } from "./SVGHeatmapComponent"; const componentApi = new ComponentApi(); ReactDOM.render( , document.getElementById("app")! ); new ComponentDev().start(); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/src/index.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { ComponentApi } from "@dashbuilder-js/component-api"; import { SVGHeatmapComponent } from "./SVGHeatmapComponent"; const api = new ComponentApi(); ReactDOM.render(, document.getElementById("app")!); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/static/index.html ================================================ Heatmap Component
    ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/static/manifest.dev.json ================================================ { "init": [ { "key": "svgUrl", "value": "/world.svg" } ], "dataSet": { "columns": [ { "name": "nodeId", "type": "TEXT", "settings": { "columnId": "nodeId", "columnName": "Node ID", "valueExpression": "value", "emptyTemplate": "---", "valuePattern": "#" } }, { "name": "value", "type": "NUMBER", "settings": { "columnId": "value", "columnName": "Value", "valueExpression": "value", "emptyTemplate": "---", "valuePattern": "#" } } ], "data": [ ["US", "1"], ["BO", "1"], ["BR", "1"], ["CD", "1"], ["MG", "1"], ["MZ", "1"], ["ZM", "1"], ["GB", "1"], ["AU", "1"], ["CN", "1"], ["CA", "0"], ["RU", "2"] ] } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/static/manifest.json ================================================ { "name": "Heatmap", "parameters": [ { "name": "svgContent", "label": "SVG Content", "type": "text", "defaultValue": "" }, { "name": "svgUrl", "type": "text", "label": "SVG URL", "defaultValue": "" } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "declaration": false }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/heatmap-component/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require("path"); const CopyPlugin = require("copy-webpack-plugin"); const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { let entryPoint = "./src/index.tsx"; const copyResources = [ { from: "./static/index.html", to: "./index.html" }, { from: "./static/manifest.json", to: "./manifest.json" } ]; if (process.env.WEBPACK_DEV_SERVER) { entryPoint = "./src/index-dev.tsx"; copyResources.push({ from: "./static/manifest.dev.json", to: "./manifest.dev.json" }); copyResources.push({ from: "./static/dev.svg", to: "./dev.svg" }); } return merge(common, { entry: { index: entryPoint }, plugins: [new CopyPlugin(copyResources)], devServer: { historyApiFallback: false, disableHostCheck: true, watchContentBase: true, contentBase: [path.join(__dirname, "./dist"), path.join(__dirname, "./static")], compress: true, port: 9001 } }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/package.json ================================================ { "name": "@dashbuilder-js/logo-component", "version": "0.1.0", "description": "", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --silent --verbose --passWithNoTests", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "start": "webpack-dev-server -d --host 0.0.0.0 --env WEBPACK_DEV_SERVER=true" }, "dependencies": { "@dashbuilder-js/component-api": "0.2.0" }, "devDependencies": { "@dashbuilder-js/component-dev": "0.2.0" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/src/Logo.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; export interface LogoProps { src: string; width?: string; height?: string; } export function Logo(props: LogoProps) { return ; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/src/LogoComponent.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { ComponentController } from "@dashbuilder-js/component-api"; import * as React from "react"; import { useState, useEffect } from "react"; import { Logo, LogoProps } from "./Logo"; const SRC_PROP = "src"; const WIDTH_PROP = "width"; const HEIGHT_PROP = "height"; interface Props { controller: ComponentController; } export function LogoComponent(props: Props) { const [logoProps, setLogoProps] = useState({ src: "" }); useEffect(() => { props.controller.setOnInit(componentProps => { setLogoProps({ src: (componentProps.get(SRC_PROP) as string) || "", width: componentProps.get(WIDTH_PROP) as string, height: componentProps.get(HEIGHT_PROP) as string }); }); }, []); return ; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/src/index-dev.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { LogoComponent } from "./LogoComponent"; import { ComponentDev } from "@dashbuilder-js/component-dev"; import { ComponentApi } from "@dashbuilder-js/component-api"; const api = new ComponentApi(); ReactDOM.render(, document.getElementById("app")!); new ComponentDev().start(); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/src/index.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { LogoComponent } from "./LogoComponent"; import { ComponentApi } from "@dashbuilder-js/component-api"; const api = new ComponentApi(); ReactDOM.render(, document.getElementById("app")!); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/static/index.html ================================================ Logo Component
    ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/static/manifest.dev.json ================================================ { "init": [ { "key": "src", "value": "https://www.redhat.com/cms/managed-files/Logo-redhat-color-375.png" }, { "key": "width", "value": "500px" } ], "functions": [ { "name": "ping", "response": "pong" } ], "dataSet": { "columns": [ { "name": "Country", "type": "LABEL", "settings": { "columnId": "Country", "columnName": "Country", "valueExpression": "value", "emptyTemplate": "---", "valuePattern": null } }, { "name": "GDP 2014", "type": "NUMBER", "settings": { "columnId": "GDP 2014", "columnName": "GDP 2014", "valueExpression": "value", "emptyTemplate": "---", "valuePattern": "#,##0.00" } } ], "data": [ ["United States", "16768100"], ["China", "9240270"], ["Japan", "4919563"], ["Germany", "3730261"], ["United Kingdom", "2678455"], ["France", "2806428"], ["Brazil", "2245673"] ] } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/static/manifest.json ================================================ { "name": "Logo", "noData": true, "category": "Core", "icon": "pficon pficon-messages", "parameters": [ { "name": "src", "type": "text", "defaultValue": "./images/dashbuilder-logo.png", "label": "Logo URL", "mandatory": true }, { "name": "width", "type": "text", "defaultValue": "", "label": "Width" }, { "name": "height", "type": "text", "defaultValue": "", "label": "Height" } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "declaration": false }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/logo-component/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require("path"); const CopyPlugin = require("copy-webpack-plugin"); const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { let entryPoint = "./src/index.tsx"; const copyResources = [ { from: "./static/images", to: "./images" }, { from: "./static/index.html", to: "./index.html" }, { from: "./static/manifest.json", to: "./manifest.json" } ]; if (process.env.WEBPACK_DEV_SERVER) { entryPoint = "./src/index-dev.tsx"; copyResources.push({ from: "./static/manifest.dev.json", to: "./manifest.dev.json" }); } return merge(common, { entry: { index: entryPoint }, plugins: [new CopyPlugin(copyResources)], devServer: { historyApiFallback: false, disableHostCheck: true, watchContentBase: true, contentBase: [path.join(__dirname, "./dist"), path.join(__dirname, "./static")], compress: true, port: 9001 } }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/package.json ================================================ { "name": "@dashbuilder-js/process-heatmap-component", "version": "0.1.0", "description": "", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --silent --verbose --passWithNoTests", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "start": "webpack-dev-server -d --host 0.0.0.0" }, "dependencies": { "@dashbuilder-js/component-api": "0.2.0", "@dashbuilder-js/heatmap-base": "0.1.0" }, "devDependencies": { "@dashbuilder-js/component-dev": "0.2.0" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/src/ProcessHeatmapComponent.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { useEffect, useState, useCallback } from "react"; import { ColumnType, DataSet, FunctionCallRequest } from "@dashbuilder-js/component-api"; import { ComponentController } from "@dashbuilder-js/component-api/dist/controller/ComponentController"; import { SvgNodeValue, SvgHeatmap } from "@dashbuilder-js/heatmap-base"; const NOT_ENOUGH_COLUMNS_MSG = "Process Heatmap expects 2 columns: Node Id(LABEL or TEXT),Value (NUMBER)."; const FIRST_COLUMN_INVALID_MSG = "Wrong type for first column, it should be either LABEL or TEXT."; const SECOND_COLUMN_INVALID_MSG = "Wrong type for second column, it should be NUMBER."; enum Params { SERVER_TEMPLATE = "serverTemplate", CONTAINER_ID = "containerId", PROCESS_ID = "processId" } enum AppStateType { ERROR = "Error", INIT = "Initializing", LOADING_SVG = "Loading SVG", LOADED_SVG = "Loaded SVG", FINISHED = "Finished loading" } interface AppState { state: AppStateType; processesNodesValues: SvgNodeValue[]; svgRequest?: FunctionCallRequest; processSVG?: string; configurationIssue: string; message?: string; } const isEmpty = (param?: string) => param === undefined || param.trim() === ""; const validateParams = (params: Map): string | undefined => { if (isEmpty(params.get(Params.SERVER_TEMPLATE))) { return "Server template is required."; } if (isEmpty(params.get(Params.CONTAINER_ID))) { return "Container ID is required."; } if (isEmpty(params.get(Params.PROCESS_ID))) { return "Process ID is required."; } }; const validateDataSet = (ds: DataSet): string | undefined => { if (ds.columns.length < 2) { return NOT_ENOUGH_COLUMNS_MSG; } if (ds.columns[0].type !== ColumnType.LABEL && ds.columns[0].type !== ColumnType.TEXT) { return FIRST_COLUMN_INVALID_MSG; } if (ds.columns[1].type !== ColumnType.NUMBER) { return SECOND_COLUMN_INVALID_MSG; } }; interface Props { controller: ComponentController; } export function ProcessHeatmapComponent(props: Props) { const [appState, setAppState] = useState({ state: AppStateType.INIT, processesNodesValues: [], configurationIssue: "" }); const onInit = useCallback( (params: Map) => { const validationMessage = validateParams(params); if (validationMessage) { setAppState(previousAppState => ({ ...previousAppState, state: AppStateType.ERROR, message: validationMessage, configurationIssue: validationMessage })); } else { setAppState(previousAppState => ({ ...previousAppState, state: AppStateType.LOADING_SVG, svgRequest: { functionName: "ProcessSVGFunction", parameters: params }, configurationIssue: "" })); } }, [appState] ); const onDataset = useCallback((ds: DataSet, params: Map) => { const validationMessage = validateParams(params) || validateDataSet(ds); if (validationMessage) { setAppState(previousAppState => ({ ...previousAppState, state: AppStateType.ERROR, message: validationMessage, configurationIssue: validationMessage })); } else { setAppState(previousAppState => ({ ...previousAppState, processesNodesValues: ds.data.map(d => ({ nodeId: d[0], value: +d[1] })), state: AppStateType.FINISHED, configurationIssue: "" })); } }, []); useEffect(() => { props.controller.setOnInit(onInit); props.controller.setOnDataSet(onDataset); }, [appState]); useEffect(() => { if (appState.configurationIssue) { props.controller.requireConfigurationFix(appState.configurationIssue); } else { props.controller.configurationOk(); } }, [appState.configurationIssue]); useEffect(() => { if (appState.svgRequest) { props.controller .callFunction(appState.svgRequest!) .then((result: any) => setAppState(previousAppState => ({ ...previousAppState, state: AppStateType.LOADED_SVG, processSVG: result })) ) .catch((errorMsg: string) => setAppState(previousAppState => ({ ...previousAppState, state: AppStateType.ERROR, message: `There was an error retrieving process SVG: ${errorMsg}` })) ); } }, [appState.svgRequest]); return (
    {(() => { switch (appState.state) { case AppStateType.ERROR: return {appState.message}; case AppStateType.LOADED_SVG: case AppStateType.FINISHED: return ; default: return Status: {appState.state}; } })()}
    ); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/src/index-dev.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { ProcessHeatmapComponent } from "./ProcessHeatmapComponent"; import { ComponentApi } from "@dashbuilder-js/component-api"; import { ComponentDev } from "@dashbuilder-js/component-dev"; const api = new ComponentApi(); ReactDOM.render(, document.getElementById("app")!); new ComponentDev().start(); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/src/index.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { ProcessHeatmapComponent } from "./ProcessHeatmapComponent"; import { ComponentApi } from "@dashbuilder-js/component-api"; const api = new ComponentApi(); ReactDOM.render(, document.getElementById("app")!); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/static/index.html ================================================ Process Heatmap Component
    ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/static/manifest.dev.json ================================================ { "init": [ { "key": "serverTemplate", "value": "sample template" }, { "key": "containerId", "value": "sample container id" }, { "key": "processId", "value": "process id" } ], "dataSet": { "columns": [ { "name": "nodeId", "type": "TEXT" }, { "name": "value", "type": "NUMBER" } ], "data": [ ["_8DF7D18B-1357-470B-BFDF-E8F168CD2D51", "1"], ["_31FBFFDF-B095-483C-BBCE-2AA83609521E", "1"], ["_7E897E88-A5A1-49F4-ABC4-D67A42B1177F", "1"] ] }, "functions": [ { "name": "ProcessSVGFunction", "params": [ { "key": "serverTemplate", "value": "sample template" }, { "key": "containerId", "value": "sample container id" }, { "key": "processId", "value": "process id" } ], "response": "Sample Task" } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/static/manifest.json ================================================ { "name": "Process Heatmap", "category": "Heatmaps", "icon": "pficon pficon-blueprint", "parameters": [ { "name": "serverTemplate", "label": "Server Template", "type": "text", "defaultValue": "", "mandatory": true }, { "name": "containerId", "label": "Container ID", "type": "text", "defaultValue": "", "mandatory": true }, { "name": "processId", "label": "Process Definition ID", "type": "text", "defaultValue": "", "mandatory": true } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "declaration": false }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/process-heatmap-component/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require("path"); const CopyPlugin = require("copy-webpack-plugin"); const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { let entryPoint = "./src/index.tsx"; const copyResources = [ { from: "./static/index.html", to: "./index.html" }, { from: "./static/manifest.json", to: "./manifest.json" } ]; if (process.env.WEBPACK_DEV_SERVER) { entryPoint = "./src/index-dev.tsx"; copyResources.push({ from: "./static/manifest.dev.json", to: "./manifest.dev.json" }); } return merge(common, { entry: { index: entryPoint }, plugins: [new CopyPlugin(copyResources)], devServer: { historyApiFallback: false, disableHostCheck: true, watchContentBase: true, contentBase: [path.join(__dirname, "./dist"), path.join(__dirname, "./static")], compress: true, port: 9001 } }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/package.json ================================================ { "name": "@dashbuilder-js/processes-heatmaps-component", "version": "0.1.0", "description": "", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --silent --verbose --passWithNoTests", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "start": "webpack-dev-server -d --host 0.0.0.0" }, "dependencies": { "@dashbuilder-js/component-api": "0.2.0", "@dashbuilder-js/heatmap-base": "0.1.0" }, "devDependencies": { "@dashbuilder-js/component-dev": "0.2.0" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/src/ProcessSelector.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { useEffect, useCallback, useState, createRef } from "react"; export interface KieServerContainer { id: string; processes: string[]; } interface SelectedValue { container: KieServerContainer; process: string; } export interface ProcessSelectorProps { containers: KieServerContainer[]; onContainerProcessSelected: (container: string, process: string) => void; selectedContainer?: string; selectedProcess?: string; } export function ProcessSelector(props: ProcessSelectorProps) { const containerSelectRef = createRef(); const titleRef = createRef(); const bodyRef = createRef(); const processSelectRef = createRef(); const [selectedValue, setSelectedValue] = useState(); const onTitleClicked = useCallback((e: any) => { titleRef.current?.classList.toggle("active"); const bodyRefEl = bodyRef.current; if (bodyRefEl) { const bodyHidden = bodyRefEl.style.display === "none"; bodyRefEl.style.display = bodyHidden ? "block" : "none"; } }, [titleRef, bodyRef]); const onContainerSelected = useCallback( (e: any) => { const containerName = containerSelectRef.current?.value; const selectedContainer = props.containers.filter(c => c.id === containerName)[0]; props.onContainerProcessSelected(selectedContainer.id, selectedContainer.processes[0]); setSelectedValue({ container: selectedContainer, process: selectedContainer.processes[0] }); }, [selectedValue, containerSelectRef.current] ); const onProcessSelected = useCallback( (e: any) => props.onContainerProcessSelected(selectedValue?.container.id!, processSelectRef.current?.value!), [selectedValue, processSelectRef.current] ); useEffect(() => { const containers = props.containers; if (containers?.length > 0) { const selectedContainer = props.selectedContainer ? containers.filter(c => c.id === props.selectedContainer)[0] : containers[0]; setSelectedValue({ container: selectedContainer, process: props.selectedProcess ? selectedContainer.processes.filter(p => p === props.selectedProcess)[0] : selectedContainer.processes[0] }); } }, [props.containers]); return (
    Process Selector
    {props.containers && props.containers.length > 0 && (
    Container
    )} {selectedValue?.container?.processes?.length! > 0 && (
    Process
    )}
    ); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/src/ProcessesHeatmapsComponent.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { useEffect, useState, useCallback } from "react"; import { ColumnType, DataSet } from "@dashbuilder-js/component-api"; import { ComponentController } from "@dashbuilder-js/component-api/dist/controller/ComponentController"; import { SvgNodeValue, SvgHeatmap } from "@dashbuilder-js/heatmap-base"; import { ProcessSelector } from "./ProcessSelector"; const NOT_ENOUGH_COLUMNS_MSG = "All Processes Heatmaps expects 4 columns: Container Id (or External Id), Process Id, Node Id ,Value (NUMBER)."; const INVALID_TEXT_COLUMN = "Wrong type for column {0}, it should be either LABEL or TEXT."; const VALUE_COLUMN_INVALID_MSG = "Wrong type for node value column, it should be NUMBER."; const NO_DATA_MESSAGE = "Dataset is empty. Please provide data with container id, process id, node id and value."; enum Params { SERVER_TEMPLATE = "serverTemplate", SHOW_STATUS = "showStatus", SHOW_PROCESS_SELECTOR = "showProcessSelector" } enum AppStateType { ERROR = "Error", INIT = "Initializing", WAITING_DATA = "Waiting Data", LOADING_SVG = "Loading SVG", LOADED_SVG = "Loaded SVG", FINISHED = "Finished loading" } interface NodeData { nodeid: string; value: number; } interface ProcessData { processId: string; nodeValues: NodeData[]; } interface ContainerData { containerId: string; processData: ProcessData[]; } interface AppState { state: AppStateType; nodesValues: SvgNodeValue[]; serverTemplate?: string; processSvg?: string; containerData: ContainerData[]; message?: string; selectedContainer?: string; selectedProcess?: string; showStatus?: boolean; } const isEmpty = (param?: string) => param === undefined || param.trim() === ""; const validateParams = (params: Map): string | undefined => { if (isEmpty(params.get(Params.SERVER_TEMPLATE))) { return "Server template is required. (Component Properties)"; } }; const validateDataSet = (ds: DataSet): string | undefined => { if (ds.columns.length < 4) { return NOT_ENOUGH_COLUMNS_MSG; } for (let i = 0; i < ds.columns.length; i++) { const column = ds.columns[i]; const columnType = column.type; if (i < 3 && columnType !== ColumnType.LABEL && columnType !== ColumnType.TEXT) { return INVALID_TEXT_COLUMN.replace("{0}", column.name); } if (i === 3 && columnType !== ColumnType.NUMBER) { return VALUE_COLUMN_INVALID_MSG; } } }; interface Props { controller: ComponentController; } export function ProcessesHeatmapsComponent(props: Props) { const [appState, setAppState] = useState({ state: AppStateType.INIT, nodesValues: [], containerData: [], showStatus: false }); const onDataset = useCallback( (ds: DataSet, params: Map) => { const validation = validateParams(params) || validateDataSet(ds); if (validation) { setAppState(previousState => ({ ...previousState, state: AppStateType.ERROR, message: validation })); props.controller.requireConfigurationFix(validation); return; } if (ds.data.length === 0) { setAppState(previousState => ({ ...previousState, state: AppStateType.ERROR, message: NO_DATA_MESSAGE })); props.controller.requireConfigurationFix(NO_DATA_MESSAGE); return; } props.controller.configurationOk(); const allContainerData: ContainerData[] = []; ds.data.map(d => { const cid = d[0]; const pid = d[1]; const nid = d[2]; const nodeValue = +d[3]; let containerData = allContainerData.filter(c => c.containerId === cid)[0]; if (!containerData) { containerData = { containerId: cid, processData: [] }; allContainerData.push(containerData); } const processData = containerData.processData.filter(p => p.processId === pid)[0]; if (processData) { processData.nodeValues.push({ nodeid: nid, value: nodeValue }); } else { containerData.processData.push({ processId: pid, nodeValues: [{ nodeid: nid, value: nodeValue }] }); } }); setAppState(previousState => ({ ...previousState, nodesValues: ds.data.map((d: string[]) => { return { nodeId: d[2], value: +d[3] }; }), state: AppStateType.LOADING_SVG, containerData: allContainerData, serverTemplate: params.get(Params.SERVER_TEMPLATE), showStatus: params.get(Params.SHOW_STATUS) === "true", selectedContainer: appState.selectedContainer || allContainerData[0].containerId, selectedProcess: appState.selectedProcess || allContainerData[0].processData[0].processId })); }, [appState] ); const onProcessSelected = useCallback( (containerId: string, processId: string) => { if ( !appState.serverTemplate || (containerId === appState.selectedContainer && processId === appState.selectedProcess) ) { return; } setAppState(previousState => ({ ...previousState, state: AppStateType.LOADING_SVG, selectedContainer: containerId, selectedProcess: processId })); }, [appState.serverTemplate, appState.selectedContainer, appState.selectedProcess] ); useEffect(() => props.controller.setOnDataSet(onDataset), [appState]); useEffect(() => { if (appState.serverTemplate && appState.selectedContainer && appState.selectedProcess) { const params = new Map(); params.set(Params.SERVER_TEMPLATE, appState.serverTemplate!); params.set("containerId", appState.selectedContainer!); params.set("processId", appState.selectedProcess!); props.controller .callFunction({ functionName: "ProcessSVGFunction", parameters: params }) .then((result: any) => setAppState(previousState => ({ ...previousState, state: AppStateType.LOADED_SVG, processSvg: result })) ) .catch((errorMsg: string) => setAppState(previousState => ({ ...previousState, state: AppStateType.ERROR, processSvg: undefined, message: `Error loading SVG for process "${appState.selectedProcess}" from container "${appState.selectedContainer}". Please make sure the process SVG exists. Error: ${errorMsg}` })) ); } }, [appState.serverTemplate, appState.selectedContainer, appState.selectedProcess]); return (
    {appState.state !== AppStateType.ERROR && appState.processSvg && ( )} {appState.containerData.length > 0 && ( { return { id: c.containerId, processes: c.processData.map(p => p.processId) }; })} onContainerProcessSelected={onProcessSelected} selectedContainer={appState.selectedContainer} selectedProcess={appState.selectedProcess} /> )} {appState.state === AppStateType.ERROR &&

    {appState.message}

    } {appState.showStatus && (
    {appState.state} {appState.message ? `: ${appState.message}` : ""}
    )}
    ); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/src/index-dev.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { ProcessesHeatmapsComponent } from "./ProcessesHeatmapsComponent"; import { ComponentApi } from "@dashbuilder-js/component-api"; import { ComponentDev } from "@dashbuilder-js/component-dev"; const api = new ComponentApi(); ReactDOM.render( , document.getElementById("app")! ); new ComponentDev().start(); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/src/index.tsx ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { ProcessesHeatmapsComponent } from "./ProcessesHeatmapsComponent"; import { ComponentApi } from "@dashbuilder-js/component-api"; const api = new ComponentApi(); ReactDOM.render( , document.getElementById("app")! ); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/static/index.html ================================================ Process Heatmap Component
    ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/static/manifest.dev.json ================================================ { "init": [ { "key": "serverTemplate", "value": "server" }, { "key": "showStatus", "value": "true" } ], "dataSet": { "columns": [ { "name": "containerId", "type": "TEXT" }, { "name": "processId", "type": "TEXT" }, { "name": "nodeId", "type": "TEXT" }, { "name": "value", "type": "NUMBER" } ], "data": [ ["container1", "process1", "_8DF7D18B-1357-470B-BFDF-E8F168CD2D51", "1"], ["container1", "process1", "_31FBFFDF-B095-483C-BBCE-2AA83609521E", "1"], ["container1", "process1", "_7E897E88-A5A1-49F4-ABC4-D67A42B1177F", "1"], ["container1", "process2", "_E39122D0-55A7-464D-A209-EF468A3D9939", "10"], ["container1", "process2", "_F71FB1D8-8363-4628-AF74-887C949FCD81", "12"], ["container1", "process2", "_14A95F6E-2421-4623-BD7F-C8BF879F9ECE", "1"], ["container2", "process1process1process1process1process1process1process1", "_8FCF18E2-0158-42A4-B15B-DE7E0DB3B5D7", "100"], ["container2", "process1process1process1process1process1process1process1", "_DDEA4967-7EAB-4224-A5A0-EC3CE37F194C", "101"], ["container2", "process1process1process1process1process1process1process1", "_51C46971-52B0-4C16-8CE1-CD28956EA343", "102"] ] }, "functions": [ { "name": "ProcessSVGFunction", "params": [ { "key": "serverTemplate", "value": "server" }, { "key": "containerId", "value": "container1" }, { "key": "processId", "value": "process1" } ], "response": "Sample Task" }, { "name": "ProcessSVGFunction", "params": [ { "key": "serverTemplate", "value": "server" }, { "key": "containerId", "value": "container1" }, { "key": "processId", "value": "process2" } ], "response": "T1T2T3" }, { "name": "ProcessSVGFunction", "params": [ { "key": "serverTemplate", "value": "server" }, { "key": "containerId", "value": "container2" }, { "key": "processId_", "value": "process1process1process1process1process1process1process1" } ], "response": "" } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/static/manifest.json ================================================ { "name": "All Processes Heatmaps", "category": "Heatmaps", "icon": "pficon pficon-blueprint", "parameters": [ { "name": "serverTemplate", "label": "Server Template", "type": "text", "category": "Server Template", "defaultValue": "", "mandatory": true }, { "name": "showStatus", "label": "Status", "type": "boolean", "category": "Display", "defaultValue": "true" } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/static/style.css ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ .allProcessHeatmapsComponent { width: 100%; height: 100%; } .statusContainer { position: absolute; width: 100%; height: 20px; border: 1px; bottom: 0px; background-color: rgba(240, 240, 240, 0.7); } .statusLabel { color: gray; } .processSelectorContainer { position: absolute; top: 0; left: 0; margin: 10px; opacity: 0.6; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); transition: 0.3s; max-width: 130px; min-width: 130px; } .processSelectorContainer:hover { opacity: 1; box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); } .errorMessage { color: #9F6000; background-color: #FEEFB3; } .cardTitle { margin: 2px; margin-bottom: 4px; } .cardBody { display: flex; flex-direction: column; } .processSelectorContainer select { max-width: 100px; min-width: 100px; background-color: #f1f1f1; color: #4d5258; border-color: #bbb; font-size: 12px; overflow: hidden; } .processSelectorContainer select:hover { border-color: #7dc3e8; } .processSelectorContainer select:focus { border-color: #0088ce; outline: 0 !important; box-shadow: inset 0 1px 1px rgba(3, 3, 3, 0.075), 0 0 8px rgba(0, 136, 206, 0.6); } .processSelectorContainer select.select-items { position: absolute; background-color: DodgerBlue; top: 100%; left: 0; right: 0; z-index: 99; } .processSelectorContainer fieldset { border-color: #dddddd; border-radius: 10px; border-width: 1px; border-style: dotted; } .processSelectorContainer fieldset legend { font-size: 12px; font-weight: bold; } .collapsible { background-color: #eee; color: #444; cursor: pointer; width: 100%; border: none; text-align: left; outline: none; font-size: 15px; } /* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */ .active, .collapsible:hover { background-color: #ccc; } /* Style the collapsible content. Note: hidden by default */ .content { padding: 0 18px; display: none; overflow: hidden; background-color: #f1f1f1; } .collapsible:after { content: '\02795'; /* Unicode character for "plus" sign (+) */ font-size: 8px; color: white; float: right; margin: 5px; } .active:after { content: "\2796"; /* Unicode character for "minus" sign (-) */ } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "declaration": false }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/processes-heatmaps-component/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require("path"); const CopyPlugin = require("copy-webpack-plugin"); const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { let entryPoint = "./src/index.tsx"; const copyResources = [ { from: "./static/index.html", to: "./index.html" }, { from: "./static/manifest.json", to: "./manifest.json" }, { from: "./static/style.css", to: "./style.css" } ]; if (process.env.WEBPACK_DEV_SERVER) { entryPoint = "./src/index-dev.tsx"; copyResources.push({ from: "./static/manifest.dev.json", to: "./manifest.dev.json" }); } return merge(common, { entry: { index: entryPoint }, plugins: [new CopyPlugin(copyResources)], devServer: { historyApiFallback: false, disableHostCheck: true, watchContentBase: true, contentBase: [path.join(__dirname, "./dist"), path.join(__dirname, "./static")], compress: true, port: 9001 } }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/runtime-client/jest.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { reporters: ["default"], moduleDirectories: ["node_modules", "src"], moduleFileExtensions: ["js", "jsx", "ts", "tsx"], testRegex: "/__tests__/.*\\.test\\.(jsx?|tsx?)$", transform: { "^.+\\.jsx?$": "babel-jest", "^.+\\.tsx?$": "ts-jest" }, moduleNameMapper: { "\\.(css|less|sass|scss)$": "/__mocks__/styleMock.js" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/runtime-client/package.json ================================================ { "name": "@dashbuilder-js/runtime-client", "version": "0.1.0", "description": "Dashbuilder Runtime client Javascript API.", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --verbose --silent --passWithNoTests", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none" }, "babel": { "presets": [ "@babel/env", "@babel/react" ] }, "jest-junit": { "outputDirectory": "./target" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/runtime-client/src/DashbuilderService.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export type RuntimeMode = "MULTIPLE_IMPORT" | "SINGLE" | "STATIC"; export interface ApiResponse { mode: RuntimeMode; availableModels: string[]; acceptingNewImports: boolean; } export interface DashboardResponse { runtimeModelId: string; pages: string[]; } export interface RequestInfo { url: string; user: string; password: string; } export function embeddedRuntimeUrl(url: string, dashboardId: string, page: string) { const urlBuild = new URL(url); urlBuild.searchParams.set("standalone", "true"); urlBuild.searchParams.set("perspective", page); if (dashboardId && dashboardId !== "") { urlBuild.searchParams.set("import", dashboardId); } return urlBuild.href; } export class DashbuilderService { private requestInfo: RequestInfo; private authToken: string; constructor(requestInfo: RequestInfo) { this.requestInfo = requestInfo; this.authToken = btoa(requestInfo.user + ":" + requestInfo.password); } public listDashboards(): Promise { const url = `${this.requestInfo.url}/rest/api`; return this.request(url).then(obj => (obj as unknown) as ApiResponse); } public listPages(id: string): Promise { if (!id || id === "") { return Promise.resolve({ runtimeModelId: id, pages: [] }); } const url = `${this.requestInfo.url}/rest/api/dashboard/${id}`; return this.request(url).then(obj => (obj as unknown) as DashboardResponse); } private request(url: string): Promise { return fetch(url, { credentials: "include", mode: "cors", headers: new Headers({ Authorization: `Basic ${this.authToken}` }) }).then(r => r.json()); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/runtime-client/src/index.ts ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export * from './DashbuilderService'; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/runtime-client/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/runtime-client/webpack.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const nodeExternals = require("webpack-node-externals"); const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = merge(common, { entry: { index: "./src/index.ts" }, output: { libraryTarget: "commonjs2" }, externals: [nodeExternals({ modulesDir: "../../node_modules" })], }); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/.gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js # testing /coverage # production /build # misc .DS_Store .env.local .env.development.local .env.test.local .env.production.local npm-debug.log* yarn-debug.log* yarn-error.log* ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/jest.config.js ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { roots: ["/src"], testMatch: ["**/__tests__/**/*.+(ts|tsx|js)", "**/?(*.)+(spec|test).+(ts|tsx|js)"], transform: { "^.+\\.(ts|tsx)$": "ts-jest" } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/package.json ================================================ { "name": "@dashbuilder-js/time-series-component", "version": "0.1.0", "description": "", "license": "Apache-2.0", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "dependencies": { "@dashbuilder-js/component-api": "^0.2.0", "@types/node": "^12.0.0", "apexcharts": "^3.23.1", "react-apexcharts": "^1.3.7", "react-router-dom": "^5.2.0" }, "scripts": { "lint": "tslint -c ../../tslint.json 'src/**/*.{ts,tsx,js,jsx}'", "test": "jest --silent --verbose --passWithNoTests --coverage", "test:clearCache": "jest --clearCache", "build:fast": "rm -rf dist && webpack", "build": "yarn run lint && yarn test && yarn run build:fast", "build:prod": "yarn run build --mode production --devtool none", "start": "webpack-dev-server -d --host 0.0.0.0 --env WEBPACK_DEV_SERVER=true" }, "devDependencies": { "@dashbuilder-js/component-dev": "^0.2.0", "@types/enzyme": "^3.10.8", "@types/enzyme-adapter-react-16": "^1.0.6", "@types/history": "^4.7.3", "@types/jest": "^26.0.21", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.6", "enzyme-to-json": "^3.6.1", "jest": "^26.6.3", "react-test-renderer": "^17.0.1", "style-loader": "^2.0.0", "ts-jest": "^26.5.4", "ts-node": "^9.1.1", "typescript": "^4.2.3", "jest-enzyme": "7.1.2", "webpack-dev-server": "^3.11.3", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/Chart.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { LineChart, ChartProps } from "./LineChart"; import { options, series } from "./SampleData"; import { ComponentController, DataSet, ColumnType } from "@dashbuilder-js/component-api"; import { useState, useEffect, useCallback } from "react"; import { Options, SingleSeries } from "./Data"; // Default Values export const NOT_ENOUGH_COLUMNS_MSG_NON_TRANSPOSED = "Time series component expects at least 2 columns: category(LABEL or TEXT or NUMBER or DATE) and one or more series(NUMBER)."; export const NOT_ENOUGH_COLUMNS_MSG_TRANSPOSED = "Time series component expects 3 columns: category(LABEL or TEXT or NUMBER or DATE), series(TEXT) and values(NUMBER)."; export const SECOND_COLUMN_INVALID_MSG_TRANSPOSED = "Wrong type for second column, it should be TEXT."; export const THIRD_COLUMN_INVALID_MSG_TRANSPOSED = "Wrong type for third column, it should be NUMBER."; export const CHARTNAME_VALIDATION = "Please remove all special characters and spaces in Chart Name"; export enum Params { TRANSPOSED = "transposed", CHARTNAME = "chartName", SHOWAREA = "showArea", XAXISTYPE = "xaxisType", DATALABELS = "dataLabels", ZOOMTYPE = "type", ZOOMENABLED = "enabled", ZOOMAUTOSCALEYAXIS = "autoScaleYaxis", TITLETEXT = "text", TITLEALIGN = "align", TOOLBARSHOW = "show", TOOLBARAUTOSELECTED = "autoSelected" } enum AppStateType { ERROR = "Error", INIT = "Initializing", LOADING_COMPONENT = "Loading Component", LOADED_COMPONENT = "Loaded Component", FINISHED = "Finished loading" } interface AppState { state: AppStateType; processesOptions: Options; processesSeries: SingleSeries[]; configurationIssue: string; message?: string; } export const validateParams = (params: Map): string | undefined => { if (!params.get(Params.TRANSPOSED)) { return "Transposed is required."; } if (!params.get(Params.CHARTNAME)) { return "Chart name is required."; } else { return validateChartName(params.get(Params.CHARTNAME)); } }; export const validateChartName = (chartName: string | number | undefined): string | undefined => { const format = /[ `!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?~]/; if (typeof chartName === "string") { return format.test(chartName) ? CHARTNAME_VALIDATION : ""; } }; const validateDataSet = (ds: DataSet, transposed: boolean): string | undefined => { return transposed ? validateTransposedDataset(ds) : validateNonTransposedDataset(ds); }; export const validateNonTransposedDataset = (ds: DataSet): string | undefined => { if (ds.columns.length < 2) { return NOT_ENOUGH_COLUMNS_MSG_NON_TRANSPOSED; } for (let i = 1; i < ds.columns.length; i++) { if (ds.columns[i].type !== ColumnType.NUMBER) { return "Wrong type for column " + (i + 1) + ", it should be NUMBER"; } } }; export const validateTransposedDataset = (ds: DataSet): string | undefined => { if (ds.columns.length < 3) { return NOT_ENOUGH_COLUMNS_MSG_TRANSPOSED; } if (ds.columns[1].type !== ColumnType.TEXT && ds.columns[1].type !== ColumnType.LABEL) { return SECOND_COLUMN_INVALID_MSG_TRANSPOSED; } if (ds.columns[2].type !== ColumnType.NUMBER) { return THIRD_COLUMN_INVALID_MSG_TRANSPOSED; } }; interface Props { controller: ComponentController; } function getSeries(dataset: DataSet, transposed: boolean): SingleSeries[] { return transposed ? getSeriesforTransposedDataset(dataset) : getSeriesforNonTransposedDataset(dataset); } export function getSeriesforNonTransposedDataset(dataset: DataSet): SingleSeries[] { const arrayseries: SingleSeries[] = []; for (let i = 1; i < dataset.columns.length; i++) { arrayseries.push({ name: dataset.columns[i].name, data: dataset.data.map((d: Array) => +d[i]) }); } return arrayseries; } export function getSeriesforTransposedDataset(dataset: DataSet): SingleSeries[] { const arrayseries: SingleSeries[] = []; const names: string[] = dataset.data.map((d: string[]) => d[1]); const datum: Array = dataset.data.map((d: Array) => d[2]); const newnames: string[] = []; for (const i of names) { if (newnames.indexOf(i) === -1) { newnames.push(i); } } for (const i of newnames) { const newdata: Array = []; for (let j = 0; j < names.length; j++) { if (i === names[j]) { newdata.push(+datum[j]); } } arrayseries.push({ name: i, data: newdata }); } return arrayseries; } export function getOptions( dataset: DataSet, transposed: boolean, chartName: string, type: string, enabled: boolean, autoScaleYaxis: boolean, text: string, align: string, show: boolean, autoSelected: string, xaxisType: string ): Options { const newoptions: Options = { chart: { id: chartName, zoom: { type, enabled, autoScaleYaxis }, toolbar: { show, autoSelected } }, title: { text, align }, xaxis: { type: xaxisType, categories: dataset.data.map((d: Array) => d[0]) }, dataLabels: { enabled: false } }; if (transposed) { newoptions.xaxis.categories = Array.from(new Set(newoptions.xaxis.categories)); } return newoptions; } export function Chart(props: Props) { const [chartProps, setChartProps] = useState({ options, series }); const [appState, setAppState] = useState({ state: AppStateType.INIT, processesOptions: { chart: { id: "", zoom: { type: "", enabled: false, autoScaleYaxis: false }, toolbar: { show: false, autoSelected: "" } }, xaxis: { type: "", categories: [] }, dataLabels: { enabled: false }, title: { text: "", align: "" } }, processesSeries: [{ name: "", data: [] }], configurationIssue: "" }); const onDataset = useCallback((ds: DataSet, params: Map) => { const transposed = params.get(Params.TRANSPOSED) === "true"; const validationMessage = validateParams(params) || validateDataSet(ds, transposed); if (validationMessage) { setAppState(previousAppState => ({ ...previousAppState, state: AppStateType.ERROR, message: validationMessage, configurationIssue: validationMessage })); } else { const op = getOptions( ds, transposed, params.get(Params.CHARTNAME), params.get(Params.ZOOMTYPE), params.get(Params.ZOOMENABLED), params.get(Params.ZOOMAUTOSCALEYAXIS), params.get(Params.TITLETEXT), params.get(Params.TITLEALIGN), params.get(Params.TOOLBARSHOW), params.get(Params.TOOLBARAUTOSELECTED), params.get(Params.XAXISTYPE), ); op.dataLabels.enabled = params.get(Params.DATALABELS) === "true"; op.chart.zoom.enabled = params.get(Params.ZOOMENABLED) === "true"; op.chart.zoom.autoScaleYaxis = params.get(Params.ZOOMAUTOSCALEYAXIS) === "true"; op.chart.toolbar.show = params.get(Params.TOOLBARSHOW) === "true"; setAppState(previousAppState => ({ ...previousAppState, processesOptions: op, processesSeries: getSeries(ds, transposed), state: AppStateType.FINISHED, configurationIssue: "" })); } }, []); useEffect(() => { props.controller.setOnInit(componentProps => { setChartProps({ type: componentProps.get(Params.SHOWAREA) === "true" ? "area" : "line", options: appState.processesOptions, series: appState.processesSeries }); }); props.controller.setOnDataSet(onDataset); }, [appState]); useEffect(() => { if (appState.configurationIssue) { props.controller.requireConfigurationFix(appState.configurationIssue); } else { props.controller.configurationOk(); } }, [appState.configurationIssue]); return (
    {(() => { switch (appState.state) { case AppStateType.ERROR: return {appState.message}; case AppStateType.LOADED_COMPONENT: case AppStateType.FINISHED: return ; default: return Status: {appState.state}; } })()}
    ); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/Data.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export interface Options { chart: { id: string; zoom: { type: string; enabled: boolean; autoScaleYaxis: boolean; }; toolbar: { show: boolean; autoSelected: string; }; }; title: { text: string; align: string; }; xaxis: { type: string; categories: Array; }; dataLabels: { enabled: boolean; }; } export interface SingleSeries { name: string; data: Array; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/LineChart.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { Options, SingleSeries } from "./Data"; import Chart from "react-apexcharts"; export type ChartType = "line" | "area"; export interface ChartProps { type?: ChartType; options: Options; series: SingleSeries[]; } export function LineChart(props: ChartProps) { return ; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/SampleData.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Options } from "./Data"; export const options: Options = { chart: { id: "apexchart-example", zoom: { type: 'x', enabled: true, autoScaleYaxis: true }, toolbar:{ show: true, autoSelected: 'zoom' } }, title:{ text: "Increase of series with time", align : "left" }, xaxis: { type: "category", categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999] }, dataLabels: { enabled: false } }; export const series = [ { name: "series-1", data: [30, 40, 35, 50, 49, 60, 70, 91, 125] } ]; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/index-dev.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import { Chart } from "./Chart"; import { ComponentDev } from "@dashbuilder-js/component-dev"; import { ComponentApi } from "@dashbuilder-js/component-api"; const api = new ComponentApi(); ReactDOM.render(, document.getElementById("app")!); new ComponentDev().start(); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/index.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import * as ReactDOM from "react-dom"; import {Chart} from "./Chart"; import { ComponentApi } from "@dashbuilder-js/component-api"; const api = new ComponentApi(); ReactDOM.render(, document.getElementById("app")!); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/tests/Chart.test.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { Chart, validateNonTransposedDataset, validateTransposedDataset, NOT_ENOUGH_COLUMNS_MSG_TRANSPOSED, NOT_ENOUGH_COLUMNS_MSG_NON_TRANSPOSED, SECOND_COLUMN_INVALID_MSG_TRANSPOSED, THIRD_COLUMN_INVALID_MSG_TRANSPOSED, CHARTNAME_VALIDATION, getSeriesforNonTransposedDataset, getSeriesforTransposedDataset, getOptions, validateChartName } from "../Chart"; import { ColumnType, ComponentApi } from "@dashbuilder-js/component-api"; import { shallow } from "enzyme"; import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; import "jest-enzyme"; configure({ adapter: new Adapter() }); const api = new ComponentApi(); const settings = { columnId: "", columnName: "", valueExpression: "", emptyTemplate: "" }; it("should test Chart component", () => { const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); describe("should test validateTransposedDataset", () => { it("should return not enough columns when columns are not enough", () => { const ds = { columns: [ { name: "category", type: ColumnType.TEXT, settings }, { name: "series", type: ColumnType.LABEL, settings } ], data: [[]] }; const result = validateTransposedDataset(ds); expect(result).toBe(NOT_ENOUGH_COLUMNS_MSG_TRANSPOSED); }); it("should test type of second column", () => { const ds = { columns: [ { name: "category", type: ColumnType.TEXT, settings }, { name: "series", type: ColumnType.NUMBER, settings }, { name: "series", type: ColumnType.NUMBER, settings } ], data: [[]] }; const result = validateTransposedDataset(ds); expect(result).toBe(SECOND_COLUMN_INVALID_MSG_TRANSPOSED); }); it("should test type of third column", () => { const ds = { columns: [ { name: "category", type: ColumnType.TEXT, settings }, { name: "series", type: ColumnType.TEXT, settings }, { name: "series", type: ColumnType.TEXT, settings } ], data: [[]] }; const result = validateTransposedDataset(ds); expect(result).toBe(THIRD_COLUMN_INVALID_MSG_TRANSPOSED); }); }); describe("should test validateNonTransposedDataset", () => { it("should test number of columns of validateNonTransposedDataset", () => { const ds = { columns: [ { name: "category", type: ColumnType.TEXT, settings } ], data: [[]] }; const result = validateNonTransposedDataset(ds); expect(result).toBe(NOT_ENOUGH_COLUMNS_MSG_NON_TRANSPOSED); }); it("should test type of second column of validateNonTransposedDataset", () => { const ds = { columns: [ { name: "category", type: ColumnType.TEXT, settings }, { name: "series-1", type: ColumnType.TEXT, settings } ], data: [[]] }; const result = validateNonTransposedDataset(ds); expect(result).toBe("Wrong type for column 2, it should be NUMBER"); }); }); describe("should test series and options for Transposed dataset", () => { it("should test getSeriesforTransposedDataset", () => { const ds = { columns: [ { name: "category", type: ColumnType.LABEL, settings }, { name: "series", type: ColumnType.LABEL, settings }, { name: "values", type: ColumnType.NUMBER, settings } ], data: [ ["2000", "series-1", "2"], ["2000", "series-2", "78"], ["2000", "series-3", "200"], ["2001", "series-1", "89"], ["2001", "series-2", "23"], ["2001", "series-3", "110"], ["2002", "series-1", "167"], ["2002", "series-2", "110"], ["2002", "series-3", "11"] ] }; const expectedResult = [ { name: "series-1", data: [2, 89, 167] }, { name: "series-2", data: [78, 23, 110] }, { name: "series-3", data: [200, 110, 11] } ]; const result = getSeriesforTransposedDataset(ds); expect(result).toStrictEqual(expectedResult); }); it("should test getOptions for transposed dataset", () => { const ds = { columns: [ { name: "category", type: ColumnType.LABEL, settings }, { name: "series", type: ColumnType.LABEL, settings }, { name: "values", type: ColumnType.NUMBER, settings } ], data: [ ["2000", "series-1", "2"], ["2000", "series-2", "78"], ["2000", "series-3", "200"], ["2001", "series-1", "89"], ["2001", "series-2", "23"], ["2001", "series-3", "110"], ["2002", "series-1", "167"], ["2002", "series-2", "110"], ["2002", "series-3", "11"] ] }; const expectedResult = { chart: { id: "new", zoom: { type: "x", enabled: false, autoScaleYaxis: false }, toolbar: { show: false, autoSelected: "zoom" } }, title: { text: "new", align: "left" }, xaxis: { type: "datetime", categories: ["2000", "2001", "2002"] }, dataLabels: { enabled: false } }; const result = getOptions(ds, true, "new", "x", false, false, "new", "left", false, "zoom", "datetime"); expect(result).toStrictEqual(expectedResult); }); }); describe("should test series and options for NonTransposed dataset", () => { it("should test getSeriesforNonTransposedDataset", () => { const ds = { columns: [ { name: "category", type: ColumnType.TEXT, settings }, { name: "series-1", type: ColumnType.TEXT, settings } ], data: [ ["2000", "2"], ["2001", "78"], ["2002", "200"] ] }; const expectedResult = [ { name: "series-1", data: [2, 78, 200] } ]; const result = getSeriesforNonTransposedDataset(ds); expect(result).toStrictEqual(expectedResult); }); it("should test getOptions for non-transposed dataset", () => { const ds = { columns: [ { name: "category", type: ColumnType.TEXT, settings }, { name: "series-1", type: ColumnType.TEXT, settings } ], data: [ ["2000", "2"], ["2001", "78"], ["2002", "200"] ] }; const expectedResult = { chart: { id: "new", zoom: { type: "x", enabled: false, autoScaleYaxis: false }, toolbar: { show: false, autoSelected: "zoom" } }, title: { text: "new", align: "left" }, xaxis: { type: "category", categories: ["2000", "2001", "2002"] }, dataLabels: { enabled: false } }; const result = getOptions(ds, false, "new", "x", false, false, "new", "left", false, "zoom", "category"); expect(result).toStrictEqual(expectedResult); }); }); describe("should test validateChartName", () => { it("should test special characters", () => { const result = validateChartName("foo+bar"); expect(result).toBe(CHARTNAME_VALIDATION); }); it("should test spaces", () => { const result = validateChartName("foo bar"); expect(result).toBe(CHARTNAME_VALIDATION); }); it("should test string without special characters", () => { const result = validateChartName("foobar"); expect(result).toBe(""); }); }); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/tests/LineChart.test.tsx ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { LineChart } from "../LineChart"; import { shallow } from "enzyme"; import { options, series } from "../SampleData"; import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; import "jest-enzyme"; configure({ adapter: new Adapter() }); it("Should test LineChart component with different props", () => { const wrapper = shallow(); expect(wrapper.html()).toMatchSnapshot(); wrapper.setProps({ type: "line", options, series }); expect(wrapper.html()).toMatchSnapshot(); wrapper.setProps({ type: "area", options, series }); expect(wrapper.html()).toMatchSnapshot(); }); ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/tests/__snapshots__/Chart.test.tsx.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should test Chart component 1`] = `
    Status: Initializing
    `; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/src/tests/__snapshots__/LineChart.test.tsx.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Should test LineChart component with different props 1`] = `"
    "`; exports[`Should test LineChart component with different props 2`] = `"
    "`; exports[`Should test LineChart component with different props 3`] = `"
    "`; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/static/index.html ================================================ Time series Component
    ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/static/manifest.dev.json ================================================ { "init": [ { "key": "transposed", "value": "true" }, { "key": "showArea", "value": "false" }, { "key": "chartName", "value": "newChart" }, { "key": "xaxisType", "value": "numeric" }, { "key": "dataLabels", "value": "true" }, { "key": "type", "value": "x" }, { "key": "enabled", "value": "true" }, { "key": "autoScaleYaxis", "value": "true" }, { "key": "text", "value": "New chart" }, { "key": "align", "value": "center" }, { "key": "show", "value": "true" }, { "key": "autoSelected", "value": "zoom" } ], "dataSet": { "columns": [ { "name": "category", "type": "TEXT" }, { "name": "series", "type": "LABEL" }, { "name": "values", "type": "NUMBER" } ], "data": [ ["1 Feb", "series-1", 2], ["1 Feb", "series-2", 78], ["1 Feb", "series-3", 200], ["2 Feb", "series-1", 89], ["2 Feb", "series-2", 23], ["2 Feb", "series-3", 110], ["3 Feb", "series-1", 167], ["3 Feb", "series-2", 110], ["3 Feb", "series-3", 11], ["4 Feb", "series-1", 70], ["4 Feb", "series-2", 34], ["4 Feb", "series-3", 57], ["5 Feb", "series-1", 110], ["5 Feb", "series-2", 140], ["5 Feb", "series-3", 1] ] } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/static/manifest.json ================================================ { "name": "Time Series Chart", "category": "Reporting", "icon": "fa fa-bell-o", "parameters": [ { "name": "transposed", "type": "boolean", "defaultValue": "false", "label": "Transpose dataset" }, { "name": "showArea", "type": "boolean", "defaultValue": "false", "label": "Show Area" }, { "name": "xaxisType", "type": "combo", "defaultValue": "category", "comboValues": ["category", "datetime", "numeric"], "label": "Date Categories" }, { "name": "dataLabels", "type": "boolean", "defaultValue": "false", "label": "Labels" }, { "name": "type", "type": "combo", "defaultValue": "x", "comboValues": ["x", "y", "xy"], "label": "Zoom type" }, { "name": "enabled", "type": "boolean", "defaultValue": "true", "label": "Zoom enabled" }, { "name": "autoScaleYaxis", "type": "boolean", "defaultValue": "false", "label": "Zoom autoscale Y axis" }, { "name": "autoSelected", "type": "combo", "defaultValue": "zoom", "comboValues": ["zoom", "selection", "pan"], "label": "Toolbar Auto Selected" }, { "name": "text", "type": "string", "defaultValue": "Comparison in series", "label": "Title text" }, { "name": "align", "type": "combo", "defaultValue": "left", "comboValues": ["left", "center", "right"], "label": "Title align" }, { "name": "show", "type": "boolean", "defaultValue": "true", "label": "Show toolbar" }, { "name": "chartName", "type": "string", "defaultValue": "Newchart", "label": "Chart Name" } ] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/tsconfig.json ================================================ { "extends": "../../tsconfig.json", "compilerOptions": { "declaration": false, "allowSyntheticDefaultImports": true, "esModuleInterop": true }, "include": ["src"] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/packages/time-series-component/webpack.config.js ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require("path"); const CopyPlugin = require("copy-webpack-plugin"); const { merge } = require("webpack-merge"); const common = require("../../webpack.common.config"); module.exports = async (env, argv) => { let entryPoint = "./src/index.tsx"; const copyResources = [ { from: "./static/index.html", to: "./index.html" }, { from: "./static/manifest.json", to: "./manifest.json" } ]; if (process.env.WEBPACK_DEV_SERVER) { entryPoint = "./src/index-dev.tsx"; copyResources.push({ from: "./static/manifest.dev.json", to: "./manifest.dev.json" }); } return merge(common, { entry: { index: entryPoint }, module: { rules: [ { test: /\.css$/i, use: ["style-loader", "css-loader"], }, { test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i, loader: "url-loader", options: { limit: 8192, }, }, ], }, plugins: [new CopyPlugin(copyResources)], devServer: { historyApiFallback: false, disableHostCheck: true, watchContentBase: true, contentBase: [path.join(__dirname, "./dist"), path.join(__dirname, "./static")], compress: true, port: 9001 } }); }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-shared 7.75.0-SNAPSHOT ../pom.xml jar dashbuilder-js Dashbuilder JS Dashbuilder JS APIs and internal components for displaying data org.uberfire appformer-js-monaco provided logo-provided,process-heatmap-provided,processes-heatmaps-provided,time-series-provided web/dashbuilder/components org.codehaus.mojo properties-maven-plugin 1.0.0 generate-resources write-project-properties ${project.build.outputDirectory}/dashbuilder-components.properties com.github.eirslett frontend-maven-plugin ${project.build.directory} install yarn install-node-and-yarn install node and npm initialize install-node-and-npm yarn run init yarn run init lock-treatment-tool execution initialize npm exec @kie/lock-treatment-tool@${version.lock-treatment-tool} -- yarn run build:prod yarn run build:prod maven-resources-plugin copy-logo-component prepare-package copy-resources ${project.build.outputDirectory}/${dashbuilder.internal.components.root}/logo-provided packages/logo-component/dist/ false copy-process-heatmap-component prepare-package copy-resources ${project.build.outputDirectory}/${dashbuilder.internal.components.root}/process-heatmap-provided packages/process-heatmap-component/dist/ false copy-processes-heatmaps-component prepare-package copy-resources ${project.build.outputDirectory}/${dashbuilder.internal.components.root}/processes-heatmaps-provided packages/processes-heatmaps-component/dist/ false copy-time-series-component prepare-package copy-resources ${project.build.outputDirectory}/${dashbuilder.internal.components.root}/time-series-provided packages/time-series-component/dist/ false org.eclipse.m2e lifecycle-mapping 1.0.0 org.apache.maven.plugins maven-antrun-plugin [1.8,) run ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/prettier.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = { printWidth: 120 }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/src/main/java/org/dashbuilder/components/internal/ProvidedComponentInfo.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.components.internal; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; /** * Access internal component information and expose during runtime. * */ public class ProvidedComponentInfo { Logger logger = Logger.getLogger(ProvidedComponentInfo.class.getName()); private static final String DASHBUILDER_COMPONENTS_PROPERTIES = "/dashbuilder-components.properties"; private static final String DASHBUILDER_COMPONENTS_LIST_PROP = "dashbuilder.internal.components.list"; private static final String DASHBUILDER_COMPONENTS_ROOT_PROP = "dashbuilder.internal.components.root"; private static ProvidedComponentInfo instance; private List internalComponentsList = Collections.emptyList(); private String internalComponentsRootPath = null; ProvidedComponentInfo() {} public static ProvidedComponentInfo get() { if (instance == null) { instance = new ProvidedComponentInfo(); instance.loadProperties(DASHBUILDER_COMPONENTS_PROPERTIES); } return instance; } void loadProperties(String resourcePath) { InputStream is = this.getClass().getResourceAsStream(resourcePath); if (is == null) { logger.warning("Not able to find internal components properties file."); return; } try { Properties properties = new Properties(); properties.load(is); loadInternalComponentsList(properties); loadInternalComponentsRootDir(properties); } catch (IOException e) { logger.warning("Not able to load internal components properties file."); } } private void loadInternalComponentsRootDir(Properties properties) { internalComponentsRootPath = properties.getProperty(DASHBUILDER_COMPONENTS_ROOT_PROP); if (internalComponentsRootPath == null || internalComponentsRootPath.trim().isEmpty()) { logger.warning("Internal components root not configured."); } } private void loadInternalComponentsList(Properties properties) { String componentsListStr = properties.getProperty(DASHBUILDER_COMPONENTS_LIST_PROP); if (componentsListStr == null || componentsListStr.trim().isEmpty()) { logger.warning("Internal components list is empty"); } else { this.internalComponentsList = Arrays.stream(componentsListStr.split("\\,")).collect(Collectors.toList()); logger.log(Level.INFO, () -> "Registered internal dashbuilder components: " + internalComponentsList); } } public List getInternalComponentsList() { return internalComponentsList; } public String getInternalComponentsRootPath() { return internalComponentsRootPath; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/src/test/java/org/dashbuilder/components/internal/InternalComponentsInfoTest.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.components.internal; import java.util.List; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; /** * Access internal component information and expose during runtime. * */ public class InternalComponentsInfoTest { @Test public void testMissingPropertiesFile() { ProvidedComponentInfo internalComponentsInfo = new ProvidedComponentInfo(); internalComponentsInfo.loadProperties("do not exist"); List components = internalComponentsInfo.getInternalComponentsList(); assertTrue(components.isEmpty()); assertNull(internalComponentsInfo.getInternalComponentsRootPath()); } @Test public void testFoundPropertiesFile() { ProvidedComponentInfo internalComponentsInfo = ProvidedComponentInfo.get(); List components = internalComponentsInfo.getInternalComponentsList(); assertTrue(components.contains("c1")); assertTrue(components.contains("c2")); assertEquals("path/to/components", internalComponentsInfo.getInternalComponentsRootPath()); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/src/test/resources/dashbuilder-components.properties ================================================ dashbuilder.internal.components.root=path/to/components dashbuilder.internal.components.list=c1,c2 ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/tsconfig.json ================================================ { "exclude": ["./**/node_modules", "./**/__tests__"], "compilerOptions": { "lib": ["es6", "dom", "es2018.promise"], "target": "es5", "declaration": true, "sourceMap": true, "noImplicitAny": true, "noImplicitThis": true, "strictNullChecks": true, "experimentalDecorators": true, "downlevelIteration": true, "jsx": "react" } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/tslint.json ================================================ { "defaultSeverity": "error", "extends": [ "tslint:recommended", "tslint-react", "tslint-config-prettier" ], "jsRules": {}, "rules": { "jsx-no-multiline-js": false, "ordered-imports": false, "object-literal-sort-keys": false, "no-console": false, "interface-name": [ true, "never-prefix" ], "max-classes-per-file": false, "jsx-no-lambda": false, "member-ordering": [ true, { "order": [ "static-field", "instance-field", "constructor", "instance-method", "static-method" ] } ], "variable-name": [ true, "ban-keywords", "check-format", "allow-snake-case", "allow-pascal-case", "allow-leading-underscore" ], "comment-format": false }, "rulesDirectory": [] } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-js/webpack.common.config.js ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const path = require("path"); module.exports = { mode: "development", devtool: "inline-source-map", output: { path: path.resolve("./dist"), filename: "[name].js" }, stats: { excludeModules: true }, performance: { maxAssetSize: 30000000, maxEntrypointSize: 30000000 }, resolve: { extensions: [".tsx", ".ts", ".js", ".jsx"], modules: [path.resolve("../../node_modules"), path.resolve("./node_modules"), path.resolve("./src")] }, module: { rules: [ { test: /\.tsx?$/, loader: "ts-loader" } ] } }; ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-shared 7.75.0-SNAPSHOT dashbuilder-kie-server-api jar Dashbuilder Kie Server API Dashbuilder Kie Server API without BC dependencies javax.validation validation-api provided org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-dataset-sql org.jboss.errai errai-bus org.jboss.errai errai-common ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/java/org/dashbuilder/kieserver/ConsoleDataSetLookup.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetOp; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ConsoleDataSetLookup extends DataSetLookup { private String serverTemplateId; public static DataSetLookup fromInstance(DataSetLookup orig, String serverTemplateId) { ConsoleDataSetLookup clone = new ConsoleDataSetLookup(); clone.setDataSetUUID(orig.getDataSetUUID()); clone.setRowOffset(orig.getRowOffset()); clone.setNumberOfRows(orig.getNumberOfRows()); for (DataSetOp dataSetOp : orig.getOperationList()) { clone.getOperationList().add(dataSetOp.cloneInstance()); } clone.setServerTemplateId(serverTemplateId); return clone; } public String getServerTemplateId() { return serverTemplateId; } public void setServerTemplateId(String serverTemplateId) { this.serverTemplateId = serverTemplateId; } @Override public DataSetLookup cloneInstance() { return fromInstance(super.cloneInstance(), getServerTemplateId()); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/java/org/dashbuilder/kieserver/KieServerConnectionInfo.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver; import java.util.Optional; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; /** * Kie Server Connection information * */ @Portable public class KieServerConnectionInfo { private Optional location; private Optional user; private Optional password; private Optional token; private boolean replaceQuery; public KieServerConnectionInfo(@MapsTo("location") Optional location, @MapsTo("user") Optional user, @MapsTo("password") Optional password, @MapsTo("token") Optional token, @MapsTo("replaceQuery") boolean replaceQuery) { this.location = location; this.user = user; this.password = password; this.token = token; this.replaceQuery = replaceQuery; } public Optional getLocation() { return location; } public Optional getUser() { return user; } public Optional getPassword() { return password; } public Optional getToken() { return token; } public boolean isReplaceQuery() { return replaceQuery; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/java/org/dashbuilder/kieserver/KieServerConnectionInfoProvider.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver; import java.util.List; import java.util.Optional; import org.jboss.errai.bus.server.annotations.Remote; @Remote public interface KieServerConnectionInfoProvider { Optional get(String name, String serverTemplate); List serverTemplates(); KieServerConnectionInfo verifiedConnectionInfo(RemoteDataSetDef def); Optional getDefault(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/java/org/dashbuilder/kieserver/RemoteDataSetDef.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class RemoteDataSetDef extends SQLDataSetDef { @NotNull(groups = {RemoteDataSetDefValidation.class}) @Size(min = 1, groups = {RemoteDataSetDefValidation.class}) protected String queryTarget; @NotNull(groups = {RemoteDataSetDefValidation.class}) @Size(min = 1, groups = {RemoteDataSetDefValidation.class}) protected String serverTemplateId; protected String queryName; public RemoteDataSetDef() { super.setProvider(new RuntimeKieServerDataSetProviderType()); } public String getQueryTarget() { return queryTarget; } public void setQueryTarget(String queryTarget) { this.queryTarget = queryTarget; } public String getServerTemplateId() { return serverTemplateId; } public void setServerTemplateId(String serverTemplateId) { this.serverTemplateId = serverTemplateId; } public String getQueryName() { return queryName; } public void setQueryName(String queryName) { this.queryName = queryName; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((queryTarget == null) ? 0 : queryTarget.hashCode()); result = prime * result + ((serverTemplateId == null) ? 0 : serverTemplateId.hashCode()); result = prime * result + ((queryName == null) ? 0 : queryName.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; RemoteDataSetDef other = (RemoteDataSetDef) obj; if (queryTarget == null) { if (other.queryTarget != null) return false; } else if (!queryTarget.equals(other.queryTarget)) return false; if (serverTemplateId == null) { if (other.serverTemplateId != null) return false; } else if (!serverTemplateId.equals(other.serverTemplateId)) return false; if (queryName == null) { if (other.queryName != null) return false; } else if (!queryName.equals(other.queryName)) return false; return true; } @Override public DataSetDef clone() { RemoteDataSetDef def = new RemoteDataSetDef(); clone(def); def.setQueryTarget(getQueryTarget()); def.setServerTemplateId(getServerTemplateId()); def.setDbSQL(getDbSQL()); def.setDataSource(getDataSource()); def.setQueryName(getQueryName()); return def; } public String toString() { StringBuilder out = new StringBuilder(); out.append("UUID=").append(UUID).append("\n"); out.append("Provider=").append(provider).append("\n"); out.append("Public=").append(isPublic).append("\n"); out.append("Push enabled=").append(pushEnabled).append("\n"); out.append("Push max size=").append(pushMaxSize).append(" Kb\n"); if (refreshTime != null) { out.append("Refresh time=").append(refreshTime).append("\n"); out.append("Refresh always=").append(refreshAlways).append("\n"); } out.append("Data source=").append(dataSource).append("\n"); out.append("Query target=").append(queryTarget).append("\n"); out.append("Query id=").append(queryName).append("\n"); out.append("Server template id=").append(serverTemplateId).append("\n"); out.append("DB SQL=").append(dbSQL).append("\n"); out.append("Get all columns=").append(allColumnsEnabled).append("\n"); out.append("Cache enabled=").append(cacheEnabled).append("\n"); out.append("Cache max rows=").append(cacheMaxRows).append(" Kb\n"); return out.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/java/org/dashbuilder/kieserver/RemoteDataSetDefValidation.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver; public interface RemoteDataSetDefValidation { } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/java/org/dashbuilder/kieserver/RemoteDefJSONMarshaller.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver; import org.dashbuilder.dataset.json.DataSetDefJSONMarshallerExt; import org.dashbuilder.json.JsonObject; import static org.dashbuilder.dataset.json.DataSetDefJSONMarshaller.ALL_COLUMNS; import static org.dashbuilder.dataset.json.DataSetDefJSONMarshaller.isBlank; public class RemoteDefJSONMarshaller implements DataSetDefJSONMarshallerExt { public static RemoteDefJSONMarshaller INSTANCE = new RemoteDefJSONMarshaller(); public static final String QUERY_TARGET = "queryTarget"; public static final String SERVER_TEMPLATE_ID = "serverTemplateId"; public static final String DATA_SOURCE = "dataSource"; public static final String DB_SCHEMA = "dbSchema"; public static final String DB_SQL = "dbSQL"; @Override public void fromJson(RemoteDataSetDef def, JsonObject json) { String queryTarget = json.getString(QUERY_TARGET); String serverTemplateId = json.getString(SERVER_TEMPLATE_ID); String dataSource = json.getString(DATA_SOURCE); String dbSchema = json.getString(DB_SCHEMA); String dbSQL = json.getString(DB_SQL); if (!isBlank(queryTarget)) { def.setQueryTarget(queryTarget); } if (!isBlank(serverTemplateId)) { def.setServerTemplateId(serverTemplateId); } if (!isBlank(dataSource)) { def.setDataSource(dataSource); } if (!isBlank(dbSchema)) { def.setDbSchema(dbSchema); } if (!isBlank(dbSQL)) { def.setDbSQL(dbSQL); } } @Override public void toJson(RemoteDataSetDef dataSetDef, JsonObject json) { // Data source. json.put(DATA_SOURCE, dataSetDef.getDataSource()); // Schema. json.put(DB_SCHEMA, dataSetDef.getDbSchema()); // Query. if (dataSetDef.getDbSQL() != null) { json.put(DB_SQL, dataSetDef.getDbSQL()); } json.put(QUERY_TARGET, dataSetDef.getQueryTarget()); json.put(SERVER_TEMPLATE_ID, dataSetDef.getServerTemplateId()); // All columns flag. json.put(ALL_COLUMNS, dataSetDef.isAllColumnsEnabled()); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/java/org/dashbuilder/kieserver/RuntimeKieServerDataSetProviderType.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.kieserver; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.json.DataSetDefJSONMarshallerExt; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class RuntimeKieServerDataSetProviderType implements DataSetProviderType { public static final String NAME = "REMOTE"; public RuntimeKieServerDataSetProviderType() { } @Override public String getName() { return NAME; } @Override public RemoteDataSetDef createDataSetDef() { RemoteDataSetDef def = new RemoteDataSetDef(); def.setProvider(this); def.setDataSource("${org.kie.server.persistence.ds}"); return def; } @Override public DataSetDefJSONMarshallerExt getJsonMarshaller() { return RemoteDefJSONMarshaller.INSTANCE; } @Override public boolean equals(Object obj) { if (!(obj instanceof RuntimeKieServerDataSetProviderType)) { return false; } return getName().equals(((RuntimeKieServerDataSetProviderType) obj).getName()); } @Override public int hashCode() { return getName().hashCode(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-kie-server-api/src/main/resources/org/dashbuilder/DashbuilderKieServerAPI.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-shared 7.75.0-SNAPSHOT dashbuilder-navigation-api jar Dashbuilder Navigation API Dashbuilder Navigation API shared between client and server org.jboss.errai errai-common org.jboss.errai errai-bus org.jboss.errai errai-security-server org.uberfire uberfire-api org.uberfire uberfire-runtime-plugins-api org.uberfire uberfire-layout-editor-api org.uberfire uberfire-security-api org.kie.soup kie-soup-json ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/NavDivider.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; /** * A {@link NavItem} that represents a divider */ public interface NavDivider extends NavItem { } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/NavFactory.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import org.dashbuilder.navigation.impl.NavFactoryImpl; /** * A factory interface for the creation of {@link NavTree} and {@link NavItem} instances. */ public interface NavFactory { NavFactory[] _instance = new NavFactory[] {new NavFactoryImpl()}; static NavFactory get() { return _instance[0]; } static void set(NavFactory factory) { _instance[0] = factory; } NavTree createNavTree(NavItem navItem); NavTree createNavTree(); NavGroup createNavGroup(); NavGroup createNavGroup(NavTree navTree); NavItem createNavItem(); NavDivider createDivider(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/NavGroup.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import java.util.List; /** * A {@link NavItem} that contains a list of children. */ public interface NavGroup extends NavItem { /** * Get the children items */ List getChildren(); /** * Change the children list */ void setChildren(List items); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/NavItem.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; /** * A navigation item is a way to classify different assets, like for instance, perspectives. A tag can be referenced by other * tags, either as a parent or as a child. The links between different tags creates a {@link NavTree} structure * that can be used to provide navigation services across the different assets referenced by the tags in the tree. */ public interface NavItem { enum Type { ITEM, GROUP, DIVIDER; } /** * A unique id within the same {@link NavTree} */ String getId(); /** * Change the item's id */ void setId(String id); /** * The item's name */ String getName(); /** * Change the item's name */ void setName(String name); /** * A brief description of the item (optional, if not provided the name is used instead) */ String getDescription(); /** * Change the item's description */ void setDescription(String description); /** * The item's {@link Type} */ Type getType(); /** * Get the parent of this item (if any) * * @return The item this one is a child of. Or null if this is a root item */ NavGroup getParent(); /** * Change the item's parent */ void setParent(NavGroup parent); /** * Flag indicating if the item can be modified from a tree once added */ boolean isModifiable(); /** * Change the item's modifiable flag */ void setModifiable(boolean modifiable); /** * An optional string that can be used to attach contextual information, like an external reference for instance. */ String getContext(); /** * Change the item's context attribute */ void setContext(String ctx); /** * Entry point for visitor interfaces */ void accept(NavItemVisitor visitor); /** * Creates a brand new copy of this item */ NavItem cloneItem(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/NavItemContext.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import java.util.Collection; import org.dashbuilder.navigation.impl.NavItemContextImpl; /** * An interface for manipulating a {@link NavItem#getContext()} as it was a collection of attribute/value pairs. */ public interface NavItemContext { static NavItemContext create() { return new NavItemContextImpl(); } static NavItemContext get(String ctx) { return new NavItemContextImpl(ctx); } static NavItemContext get(NavItem navItem) { return new NavItemContextImpl(navItem.getContext()); } void init(String ctx); Collection getPropertyIds(); String getProperty(String id); String removeProperty(String id); NavItemContext setProperty(String id, String value); /** * Check if this context contains all property-value pairs of some other context. * * @param cxt * @return true iff all the properties of ctx are also present in this context and have the same value. */ boolean includesPropertiesOf(NavItemContext cxt); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/NavItemVisitor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; /** * {@link NavItem} visitor interface */ public interface NavItemVisitor { /** * Visit the given {@link NavGroup}. * * @param group The node to visit */ void visitGroup(NavGroup group); /** * Visit the given {@link NavItem}. * * @param item The node to visit */ void visitItem(NavItem item); /** * Visit the given {@link NavDivider}. * * @param divider The node to visit */ void visitDivider(NavDivider divider); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/NavTree.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import java.util.List; /** * A tree like structure containing a list of parent and children nodes where every node is a {@link NavItem} instance. */ public interface NavTree { /** * The list of items belonging to the first tree level * * @return A list of {@link NavItem} instances */ List getRootItems(); /** * Get an item given its id. All the tree nodes are compared, no matter its level. * * @param id The unique identifier of the item * @return The first instance found */ NavItem getItemById(String id); /** * Given an existing item, it creates a brand new subtree where the item (or its children in case of groups) * is taken as the root node. * * @param id The unique identifier of the item * @return The first instance found */ NavTree getItemAsTree(String id); /** * Get the items that match the given context * * @param ctx The context to search for * @return The list of nav items that match the target context */ List searchItems(NavItemContext ctx); /** * Creates and register a brand new {@link NavGroup} item. * * @param id The unique id of the item * @param name The item's name * @param description A brief description of the item * @param groupId The identifier of an existing node in the tree where to append the newly created item as a child * @param modifiable Flag indicating if the item can be modified once added * * @return The instance just created */ NavGroup addGroup(String id, String name, String description, String groupId, boolean modifiable); /** * Creates and register a brand new {@link NavItem} item. * * @param id The unique id of the item * @param name The item's name * @param description A brief description of the item * @param groupId The identifier of an existing node in the tree where to append the newly created item as a child * @param modifiable Flag indicating if the item can be modified once added * @param context An string that contains item related information, like an external reference for instance. * * @return The instance just created */ NavItem addItem(String id, String name, String description, String groupId, boolean modifiable, String context); /** * Creates and register a brand new {@link NavDivider} item. * * @param groupId The identifier of an existing node in the tree where to append the newly created item as a child * @param modifiable Flag indicating if the item can be modified once added * * @return The instance just created */ NavDivider addDivider(String groupId, boolean modifiable); /** * Delete an existing item including all its children. * * @param id The unique identifier of the item * @return The instance removed or null if the instance is not found */ NavItem deleteItem(String id); /** * Updates the name attribute of an existing item * * @param id The unique id of the item * @param name A brief description of the item * * @return The instance being updated */ NavItem setItemName(String id, String name); /** * Updates the description attribute of an existing item * * @param id The unique id of the item * @param description A brief description of the item * * @return The instance being updated */ NavItem setItemDescription(String id, String description); /** * Updates the modifiable flag attribute of an existing item * * @param id The unique id of the item * @param modifiable Flag indicating if the item can be modified * * @return The instance being updated */ NavItem setItemModifiable(String id, boolean modifiable); /** * Updates the perspective attached to an existing perspective link * * @param id The unique id of the item * @param context The item's context * * @return The item being updated */ NavItem setItemContext(String id, String context); /** * Changes the location of an item in the tree * * @param id The unique id of the item * @param newParentId The identifier of an existing node in the tree where to move the item * * @return The instance being updated */ NavItem moveItem(String id, String newParentId); /** * Move the specified item to the first position within its parent's children list * * @param id The unique id of the item */ void moveItemFirst(String id); /** * Move the specified item to the last position within its parent's children list * * @param id The unique id of the item */ void moveItemLast(String id); /** * Move an item one position up in its parent's children list * * @param id The unique id of the item */ void moveItemUp(String id); /** * Move an item one position down in its parent's children list * * @param id The unique id of the item */ void moveItemDown(String id); /** * Entry point for visitor interfaces */ void accept(NavItemVisitor visitor); /** * Creates a brand new copy of this tree */ NavTree cloneTree(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/event/NavTreeChangedEvent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.event; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.common.client.api.annotations.Portable; /** * Event fired when the application navigation tree is changed */ @Portable public class NavTreeChangedEvent { private NavTree navTree; public NavTreeChangedEvent() { } public NavTreeChangedEvent(NavTree navTree) { this.navTree = navTree; } public NavTree getNavTree() { return navTree; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/event/PerspectivePluginsChangedEvent.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.event; /** * Event fired when a perspective plugin is either added, renamed or deleted. */ public class PerspectivePluginsChangedEvent { } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/impl/NavDividerImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.impl; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemVisitor; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class NavDividerImpl extends NavItemImpl implements NavDivider { public NavDividerImpl() { type = Type.DIVIDER; } @Override public void accept(NavItemVisitor visitor) { visitor.visitDivider(this); } @Override public NavItem cloneItem() { NavDividerImpl clone = new NavDividerImpl(); clone.id = this.id; clone.parent = this.parent; clone.name = this.name; clone.description = this.description; clone.modifiable = this.modifiable; clone.context = this.context; return clone; } public String toString() { return super.toString("DIVIDER"); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/impl/NavFactoryImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.impl; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; public class NavFactoryImpl implements NavFactory { @Override public NavTree createNavTree(NavItem navItem) { if (navItem instanceof NavGroup) { NavGroup root = (NavGroup) navItem.cloneItem(); root.setParent(null); root.getChildren().forEach(e -> e.setParent(null)); return new NavTreeImpl(root); } else { NavItem i = navItem.cloneItem(); i.setParent(null); NavTreeImpl tree = new NavTreeImpl(); tree.getRootItems().add(i); return tree; } } @Override public NavTree createNavTree() { return new NavTreeImpl(); } @Override public NavGroup createNavGroup() { return new NavGroupImpl(); } @Override public NavGroup createNavGroup(NavTree navTree) { NavGroup navGroup = createNavGroup(); navGroup.setChildren(navTree.cloneTree().getRootItems()); navGroup.getChildren().forEach(child -> child.setParent(navGroup)); return navGroup; } @Override public NavItem createNavItem() { return new NavItemImpl(); } @Override public NavDivider createDivider() { return new NavDividerImpl(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/impl/NavGroupImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.impl; import java.util.ArrayList; import java.util.List; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemVisitor; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class NavGroupImpl extends NavItemImpl implements NavGroup { List children = new ArrayList<>(); public NavGroupImpl() { type = Type.GROUP; } @Override public List getChildren() { return children; } @Override public void setChildren(List children) { this.children = children; } @Override public void accept(NavItemVisitor visitor) { visitor.visitGroup(this); for (NavItem child : children) { child.accept(visitor); } } @Override public NavItem cloneItem() { NavGroupImpl clone = new NavGroupImpl(); clone.id = this.id; clone.name = this.name; clone.parent = this.parent; clone.description = this.description; clone.modifiable = this.modifiable; clone.context = this.context; for (NavItem child : children) { NavItem childClone = child.cloneItem(); clone.children.add(childClone); childClone.setParent(clone); } return clone; } @Override public String toString() { StringBuilder out = new StringBuilder(super.toString("GROUP")); out.append("CHILDREN=["); children.forEach(i -> out.append(i.getId()).append(" ")); out.append("]\n"); return out.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/impl/NavItemContextImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.impl; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.dashbuilder.navigation.NavItemContext; public class NavItemContextImpl implements NavItemContext { Map ctxMap = new HashMap<>(); public NavItemContextImpl() { } public NavItemContextImpl(String ctx) { init(ctx); } @Override public void init(String ctx) { ctxMap.clear(); if (ctx != null && ctx.length() > 0) { // TODO: encoding String[] tokens = ctx.split(";"); for(int i=0;i getPropertyIds() { return ctxMap.keySet(); } @Override public String getProperty(String id) { return ctxMap.get(id); } @Override public String removeProperty(String id) { return ctxMap.remove(id); } @Override public NavItemContext setProperty(String id, String value) { ctxMap.put(id, value); return this; } @Override public boolean includesPropertiesOf(NavItemContext ctx) { for (String p : ctx.getPropertyIds()) { String v1 = this.getProperty(p); String v2 = ctx.getProperty(p); if (v1 == null && v2 != null) { return false; } if (v1 != null && !v1.equals(v2)) { return false; } } return true; } @Override public String toString() { StringBuilder out = new StringBuilder(); ctxMap.keySet().forEach(k -> { out.append(k).append("=").append(ctxMap.get(k)).append(";"); }); return out.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/impl/NavItemImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.impl; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemVisitor; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class NavItemImpl implements NavItem { String id = null; String name = null; String description = null; NavGroup parent = null; boolean modifiable = true; String context = null; Type type = Type.ITEM; public NavItemImpl() { } public NavItemImpl(String id, String name, String description, NavGroup parent, boolean modifiable, String context) { this.id = id; this.name = name; this.description = description; this.parent = parent; this.modifiable = modifiable; this.context = context; } @Override public String getId() { return id; } @Override public void setId(String id) { this.id = id; } @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } @Override public String getDescription() { return description; } @Override public void setDescription(String description) { this.description = description; } @Override public Type getType() { return type; } @Override public NavGroup getParent() { return parent; } @Override public void setParent(NavGroup parent) { this.parent = parent; } public boolean isModifiable() { return modifiable; } public void setModifiable(boolean modifiable) { this.modifiable = modifiable; } @Override public void accept(NavItemVisitor visitor) { visitor.visitItem(this); } @Override public String getContext() { return context; } @Override public void setContext(String context) { this.context = context; } @Override public boolean equals(Object obj) { if (id == null || obj == null || !(obj instanceof NavItem)) { return false; } NavItem other = (NavItem) obj; return id.equals(other.getId()); } @Override public NavItem cloneItem() { NavItemImpl clone = new NavItemImpl(); clone.id = this.id; clone.parent = this.parent; clone.name = this.name; clone.description = this.description; clone.modifiable = this.modifiable; clone.context = this.context; return clone; } public String toString() { return toString("ITEM"); } public String toString(String type) { StringBuilder out = new StringBuilder(); out.append(type).append("=").append(id).append("\n"); out.append("NAME=").append(name).append("\n"); out.append("DESCRIPTION=").append(description).append("\n"); out.append("DELETABLE=").append(modifiable).append("\n"); out.append("PARENT=").append(parent).append("\n"); out.append("CONTEXT=").append(context).append("\n"); return out.toString(); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/impl/NavTreeBuilder.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.impl; import java.util.Stack; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavItemContext; import org.dashbuilder.navigation.NavTree; public class NavTreeBuilder { NavFactory factory = NavFactory.get(); Stack stack = new Stack<>(); NavGroup root = factory.createNavGroup(); public NavTreeBuilder() { stack.push(root); } public NavTreeBuilder group(String id, String name, String description, boolean modifiable) { NavGroup item = factory.createNavGroup(); item.setId(id); item.setName(name); item.setDescription(description); item.setModifiable(modifiable); stackGroup(item); return this; } public NavTreeBuilder item(String id, String name, String description, boolean modifiable) { return item(id, name, description, modifiable, (String) null); } public NavTreeBuilder item(String id, String name, String description, boolean modifiable, NavItemContext itemCtx) { return item(id, name, description, modifiable, itemCtx != null ? itemCtx.toString() : null); } public NavTreeBuilder item(String id, String name, String description, boolean modifiable, String itemCtx) { NavItem item = factory.createNavItem(); item.setId(id); item.setName(name); item.setDescription(description); item.setModifiable(modifiable); item.setContext(itemCtx); stackItem(item); return this; } public NavTreeBuilder divider() { NavDivider item = factory.createDivider(); item.setId(Integer.toString(item.hashCode())); stackItem(item); return this; } public NavTreeBuilder endGroup() { if (!stack.isEmpty()) { stack.pop(); } else { throw new IllegalStateException("Call group first"); } return this; } public NavTree build() { return new NavTreeImpl(root); } private void stackGroup(NavGroup item) { stackItem(item); stack.push(item); } private void stackItem(NavItem item) { NavGroup group = stack.peek(); item.setParent(group == root ? null : group); group.getChildren().add(item); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/impl/NavTreeImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.impl; import java.util.ArrayList; import java.util.List; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemContext; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.NavItemVisitor; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class NavTreeImpl implements NavTree { private NavGroup root; public NavTreeImpl() { root = NavFactory.get().createNavGroup(); } public NavTreeImpl(NavGroup root) { this.root = root; } public List getRootItems() { return root.getChildren(); } @Override public NavItem getItemById(String id) { return getItemById(id, root.getChildren()); } private NavItem getItemById(String id, List navItemList) { if (id == null) { return null; } for (NavItem navItem : navItemList) { if (navItem.getId() != null && navItem.getId().equals(id)) { return navItem; } if (navItem instanceof NavGroup) { NavItem child = getItemById(id, ((NavGroup) navItem).getChildren()); if (child != null) { return child; } } } return null; } @Override public NavTree getItemAsTree(String id) { NavItem item = getItemById(id); return item != null ? NavFactory.get().createNavTree(item) : null; } @Override public List searchItems(NavItemContext ctx) { return searchItems(ctx, getRootItems()); } public List searchItems(NavItemContext ctx, List navItemList) { List result = new ArrayList<>(); if (ctx == null) { return result; } NavItemContext niCtx = NavItemContext.create(); for (NavItem navItem : navItemList) { niCtx.init(navItem.getContext()); if (niCtx.includesPropertiesOf(ctx)) { result.add(navItem); } if (navItem instanceof NavGroup) { List children = searchItems(ctx, ((NavGroup) navItem).getChildren()); result.addAll(children); } } return result; } @Override public NavGroup addGroup(String id, String name, String description, String parentId, boolean modifiable) { NavGroup newNavItem = NavFactory.get().createNavGroup(); newNavItem.setId(id); newNavItem.setName(name); newNavItem.setDescription(description); newNavItem.setModifiable(modifiable); addItem(newNavItem, parentId); return newNavItem; } @Override public NavItem addItem(String id, String name, String description, String parentId, boolean modifiable, String context) { NavItem newNavItem = NavFactory.get().createNavItem(); newNavItem.setId(id); newNavItem.setName(name); newNavItem.setDescription(description); newNavItem.setModifiable(modifiable); newNavItem.setContext(context); addItem(newNavItem, parentId); return newNavItem; } @Override public NavDivider addDivider(String parentId, boolean modifiable) { NavDivider newNavItem = NavFactory.get().createDivider(); newNavItem.setId(Integer.toString(newNavItem.hashCode())); newNavItem.setModifiable(modifiable); addItem(newNavItem, parentId); return newNavItem; } private void addItem(NavItem item, String parentId) { // Ensure the parent exists (if defined) NavItem parent = getItemById(parentId); if (parentId != null && parent == null) { throw new RuntimeException("Parent '" + parentId + "' not found"); } // Ensure the parent is a group if (parent != null && !(parent instanceof NavGroup)) { throw new RuntimeException("Parent '" + parentId + "' is not a group"); } // Register the item if (parent == null) { item.setParent(null); root.getChildren().add(item); } else { ((NavGroup) parent).getChildren().add(item); item.setParent((NavGroup) parent); } } @Override public NavItem deleteItem(String id) { NavItem navItem = getItemById(id); if (navItem != null) { if (navItem.getParent() == null) { root.getChildren().remove(navItem); } else { navItem.getParent().getChildren().remove(navItem); navItem.setParent(null); } } return navItem; } @Override public NavItem setItemName(String id, String name) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setName(name); return navItem; } @Override public NavItem setItemDescription(String id, String description) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setDescription(description); return navItem; } @Override public NavItem setItemModifiable(String id, boolean modifiable) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setModifiable(modifiable); return navItem; } @Override public NavItem setItemContext(String id, String context) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setContext(context); return navItem; } @Override public NavItem moveItem(String id, String newParentId) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } // Ensure the new target parent exists NavItem newParent = getItemById(newParentId); if (newParent == null && newParentId != null) { throw new RuntimeException("Parent not found: " + newParentId); } // Ensure the parent is a group if (newParent != null && !(newParent instanceof NavGroup)) { throw new RuntimeException("Parent '" + newParentId + "' is not a group"); } // Avoid loops if (newParentId != null && newParentId.equals(id)) { throw new RuntimeException("The parent can't be the item itself: " + newParentId); } // Do not move if nothing changes String parentId = navItem.getParent() != null ? navItem.getParent().getId(): null; if ((parentId == null && newParentId == null) || (parentId != null && newParentId != null && parentId.equals(newParentId))) { return navItem; } // Do move if (navItem.getParent() != null) { navItem.getParent().getChildren().remove(navItem); } navItem.setParent(null); if (newParent != null) { ((NavGroup) newParent).getChildren().add(navItem); navItem.setParent((NavGroup) newParent); } return navItem; } @Override public void moveItemFirst(String id) { changePosition(id, true, null); } @Override public void moveItemLast(String id) { changePosition(id, false, null); } @Override public void moveItemUp(String id) { changePosition(id, true, 1); } @Override public void moveItemDown(String id) { changePosition(id, false, 1); } public void changePosition(String id, boolean up, Integer npositions) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } NavGroup parent = navItem.getParent(); List itemList = parent != null ? parent.getChildren() : getRootItems(); int idx = itemList.indexOf(navItem); int newPos = npositions == null ? (up ? 0 : itemList.size()-1) : (up ? idx-npositions: idx+npositions); if ((up && newPos < 0) || (!up && newPos > itemList.size()-1)) { throw new RuntimeException("Item '" + id + "' position out of range (old=" + idx + ", new=" + newPos + ")"); } itemList.remove(idx); itemList.add(newPos, navItem); } @Override public void accept(NavItemVisitor visitor) { for (NavItem item : root.getChildren()) { item.accept(visitor); } } @Override public NavTree cloneTree() { NavGroup rootClone = (NavGroup) this.root.cloneItem(); rootClone.getChildren().forEach(e -> e.setParent(null)); return new NavTreeImpl(rootClone); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/json/NavTreeJSONMarshaller.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.json; import java.util.List; import org.dashbuilder.json.Json; import org.dashbuilder.json.JsonArray; import org.dashbuilder.json.JsonException; import org.dashbuilder.json.JsonObject; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; public class NavTreeJSONMarshaller { private static final String NAV_ITEM_ID = "id"; private static final String NAV_ITEM_TYPE = "type"; private static final String NAV_ITEM_NAME = "name"; private static final String NAV_ITEM_DESC = "description"; private static final String NAV_ITEM_MODIF = "modifiable"; private static final String NAV_ITEM_CTX = "context"; private static final String NAV_TREE_ROOT_ITEMS = "root_items"; private static final String NAV_GROUP_CHILDREN = "children"; private static NavTreeJSONMarshaller SINGLETON = new NavTreeJSONMarshaller(); public static NavTreeJSONMarshaller get() { return SINGLETON; } // To Json public JsonObject toJson(NavTree navTree) throws JsonException { JsonObject json = Json.createObject(); if (navTree != null) { json.put(NAV_TREE_ROOT_ITEMS, toJson(navTree.getRootItems())); } return json; } public JsonObject toJson(NavItem navItem) throws JsonException { JsonObject json = Json.createObject(); if (navItem != null) { json.put(NAV_ITEM_ID, navItem.getId()); json.put(NAV_ITEM_TYPE, navItem.getType().toString()); if (navItem.getType() != NavItem.Type.DIVIDER) { json.put(NAV_ITEM_NAME, navItem.getName()); json.put(NAV_ITEM_DESC, navItem.getDescription()); json.put(NAV_ITEM_MODIF, navItem.isModifiable()); json.put(NAV_ITEM_CTX, navItem.getContext()); if (navItem.getType() == NavItem.Type.GROUP) { json.put(NAV_GROUP_CHILDREN, toJson(((NavGroup) navItem).getChildren())); } } } return json; } public JsonArray toJson(List navItemList) throws JsonException { JsonArray json = Json.createArray(); if (navItemList != null) { for (int i=0; i targetList, NavGroup parent) throws JsonException { if (json != null) { for (int i = 0; i < json.length(); i++) { NavItem navItem = parseNavItem(json.getObject(i)); if (navItem != null) { navItem.setParent(parent); targetList.add(navItem); } } } } private NavItem parseNavItem(JsonObject json) throws JsonException { if (json == null) { return null; } NavItem navItem = null; String type = json.getString(NAV_ITEM_TYPE); if (type == null) { throw new RuntimeException("Nav item type not specified"); } if (NavItem.Type.DIVIDER.toString().equals(type)) { navItem = NavFactory.get().createDivider(); } else if (NavItem.Type.GROUP.toString().equals(type)) { navItem = NavFactory.get().createNavGroup(); } else { navItem = NavFactory.get().createNavItem(); } String id = json.getString(NAV_ITEM_ID); String name = json.getString(NAV_ITEM_NAME); String desc = json.getString(NAV_ITEM_DESC); String modif = json.getString(NAV_ITEM_MODIF); String ctx = json.getString(NAV_ITEM_CTX); navItem.setId(id); navItem.setName(name); navItem.setDescription(desc); navItem.setModifiable(modif != null ? Boolean.parseBoolean(modif) : true); navItem.setContext(ctx); if (NavItem.Type.GROUP.toString().equals(type)) { JsonArray childrenArray = json.getArray(NAV_GROUP_CHILDREN); NavGroup navGroup = (NavGroup) navItem; parseNavItemArray(childrenArray, navGroup.getChildren(), navGroup); } return navItem; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/layout/LayoutNavigationRef.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.layout; import java.util.Objects; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class LayoutNavigationRef { LayoutNavigationRefType type; String name; public LayoutNavigationRef() { } public LayoutNavigationRef(LayoutNavigationRefType type, String name) { this.type = type; this.name = name; } public LayoutNavigationRefType getType() { return type; } public String getName() { return name; } @Override public String toString() { return "LayoutNavigationRef{" + "type=" + type + ", name='" + name + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } LayoutNavigationRef that = (LayoutNavigationRef) o; return type == that.type && Objects.equals(name, that.name); } @Override public int hashCode() { return Objects.hash(type, name); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/layout/LayoutNavigationRefType.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.layout; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public enum LayoutNavigationRefType { PERSPECTIVE, NAV_COMPONENT, NAV_GROUP_CONTEXT, NAV_GROUP_DEFINED, DEFAULT_ITEM_DEFINED, DEFAULT_ITEM_FOUND, } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/layout/LayoutRecursionIssue.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.layout; import java.util.ArrayList; import java.util.List; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.ext.layout.editor.api.editor.LayoutTemplate; /** * Class containing the list of navigation references involved in an {@link LayoutTemplate} infinite recursion issue. */ @Portable public class LayoutRecursionIssue { List refList = new ArrayList<>(); public LayoutRecursionIssue() { } public boolean contains(LayoutNavigationRef other) { if (other != null) { for (LayoutNavigationRef ref : refList) { if (ref.getType() != null && ref.getType().equals(other.getType()) && ref.getName() != null && ref.getName().equals(other.getName())) { return true; } } } return false; } public void push(LayoutNavigationRef ref) { refList.add(ref); } public LayoutNavigationRef pop() { return refList.remove(refList.size()-1); } public boolean isEmpty() { return refList.isEmpty(); } public List getRefList() { return refList; } public LayoutNavigationRef getLastDefaultItemRef() { for (LayoutNavigationRef ref : refList) { if (ref.getType().equals(LayoutNavigationRefType.DEFAULT_ITEM_FOUND) || ref.getType().equals(LayoutNavigationRefType.DEFAULT_ITEM_DEFINED)) { return ref; } } return null; } public String printReport(NavTree navTree, LayoutRecursionIssueI18n i18n) { String msg = ""; LayoutNavigationRef previousRef = null; for (int i=0; i listPlugins(); Plugin getPerspectivePlugin(String perspectiveName); LayoutTemplate getLayoutTemplate(String perspectiveName); LayoutTemplate getLayoutTemplate(Plugin perspectivePlugin); LayoutTemplateInfo getLayoutTemplateInfo(String perspectiveName); LayoutTemplateInfo getLayoutTemplateInfo(Plugin perspectivePlugin, LayoutTemplateContext layoutCtx); LayoutTemplateInfo getLayoutTemplateInfo(LayoutTemplate layoutTemplate); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/workbench/NavSecurityController.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.workbench; import java.util.Iterator; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.security.shared.api.identity.User; import org.uberfire.security.ResourceRef; import org.uberfire.security.authz.AuthorizationManager; import org.uberfire.workbench.model.ActivityResourceType; /** * A security interface for controlling access {@link NavTree} and {@link NavItem} instances. */ @ApplicationScoped public class NavSecurityController { private AuthorizationManager authorizationManager; private User user; @Inject public NavSecurityController(AuthorizationManager authorizationManager, User user) { this.authorizationManager = authorizationManager; this.user = user; } public NavTree secure(NavTree navTree, boolean removeEmptyGroups) { NavTree clone = navTree.cloneTree(); secure(clone.getRootItems(), removeEmptyGroups); return clone; } public void secure(List itemList, boolean removeEmptyGroups) { Iterator it = itemList.iterator(); while (it.hasNext()) { NavItem navItem = it.next(); if (!canRead(navItem)) { it.remove(); } else if (navItem instanceof NavGroup) { List children = ((NavGroup) navItem).getChildren(); if (removeEmptyGroups) { removeEmptyGroups(children); } secure(children, removeEmptyGroups); } } if (removeEmptyGroups) { removeEmptyGroups(itemList); } } private void removeEmptyGroups(List itemList) { Iterator it = itemList.iterator(); while (it.hasNext()) { NavItem navItem = it.next(); if (navItem instanceof NavGroup) { if (isEmpty((NavGroup) navItem)) { it.remove(); } } } } private boolean isEmpty(NavGroup navGroup) { for (NavItem navItem : navGroup.getChildren()) { // Group found => non empty if subgroup non empty as well. if (navItem instanceof NavGroup) { if (!isEmpty((NavGroup) navItem)) { return false; } } // Item found => non empty else if (!(navItem instanceof NavDivider)) { return false; } } return true; } public boolean canRead(String navItemCtx) { NavWorkbenchCtx ctx = NavWorkbenchCtx.get(navItemCtx); // Check permissions for (String p : ctx.getPermissions()) { if (!authorizationManager.authorize(p, user)) { return false; } } // Check resource access String resourceId = ctx.getResourceId(); ActivityResourceType resourceType = ctx.getResourceType(); if (resourceId != null && resourceType != null) { ResourceRef resourceRef = new ResourceRef(resourceId, resourceType); if (!authorizationManager.authorize(resourceRef, user)) { return false; } } // The item is available return true; } public boolean canRead(NavItem navItem) { if (navItem == null) { return false; } return canRead(navItem.getContext()); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/java/org/dashbuilder/navigation/workbench/NavWorkbenchCtx.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation.workbench; import java.util.ArrayList; import java.util.List; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemContext; import org.dashbuilder.navigation.impl.NavItemContextImpl; import org.uberfire.workbench.model.ActivityResourceType; /** * A {@link NavItemContext} which contains workbench related context like for instance: *
      *
    • A list of permissions the nav item is tied to
    • *
    • An identifier of a resource this item is referring to
    • *
    */ public class NavWorkbenchCtx extends NavItemContextImpl { public static final String PERMISSIONS = "permissions"; public static final String RESOURCE_ID = "resourceId"; public static final String RESOURCE_TYPE = "resourceType"; public static final String NAV_GROUP_ID = "navGroupId"; public static NavWorkbenchCtx get(NavItem navItem) { return navItem != null ? new NavWorkbenchCtx(navItem.getContext()): new NavWorkbenchCtx(); } public static NavWorkbenchCtx get(String navItemCtx) { return new NavWorkbenchCtx(navItemCtx); } public static NavWorkbenchCtx perspective(String perspectiveId) { NavWorkbenchCtx ctx = new NavWorkbenchCtx(); ctx.setResourceId(perspectiveId); ctx.setResourceType(ActivityResourceType.PERSPECTIVE); return ctx; } public static NavWorkbenchCtx permission(String... permission) { NavWorkbenchCtx ctx = new NavWorkbenchCtx(); for (String p : permission) { ctx.addPermission(p); } return ctx; } public NavWorkbenchCtx() { super(); } public NavWorkbenchCtx(String ctx) { super(ctx); } public String getResourceId() { return super.getProperty(RESOURCE_ID); } public NavWorkbenchCtx setResourceId(String resourceId) { if (resourceId == null) { super.removeProperty(RESOURCE_ID); } else { super.setProperty(RESOURCE_ID, resourceId); } return this; } public ActivityResourceType getResourceType() { String type = super.getProperty(RESOURCE_TYPE); return type != null ? ActivityResourceType.valueOf(type.toUpperCase()) : null; } public NavWorkbenchCtx setResourceType(ActivityResourceType resourceType) { super.setProperty(RESOURCE_TYPE, resourceType.getName().toUpperCase()); return this; } public String getNavGroupId() { return super.getProperty(NAV_GROUP_ID); } public NavWorkbenchCtx setNavGroupId(String navGroupId) { if (navGroupId == null) { super.removeProperty(NAV_GROUP_ID); } else { super.setProperty(NAV_GROUP_ID, navGroupId); } return this; } public NavWorkbenchCtx clearPermissions() { super.removeProperty(PERMISSIONS); return this; } public List getPermissions() { List permissionList = new ArrayList<>(); String str = super.getProperty(PERMISSIONS); if (str != null) { for (String p : str.split(",")) { permissionList.add(p.trim()); } } return permissionList; } public NavWorkbenchCtx addPermission(String permission) { String str = super.getProperty(PERMISSIONS); str = str == null ? permission : str + "," + permission; super.setProperty(PERMISSIONS, str); return this; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/main/resources/org/dashbuilder/NavigationAPI.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/test/java/org/dashbuilder/navigation/NavItemContextInclusionTest.java ================================================ /* * Copyright 2017 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.Arrays; import java.util.Collection; import static org.junit.Assert.assertEquals; import static org.junit.runners.Parameterized.Parameter; import static org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class NavItemContextInclusionTest { @Parameters public static Collection data() { return Arrays.asList(new Object[][]{ {"", "", true}, {"a=1", "a=1", true}, //identical ctxts {"a=1;b=2", "a=1;b=2", true}, {"a=1;b=2", "b=2;a=1", true}, // order should not matter {"a=1;b=2", "a=1", true}, // extra property {"a=1;b=2;c=3", "b=2", true}, // extra property in different place {"a=1;b=2", "c=3", false}, // property not included {"a=1", "a=2", false}, // different value of property {"a=1;b=2", "a=1;c=2", false}, // same amount of props, but different names {"A=1", "a=1", false}, // property names are case sensitive }); } @Parameter(0) public String ctx1; @Parameter(1) public String ctx2; @Parameter(2) public boolean includesPropertiesOf; @Test public void testMatch() { NavItemContext c1 = NavItemContext.get(ctx1), c2 = NavItemContext.get(ctx2); String msg = String.format("NavItemContext %s should%s include properties of %s", ctx1, (includesPropertiesOf ? "" : " not"), ctx2); assertEquals(msg, includesPropertiesOf, c1.includesPropertiesOf(c2)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/test/java/org/dashbuilder/navigation/NavItemContextTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.junit.Test; import org.uberfire.workbench.model.ActivityResourceType; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class NavItemContextTest { @Test public void testEmpty() { NavItemContext ctx = NavItemContext.get(""); assertEquals(ctx.getPropertyIds().size(), 0); ctx = NavItemContext.create(); assertEquals(ctx.getPropertyIds().size(), 0); } @Test public void testParse() { NavItemContext ctx = NavItemContext.get("a=A;b=B;"); assertEquals(ctx.getPropertyIds().size(), 2); assertEquals(ctx.getProperty("a"), "A"); assertEquals(ctx.getProperty("b"), "B"); } @Test public void testFormat() { NavItemContext ctx = NavItemContext.create(); ctx.setProperty("a", "A"); ctx.setProperty("b", "B"); assertEquals(ctx.getPropertyIds().size(), 2); assertEquals(ctx.getProperty("a"), "A"); assertEquals(ctx.getProperty("b"), "B"); assertEquals(ctx.toString(), "a=A;b=B;"); } @Test public void testPerspective() { NavWorkbenchCtx ctx = NavWorkbenchCtx.perspective("A"); assertEquals(ctx.getPropertyIds().size(), 2); assertEquals(ctx.getResourceId(), "A"); assertEquals(ctx.getResourceType(), ActivityResourceType.PERSPECTIVE); assertEquals(ctx.getProperty(NavWorkbenchCtx.RESOURCE_ID), "A"); assertEquals(ctx.getProperty(NavWorkbenchCtx.RESOURCE_TYPE), "PERSPECTIVE"); assertEquals(ctx.toString(), "resourceId=A;resourceType=PERSPECTIVE;"); } @Test public void testPermissions() { NavWorkbenchCtx ctx = NavWorkbenchCtx.permission("p1", "p2", "p3"); assertThat(ctx.getPermissions()) .hasSize(3) .contains("p1", "p2", "p3"); ctx.clearPermissions(); assertThat(ctx.getPermissions()) .isEmpty(); } @Test public void testRemoveProperty() { NavWorkbenchCtx ctx = NavWorkbenchCtx.get("a=1;b=2;c=3"); ctx.removeProperty("b"); NavWorkbenchCtx expectedCtx = NavWorkbenchCtx.get("a=1;c=3"); assertTrue(ctx.includesPropertiesOf(expectedCtx)); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/test/java/org/dashbuilder/navigation/NavSecurityTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import java.util.ArrayList; import java.util.List; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.workbench.NavSecurityController; import org.dashbuilder.navigation.workbench.NavWorkbenchCtx; import org.jboss.errai.security.shared.api.identity.User; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.security.authz.AuthorizationManager; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class NavSecurityTest { public static final String ITEM_HOME_ID = "home"; public static final String ITEM_ADMIN_ID = "admin"; public static final String ITEM_SECURITY_ID = "security"; public static final String ITEM_DATASETS_ID = "datasets"; @Mock AuthorizationManager authorizationManager; @Mock User user; NavTree tree; NavSecurityController controller; @Before public void setUp() { tree = new NavTreeBuilder() .item(ITEM_HOME_ID, "Home", null, false, NavWorkbenchCtx.permission(ITEM_HOME_ID)) .divider() .group(ITEM_ADMIN_ID, "Administration", null, false) .item(ITEM_SECURITY_ID, "Security", null, false, NavWorkbenchCtx.permission(ITEM_SECURITY_ID)) .item(ITEM_DATASETS_ID, "Data sets", null, false, NavWorkbenchCtx.permission(ITEM_DATASETS_ID)) .build(); controller = new NavSecurityController(authorizationManager, user); } @Test public void testTreeStructure() { when(authorizationManager.authorize(ITEM_HOME_ID, user)).thenReturn(true); when(authorizationManager.authorize(ITEM_SECURITY_ID, user)).thenReturn(false); when(authorizationManager.authorize(ITEM_DATASETS_ID, user)).thenReturn(true); NavTree securedTree = controller.secure(tree, true); List rootNavItems = securedTree.getRootItems(); assertEquals(rootNavItems.size(), 3); NavItem admin = securedTree.getItemById(ITEM_ADMIN_ID); assertTrue(admin instanceof NavGroup); assertEquals(((NavGroup) admin).getChildren().size(), 1); } @Test public void testHideEmptyGroups() { when(authorizationManager.authorize(ITEM_HOME_ID, user)).thenReturn(true); when(authorizationManager.authorize(ITEM_SECURITY_ID, user)).thenReturn(false); when(authorizationManager.authorize(ITEM_DATASETS_ID, user)).thenReturn(false); NavTree securedTree = controller.secure(tree, true); NavItem admin = securedTree.getItemById(ITEM_ADMIN_ID); assertEquals(securedTree.getRootItems().size(), 2); assertNull(admin); List navItems = new ArrayList<>(tree.getRootItems()); controller.secure(navItems, true); assertEquals(navItems.size(), 2); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/test/java/org/dashbuilder/navigation/NavTreeJsonTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import org.dashbuilder.json.JsonObject; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.dashbuilder.navigation.json.NavTreeJSONMarshaller; import org.junit.Test; import static org.junit.Assert.*; public class NavTreeJsonTest { public static final NavTree NAV_TREE = new NavTreeBuilder() .item("1", "name1", "desc1", true, "ctx1") .item("2", "name2", "desc2", false, "ctx2") .divider() .group("3", "name3", "desc3", true) .item("4", "name4", "desc4", true, "ctx4") .build(); @Test public void testNavTreeMarshalling() { NavTreeJSONMarshaller jsonMarshaller = NavTreeJSONMarshaller.get(); JsonObject _jsonObj = jsonMarshaller.toJson(NAV_TREE); assertNotNull(_jsonObj.toString()); NavTree navTree = jsonMarshaller.fromJson(_jsonObj); assertEquals(navTree.getRootItems().size(), 4); NavItem navItem = navTree.getItemById("1"); assertNotNull(navItem); assertEquals(navItem.getType(), NavItem.Type.ITEM); assertEquals(navItem.getName(), "name1"); assertEquals(navItem.getDescription(), "desc1"); assertEquals(navItem.isModifiable(), true); assertEquals(navItem.getContext(), "ctx1"); navItem = navTree.getItemById("2"); assertNotNull(navItem); assertEquals(navItem.getType(), NavItem.Type.ITEM); assertEquals(navItem.getName(), "name2"); assertEquals(navItem.getDescription(), "desc2"); assertEquals(navItem.isModifiable(), false); assertEquals(navItem.getContext(), "ctx2"); navItem = navTree.getItemById("3"); assertNotNull(navItem); assertEquals(navItem.getType(), NavItem.Type.GROUP); assertEquals(navItem.getName(), "name3"); assertEquals(navItem.getDescription(), "desc3"); assertEquals(navItem.isModifiable(), true); navItem = navTree.getItemById("4"); assertNotNull(navItem); assertEquals(navItem.getType(), NavItem.Type.ITEM); assertEquals(navItem.getName(), "name4"); assertEquals(navItem.getDescription(), "desc4"); assertEquals(navItem.isModifiable(), true); assertEquals(navItem.getContext(), "ctx4"); assertEquals(navItem.getParent(), navTree.getItemById("3")); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-navigation-api/src/test/java/org/dashbuilder/navigation/NavTreeTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.navigation; import org.assertj.core.api.Assertions; import org.dashbuilder.navigation.impl.NavTreeBuilder; import org.junit.Before; import org.junit.Test; import java.util.List; import static org.junit.Assert.*; public class NavTreeTest { public static final String ITEM_HOME_ID = "home"; public static final String ITEM_ADMIN_ID = "admin"; public static final String ITEM_SECURITY_ID = "security"; public static final String ITEM_DATASETS_ID = "datasets"; public static final String NONEXISTENT_ITEM_ID = "item with this id does not exist"; NavTree tree; @Before public void setUp() { tree = new NavTreeBuilder() .item(ITEM_HOME_ID, "Home", null, false) .divider() .group(ITEM_ADMIN_ID, "Administration", null, false) .item(ITEM_SECURITY_ID, "Security", null, false) .item(ITEM_DATASETS_ID, "Data sets", null, false) .build(); } @Test public void testTreeStructure() { List rootNavItems = tree.getRootItems(); assertEquals(rootNavItems.size(), 3); NavItem home = tree.getItemById(ITEM_HOME_ID); assertTrue(home instanceof NavItem); assertEquals(home.getId(), ITEM_HOME_ID); assertEquals(home.getName(), "Home"); assertEquals(home.isModifiable(), false); assertNull(home.getParent()); NavItem admin = tree.getItemById(ITEM_ADMIN_ID); assertTrue(admin instanceof NavGroup); assertEquals(((NavGroup) admin).getChildren().size(), 2); NavItem security = tree.getItemById(ITEM_SECURITY_ID); assertTrue(security instanceof NavItem); assertEquals(security.getParent(), admin); } @Test public void testDeleteItem() { tree.deleteItem(ITEM_HOME_ID); List rootNavItems = tree.getRootItems(); assertEquals(rootNavItems.size(), 2); tree.deleteItem(ITEM_DATASETS_ID); NavItem admin = tree.getItemById(ITEM_ADMIN_ID); assertEquals(((NavGroup) admin).getChildren().size(), 1); } @Test(expected = RuntimeException.class) public void testParentNotFound() { tree.moveItem("none", "parent"); } @Test(expected = RuntimeException.class) public void testAvoidLoops() { tree.moveItem(ITEM_HOME_ID, "home"); } @Test public void testItemContext() { tree.setItemContext(ITEM_HOME_ID, "p1"); NavItem home = tree.getItemById(ITEM_HOME_ID); assertTrue(home instanceof NavItem); assertEquals(home.getContext(), "p1"); } @Test public void testSearchItems() { NavItemContext ctx1 = NavItemContext.create().setProperty("p1", "v1").setProperty("p2", "v2"); NavItemContext ctx2 = NavItemContext.create().setProperty("p1", "v1").setProperty("p3", "v3"); NavItemContext ctx3 = NavItemContext.create().setProperty("p1", "v1").setProperty("p2", "v2"); tree.setItemContext(ITEM_HOME_ID, ctx1.toString()); tree.setItemContext(ITEM_DATASETS_ID, ctx2.toString()); List navItems = tree.searchItems(ctx3); assertEquals(navItems.size(), 1); assertEquals(navItems.get(0).getId(), ITEM_HOME_ID); } @Test(expected = RuntimeException.class) public void testMoveUpNotAllowed() { tree.moveItemUp(ITEM_SECURITY_ID); tree.moveItemDown(ITEM_DATASETS_ID); } @Test(expected = RuntimeException.class) public void testMoveDownNotAllowed() { tree.moveItemDown(ITEM_DATASETS_ID); } @Test public void testMoveUpAndDown() { NavGroup admin = (NavGroup) tree.getItemById(ITEM_ADMIN_ID); List navItems = admin.getChildren(); assertEquals(navItems.get(0).getId(), ITEM_SECURITY_ID); assertEquals(navItems.get(1).getId(), ITEM_DATASETS_ID); tree.moveItemUp(ITEM_DATASETS_ID); assertEquals(navItems.get(0).getId(), ITEM_DATASETS_ID); assertEquals(navItems.get(1).getId(), ITEM_SECURITY_ID); tree.moveItemDown(ITEM_DATASETS_ID); assertEquals(navItems.get(0).getId(), ITEM_SECURITY_ID); assertEquals(navItems.get(1).getId(), ITEM_DATASETS_ID); tree.moveItemFirst(ITEM_DATASETS_ID); assertEquals(navItems.get(0).getId(), ITEM_DATASETS_ID); assertEquals(navItems.get(1).getId(), ITEM_SECURITY_ID); tree.moveItemLast(ITEM_DATASETS_ID); assertEquals(navItems.get(0).getId(), ITEM_SECURITY_ID); assertEquals(navItems.get(1).getId(), ITEM_DATASETS_ID); } @Test public void testSubtreeCreation() { NavTree subtree = tree.getItemAsTree(ITEM_ADMIN_ID); assertEquals(subtree.getRootItems().size(), 2); subtree.getRootItems().forEach(i -> assertNull(i.getParent())); } @Test public void testCloneTree() { NavTree clone = tree.cloneTree(); clone.getRootItems().forEach(i -> assertNull(i.getParent())); } @Test public void setItemName_worksWhenItemPresent() { NavItem modifiedItem = tree.setItemName(ITEM_HOME_ID, "NEW NAME!"); assertEquals("NEW NAME!", modifiedItem.getName()); assertEquals("NEW NAME!", tree.getItemById(ITEM_HOME_ID).getName()); } @Test public void setItemModifiable_worksWhenItemPresent() { assertFalse(tree.getItemById(ITEM_HOME_ID).isModifiable()); NavItem modifiedItem = tree.setItemModifiable(ITEM_HOME_ID, true); assertTrue(modifiedItem.isModifiable()); assertTrue(tree.getItemById(ITEM_HOME_ID).isModifiable()); } @Test public void setItemDescription_worksWhenItemPresent() { NavItem modifiedItem = tree.setItemDescription(ITEM_HOME_ID, "new description"); assertEquals("new description", modifiedItem.getDescription()); assertEquals("new description", tree.getItemById(ITEM_HOME_ID).getDescription()); } @Test(expected = RuntimeException.class) public void setItemName_throwsExceptionWhenItemNotPresent() { tree.setItemName(NONEXISTENT_ITEM_ID, "anything"); } @Test(expected = RuntimeException.class) public void setItemModifiable_throwsExceptionWhenItemNotPresent() { tree.setItemModifiable(NONEXISTENT_ITEM_ID, true); } @Test(expected = RuntimeException.class) public void setItemDescription_throwsExceptionWhenItemNotPresent() { tree.setItemDescription(NONEXISTENT_ITEM_ID, "doesn't matter"); } @Test public void addGroupTest() { final String id = "id", name = "name", description = "desc", parentId = ITEM_ADMIN_ID; final boolean modifiable = false; tree.addGroup(id, name, description, parentId, modifiable); NavItem newGroup = tree.getItemById(id); assertEquals(id, newGroup.getId()); assertEquals(name, newGroup.getName()); assertEquals(parentId, newGroup.getParent().getId()); assertEquals(description, newGroup.getDescription()); assertFalse(newGroup.isModifiable()); } @Test public void addGroupThrowsException_whenParentIsNotGroup() { String idOfParentWhichIsNotGroup = ITEM_SECURITY_ID; try { tree.addGroup(null, null, null, idOfParentWhichIsNotGroup, true); Assertions.fail("Exception should be thrown when using something else as parent than NavGroup"); } catch (RuntimeException e) { assertEquals("Parent '" + idOfParentWhichIsNotGroup + "' is not a group", e.getMessage()); } } @Test public void addItemTest() { final String id = "id", name = "name", description = "desc", parentId = ITEM_ADMIN_ID, context = "a=1"; final boolean modifiable = false; tree.addItem(id, name, description, parentId, modifiable, context); NavItem item = tree.getItemById(id); assertEquals(id, item.getId()); assertEquals(name, item.getName()); assertEquals(parentId, item.getParent().getId()); assertEquals(description, item.getDescription()); assertFalse(item.isModifiable()); assertEquals(context, item.getContext()); } @Test public void addItemShouldThrowException_whenParentDoesNotExist() { try { tree.addItem(null, null, null, NONEXISTENT_ITEM_ID, true, null); Assertions.fail("Exception should be thrown when parent with given ID does not exist"); } catch (RuntimeException e) { assertEquals("Parent '" + NONEXISTENT_ITEM_ID + "' not found", e.getMessage()); } } @Test public void moveItemTest() { final String newGroupId = "ngi"; tree.addGroup(newGroupId, "name", "desc", ITEM_ADMIN_ID, true); tree.moveItem(ITEM_SECURITY_ID, newGroupId); assertEquals(newGroupId, tree.getItemById(ITEM_SECURITY_ID).getParent().getId()); } @Test public void moveItemShouldThrowException_whenParentDoesNotExist() { try { tree.moveItem(ITEM_SECURITY_ID, NONEXISTENT_ITEM_ID); Assertions.fail("Exception should be thrown when parent with given ID does not exist"); } catch (RuntimeException e) { assertEquals("Parent not found: " + NONEXISTENT_ITEM_ID, e.getMessage()); } } @Test public void moveItemShouldThrowException_whenParentIdSameAsItemId() { final String sameId = ITEM_ADMIN_ID; try { tree.moveItem(sameId, sameId); Assertions.fail("Exception should be thrown when parentId same as item Id"); } catch (RuntimeException e) { assertEquals("The parent can't be the item itself: " + sameId, e.getMessage()); } } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-shared 7.75.0-SNAPSHOT dashbuilder-services-api jar Dashbuilder Services API Dashbuilder Services API shared between client and server. org.uberfire uberfire-api org.uberfire uberfire-commons-editor-api org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-navigation-api org.dashbuilder dashbuilder-displayer-api org.jboss.errai errai-bus ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/dataset/service/DataSetDefServices.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import java.util.List; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.bus.server.annotations.Remote; /** * Services for the handling of data set definitions */ @Remote public interface DataSetDefServices { /** * Get those public (shareable) data set definition (those with the "public" flag set to true) */ List getPublicDataSetDefs(); /** * Creates a brand new data set definition for the provider type specified * @param type The provider type * @return A data set definition instance */ DataSetDef createDataSetDef(DataSetProviderType type); /** * Register a data set definition. * @param definition The data set definition. * @param message, A message top store along the registration request. If null is ignored. * @return The registered data set definition UUID. If UUID not present on the definition from the argument definition, the UUID will be generated. */ String registerDataSetDef(DataSetDef definition, String message); /** * Removes a data set definition from the registry. * @param message, A message top store along the registration request. If null is ignored. * @param uuid The data set definition identifier. */ void removeDataSetDef(String uuid, String message); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/dataset/service/DataSetDefVfsServices.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import org.dashbuilder.dataset.backend.EditDataSetDef; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.bus.server.annotations.Remote; import org.uberfire.backend.vfs.Path; import org.uberfire.ext.editor.commons.service.support.SupportsCopy; import org.uberfire.ext.editor.commons.service.support.SupportsDelete; /** * Services for the handling the storage of data set definitions */ @Remote public interface DataSetDefVfsServices extends SupportsDelete, SupportsCopy { Path resolve(DataSetDef dataSetDef); DataSetDef get(Path path); EditDataSetDef load(Path path) throws Exception; Path save(DataSetDef dataSetDef, String commitMessage); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/dataset/service/DataSetExportServices.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.jboss.errai.bus.server.annotations.Remote; /** * Data set export (CSV & Excel) services */ @Remote public interface DataSetExportServices { /** * Export a dataset, specified by a DataSetLookup, to CSV format. * @param dataSetLookup The dataSetLookup that defines the dataset to be exported. * @return The VFS path to the export file generated */ org.uberfire.backend.vfs.Path exportDataSetCSV(DataSetLookup dataSetLookup); /** * Export a dataset, specified by a DataSetLookup, to Excel format. * @param dataSetLookup The dataSetLookup that defines the dataset to be exported. * @return The VFS path to the export file generated */ org.uberfire.backend.vfs.Path exportDataSetExcel(DataSetLookup dataSetLookup); /** * Export a dataset to CSV format. * @param dataSet The dataset to export. * @return The VFS path to the export file generated */ org.uberfire.backend.vfs.Path exportDataSetCSV(DataSet dataSet); /** * Export a dataset to Excel format. * @param dataSet The dataset to export. * @return The VFS path to the export file generated */ org.uberfire.backend.vfs.Path exportDataSetExcel(DataSet dataSet); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/dataset/service/DataSetLookupServices.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.bus.server.annotations.Remote; /** * Data set lookup services */ @Remote public interface DataSetLookupServices { /** * Apply a sequence of operations (filter, sort, group, ...) on a remote data set. * * @return A brand new data set with all the calculations applied. */ DataSet lookupDataSet(DataSetLookup lookup) throws Exception; /** * Load a data set and apply several operations (filter, sort, group, ...) on top of it for a given definition. * Index and cache are not used. * @return null, if the data set can be retrieved. */ DataSet lookupDataSet(DataSetDef def, DataSetLookup lookup) throws Exception; /** * Same as lookupDataSet but only retrieves the metadata of the resulting data set. * * @return A DataSetMetadata instance containing general information about the data set. */ DataSetMetadata lookupDataSetMetadata(String uuid) throws Exception; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/dataset/service/SQLProviderServices.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.dataset.service; import java.util.List; import org.dashbuilder.dataset.def.SQLDataSourceDef; import org.jboss.errai.bus.server.annotations.Remote; /** * Services around the SQL provider type. */ @Remote public interface SQLProviderServices { /** * Get the list of available data source references */ List getDataSourceDefs(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/external/model/ComponentParameter.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.model; import java.util.List; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ComponentParameter { private String name; private String type; private String category; private String defaultValue; private String label; private List comboValues; private boolean mandatory; public ComponentParameter() { // default constructor used internally } public ComponentParameter(@MapsTo("name") String name, @MapsTo("type") String type, @MapsTo("category") String category, @MapsTo("defaultValue") String defaultValue, @MapsTo("label") String label, @MapsTo("comboValues") List comboValues) { this.name = name; this.type = type; this.category = category; this.defaultValue = defaultValue; this.label = label; this.comboValues = comboValues; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } public String getDefaultValue() { return defaultValue; } public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public List getComboValues() { return comboValues; } public void setComboValues(List comboValues) { this.comboValues = comboValues; } public boolean isMandatory() { return mandatory; } public void setMandatory(boolean mandatory) { this.mandatory = mandatory; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/external/model/ExternalComponent.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.model; import java.util.List; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ExternalComponent { public static final String COMPONENT_ID_KEY = "componentId"; public static final String COMPONENT_PARTITION_KEY = "componentPartition"; private String id; private String name; private String icon; private String category; private boolean noData; private boolean provided; private List parameters; public ExternalComponent() { // do nothing } public ExternalComponent(@MapsTo("id") String id, @MapsTo("name") String name, @MapsTo("icon") String icon, @MapsTo("noData") boolean noData, @MapsTo("parameters") List parameters) { this.id = id; this.name = name; this.icon = icon; this.noData = noData; this.parameters = parameters; } public void setId(String id) { this.id = id; } public String getId() { return id; } public String getName() { return name; } public String getIcon() { return icon; } public String getCategory() { return category; } public boolean isNoData() { return noData; } public List getParameters() { return parameters; } public boolean isProvided() { return provided; } public void setProvided(boolean provided) { this.provided = provided; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/external/service/BackendComponentFunctionService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.service; import java.util.List; import java.util.Map; import org.jboss.errai.bus.server.annotations.Remote; /** * List and calls functions available on backend. * */ @Remote public interface BackendComponentFunctionService { List listFunctions(); Object callFunction(String name, Map params); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/external/service/ComponentAssetProvider.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.service; import java.io.InputStream; public interface ComponentAssetProvider { InputStream openAsset(String componentAssetPath); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/external/service/ComponentLoader.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.service; import java.util.List; import org.dashbuilder.external.model.ExternalComponent; public interface ComponentLoader { public static final String DESCRIPTOR_FILE = "manifest.json"; /** * Load the list of components externally created by users . * * @return * The list of external components. */ List loadExternal(); /** * Load external components that are provided (built-in) by Dashbuilder. * @return * The list of provided external components */ List loadProvided(); /** * The filesystem directory for external components. * * @return */ String getExternalComponentsDir(); /** * The internal path for provided components. * * @return */ String getProvidedComponentsPath(); boolean isExternalComponentsEnabled(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/external/service/ComponentService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.external.service; import java.util.List; import java.util.Optional; import org.dashbuilder.external.model.ExternalComponent; import org.jboss.errai.bus.server.annotations.Remote; @Remote public interface ComponentService { List listProvidedComponents(); List listExternalComponents(); List listAllComponents(); Optional byId(String componentId); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/perspectives/PerspectiveIds.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.perspectives; public interface PerspectiveIds { String HOME = "HomePerspective"; String DATA_SETS = "DataSetAuthoringPerspective"; String GALLERY = "DisplayerGalleryPerspective"; String CONTENT_MANAGER = "ContentManagerPerspective"; String DATA_TRANSFER = "DataTransferPerspective"; String APPS = "AppsPerspective"; String PLUGINS = "PlugInAuthoringPerspective"; String SALES_DASHBOARD = "SalesDashboardPerspective"; String SALES_REPORTS = "SalesReportsPerspective"; String SECURITY = "SecurityManagementPerspective"; } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/renderer/service/RendererSettingsService.java ================================================ package org.dashbuilder.renderer.service; import org.dashbuilder.renderer.RendererSettings; import org.jboss.errai.bus.server.annotations.Remote; /** * Provide access to Renderer settings. * */ @Remote public interface RendererSettingsService { final static String DEFAULT_RENDERER_PROPERTY = "org.dashbuilder.renderer.default"; final static String OFFLINE_RENDERER_PROPERTY = "org.dashbuilder.renderer.offline"; public RendererSettings getSettings(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/transfer/DataTransferExportModel.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.Collections; import java.util.List; import org.dashbuilder.dataset.def.DataSetDef; /** * Contains the dashboard elements that should be exported * */ public class DataTransferExportModel { private static final DataTransferExportModel EXPORT_ALL = new DataTransferExportModel(Collections.emptyList(), Collections.emptyList(), true, true); private List datasetDefinitions; private List pages; private boolean exportNavigation; private boolean exportAll; public DataTransferExportModel() {} public DataTransferExportModel(List datasetDefinitions, List pages, boolean exportNavigation) { this(datasetDefinitions, pages, exportNavigation, false); } protected DataTransferExportModel(List datasetDefinitions, List pages, boolean exportNavigation, boolean exportAll) { this.datasetDefinitions = datasetDefinitions; this.pages = pages; this.exportNavigation = exportNavigation; this.exportAll = exportAll; } public static DataTransferExportModel exportAll() { return EXPORT_ALL; } public List getDatasetDefinitions() { return datasetDefinitions; } public void setDatasetDefinitions(List datasetDefinitions) { this.datasetDefinitions = datasetDefinitions; } public List getPages() { return pages; } public void setPages(List pages) { this.pages = pages; } public boolean isExportNavigation() { return exportNavigation; } public void setExportNavigation(boolean exportNavigation) { this.exportNavigation = exportNavigation; } public boolean isExportAll() { return exportAll; } public void setExportAll(boolean exportAll) { this.exportAll = exportAll; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/transfer/DataTransferServices.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.List; import org.jboss.errai.bus.server.annotations.Remote; @Remote public interface DataTransferServices { public static final String FILE_PATH = "dashbuilder-data-transfer"; public static final String EXPORT_FILE_NAME = "export.zip"; public static final String IMPORT_FILE_NAME = "import.zip"; public static final String COMPONENTS_EXPORT_PATH = "dashbuilder/components/"; public static final String EXPORT_LOCATION_PROP = "dashbuilder.export.dir"; public static final String SHARE_OPEN_MODEL_PROP = "dashbuilder.shareOpenModel"; public static final String DB_STANDALONE_LOCATION_PROP = "dashbuilder.runtime.location"; public String doExport(DataTransferExportModel exportsModel) throws java.io.IOException; public List doImport() throws Exception; public String generateExportUrl(DataTransferExportModel exportsModel) throws Exception; public ExportInfo exportInfo(); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/transfer/ExportInfo.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.List; import org.dashbuilder.dataset.def.DataSetDef; public class ExportInfo { private boolean externalServerAvailable; private List datasetsDefinitions; private List pages; public ExportInfo() {} public ExportInfo(List datasetsDefinitions, List pages, boolean externalServerAvailable) { this.datasetsDefinitions = datasetsDefinitions; this.pages = pages; this.externalServerAvailable = externalServerAvailable; } public List getDatasetsDefinitions() { return datasetsDefinitions; } public List getPages() { return pages; } public boolean isExternalServerAvailable() { return externalServerAvailable; } @Override public String toString() { return "ExportModel [externalServerAvailable=" + externalServerAvailable + ", " + "datasetsDefinitions=" + datasetsDefinitions + "," + " pages=" + pages + "]"; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/java/org/dashbuilder/transfer/ExportModelValidationService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.transfer; import java.util.List; import java.util.Map; import org.jboss.errai.bus.server.annotations.Remote; /** * Perform validations on an ExportModel * */ @Remote public interface ExportModelValidationService { /** * Check if there is datasets not exported for the given export model * * @param exportModel * The export model to be validated * @return * A map of pages with missing dependencies and the list of dependencies for each page. */ Map> checkMissingDatasets(DataTransferExportModel exportModel); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-services-api/src/main/resources/org/dashbuilder/ServicesAPI.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/README.md ================================================ Dashbuilder validations module ============================== Introduction -------------- Dashbuilder integrates with GWT & JSR303 Bean Validation framework in order to perform both client and server side bean validations. This module provides both client and server side validation factories, message resolvers and other related stuff. Notes ----- * As by transitive resolution mechanism the dependency for org.hibernate:hibernate-validator:jar is set to version 4.3.X, and this version is incompatible with GWT validation framework, this module is using [Dashbuilder Hibernate Validator](../dashbuilder-hibernate-validator/README.md). * As GWT validation framework does not support JSR303 custom Validation Providers (see com.google.gwt.validation.client.impl.Validation#byProvider(Class providerType), this module is built on top of all dashbuilder shared modules and provides the default provider validation factory class and the default validation messages resolver. ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/pom.xml ================================================ dashbuilder-shared org.dashbuilder 7.75.0-SNAPSHOT 4.0.0 dashbuilder-validations jar Dashbuilder Validations Dashbuilder validation factory and messages provider. org.kie.soup kie-soup-dataset-api org.kie.soup kie-soup-dataset-shared org.dashbuilder dashbuilder-dataset-client org.dashbuilder dashbuilder-displayer-api com.google.gwt gwt-user provided org.jboss.errai errai-common org.jboss.errai errai-ioc org.jboss.errai errai-validation javax.validation validation-api provided org.hibernate hibernate-validator provided com.google.gwt.gwtmockito gwtmockito test src/main/java src/main/resources ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/DataSetDefValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations; import javax.validation.ConstraintViolation; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; /** * Validator for {@link DataSetDef} */ public interface DataSetDefValidator { /** * Retrieves the supported {@link DataSetDef} type */ DataSetProviderType getSupportedProvider(); /** * Validates the {@link DataSetDef} basic attributes */ Iterable> validateBasicAttributes( DataSetDef dataSetDef ); /** * Validates the {@link DataSetDef} specific attributes */ Iterable> validateCustomAttributes( T dataSetDef, Object... params ); /** * Validates a {@link DataSetDef} */ Iterable> validate( T dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params ); Iterable> validateProviderType( DataSetDef dataSetDef ); } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/DataSetValidatorProvider.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations; import java.util.HashMap; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.validation.ConstraintViolation; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.DataSetDef; import org.jboss.errai.common.client.api.Assert; import org.jboss.errai.ioc.client.api.ManagedInstance; @ApplicationScoped public class DataSetValidatorProvider { private Map validators = new HashMap<>(); private ManagedInstance validatorsInstances; @Inject public DataSetValidatorProvider( ManagedInstance validatorsInstances ) { this.validatorsInstances = validatorsInstances; } @PostConstruct public void init() { for( DataSetDefValidator validator : validatorsInstances ) { registerValidator( validator ); } } protected void registerValidator( DataSetDefValidator validator ) { validators.put( validator.getSupportedProvider().getName(), validator ); } public DataSetDefValidator getValidator( DataSetDef dataSetDef ) { Assert.notNull("DataSetDef cannot be null", dataSetDef); DataSetDefValidator validator = validators.get( dataSetDef.getProvider().getName() ); if ( validator == null ) { throw new IllegalArgumentException( "Cannot find validator for type '" + dataSetDef.getClass().getName() + "'" ); } return validator; } public Iterable> validateAttributes( DataSetDef dataSetDef, Object... params ) { DataSetDefValidator validator = getValidator( dataSetDef ); return validator.validateCustomAttributes( dataSetDef, params ); } public Iterable> validate( DataSetDef dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params ) { DataSetDefValidator validator = getValidator( dataSetDef ); return validator.validate( dataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, params ); } public Iterable> validateBasicAttributes( DataSetDef dataSetDef ) { DataSetDefValidator validator = getValidator( dataSetDef ); return validator.validateBasicAttributes( dataSetDef ); } public Iterable> validateProviderType( DataSetDef dataSetDef ) { DataSetDefValidator validator = getValidator( dataSetDef ); return validator.validateProviderType( dataSetDef ); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/dataset/AbstractDataSetDefValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.validation.groups.DataSetDefBasicAttributesGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefCacheRowsValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefProviderTypeGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefPushSizeValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefRefreshIntervalValidation; import org.dashbuilder.validations.DataSetDefValidator; /** *

    The base data set definition validator.

    * @since 0.4.0 */ public abstract class AbstractDataSetDefValidator implements DataSetDefValidator { protected Validator validator; public AbstractDataSetDefValidator( Validator validator ) { this.validator = validator; } @Override public Iterable> validateProviderType( final DataSetDef dataSetDef ) { Set> violations = validator.validate( dataSetDef, DataSetDefProviderTypeGroup.class ); return (Iterable>) (Set) violations; } @Override public Iterable> validateBasicAttributes( DataSetDef dataSetDef ) { Set> violations = validator.validate( dataSetDef, DataSetDefBasicAttributesGroup.class ); return (Iterable>) (Set) violations; } protected Class[] getValidationGroups( final boolean isCacheEnabled, final boolean isPushEnabled, final boolean isRefreshEnabled, final Class... groups ) { List classes = new LinkedList(); classes.add( DataSetDefBasicAttributesGroup.class ); classes.add( DataSetDefProviderTypeGroup.class ); if ( isCacheEnabled ) { classes.add( DataSetDefCacheRowsValidation.class ); } if ( isPushEnabled ) { classes.add( DataSetDefPushSizeValidation.class ); } if ( isRefreshEnabled ) { classes.add( DataSetDefRefreshIntervalValidation.class ); } if ( groups != null ) { for ( final Class group : groups ) { classes.add( group ); } } return classes.toArray( new Class[classes.size()] ); } protected Iterable> toIterable( Set> violations ) { return (Iterable>) (Set) violations; } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/dataset/BeanDataSetDefValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.dashbuilder.dataset.validation.groups.BeanDataSetDefValidation; /** *

    The singleton application BEAN data set definition validator.

    * @since 0.4.0 */ @Dependent public class BeanDataSetDefValidator extends AbstractDataSetDefValidator { @Inject public BeanDataSetDefValidator( Validator validator ) { super( validator ); } @Override public DataSetProviderType getSupportedProvider() { return DataSetProviderType.BEAN; } @Override public Iterable> validateCustomAttributes( BeanDataSetDef dataSetDef, Object... params ) { Set> _violations = validator.validate( dataSetDef, BeanDataSetDefValidation.class ); return toIterable( _violations ); } @Override public Iterable> validate( BeanDataSetDef dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params ) { Set> _violations = validator.validate( dataSetDef, getValidationGroups( isCacheEnabled, isPushEnabled, isRefreshEnabled, BeanDataSetDefValidation.class ) ); return toIterable( _violations ); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/dataset/CSVDataSetDefValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.dataset.validation.groups.CSVDataSetDefFilePathValidation; import org.dashbuilder.dataset.validation.groups.CSVDataSetDefFileURLValidation; import org.dashbuilder.dataset.validation.groups.CSVDataSetDefValidation; /** *

    The singleton application CSV data set definition validator.

    * * @since 0.4.0 */ @Dependent public class CSVDataSetDefValidator extends AbstractDataSetDefValidator { @Inject public CSVDataSetDefValidator( Validator validator ) { super( validator ); } @Override public DataSetProviderType getSupportedProvider() { return DataSetProviderType.CSV; } @Override public Iterable> validateCustomAttributes( CSVDataSetDef dataSetDef, Object... params) { assert params != null && params.length == 1; final Boolean isFilePath = (Boolean) params[0]; Set> _violations = validator.validate( dataSetDef, CSVDataSetDefValidation.class, isFilePath ? CSVDataSetDefFilePathValidation.class : CSVDataSetDefFileURLValidation.class); return toIterable(_violations); } @Override public Iterable> validate(CSVDataSetDef dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params) { assert params != null && params.length == 1; final Boolean isFilePath = (Boolean) params[0]; Set> _violations = validator.validate(dataSetDef, getValidationGroups(isCacheEnabled, isPushEnabled, isRefreshEnabled, CSVDataSetDefValidation.class, isFilePath ? CSVDataSetDefFilePathValidation.class : CSVDataSetDefFileURLValidation.class)); return toIterable(_violations); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/dataset/KafkaDataSetDefValidator.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.KafkaDataSetDef; import org.dashbuilder.dataset.def.PrometheusDataSetDef; import org.dashbuilder.dataset.validation.groups.KafkaDataSetDefValidation; @Dependent public class KafkaDataSetDefValidator extends AbstractDataSetDefValidator { @Inject public KafkaDataSetDefValidator(Validator validator) { super(validator); } @Override public DataSetProviderType getSupportedProvider() { return DataSetProviderType.KAFKA; } @Override public Iterable> validateCustomAttributes(KafkaDataSetDef dataSetDef, Object... params) { Set> violations = validator.validate(dataSetDef, KafkaDataSetDefValidation.class); return toIterable(violations); } @Override public Iterable> validate(KafkaDataSetDef dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params) { Set> violations = validator.validate(dataSetDef, getValidationGroups(isCacheEnabled, isPushEnabled, isRefreshEnabled, KafkaDataSetDefValidation.class)); return toIterable(violations); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/dataset/PrometheusDataSetDefValidator.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.PrometheusDataSetDef; import org.dashbuilder.dataset.validation.groups.PrometheusDataSetDefValidation; @Dependent public class PrometheusDataSetDefValidator extends AbstractDataSetDefValidator { @Inject public PrometheusDataSetDefValidator(Validator validator) { super(validator); } @Override public DataSetProviderType getSupportedProvider() { return DataSetProviderType.PROMETHEUS; } @Override public Iterable> validateCustomAttributes(PrometheusDataSetDef dataSetDef, Object... params) { Set> violations = validator.validate(dataSetDef, PrometheusDataSetDefValidation.class); return toIterable(violations); } @Override public Iterable> validate(PrometheusDataSetDef dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params) { Set> violations = validator.validate(dataSetDef, getValidationGroups(isCacheEnabled, isPushEnabled, isRefreshEnabled, PrometheusDataSetDefValidation.class)); return toIterable(violations); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/java/org/dashbuilder/validations/dataset/SQLDataSetDefValidator.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import java.util.Set; import javax.enterprise.context.Dependent; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import org.dashbuilder.dataprovider.DataSetProviderType; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefDbSQLValidation; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefDbTableValidation; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefValidation; /** *

    The singleton application SQL data set definition validator.

    * @since 0.4.0 */ @Dependent public class SQLDataSetDefValidator extends AbstractDataSetDefValidator { @Inject public SQLDataSetDefValidator( Validator validator ) { super( validator ); } @Override public DataSetProviderType getSupportedProvider() { return DataSetProviderType.SQL; } @Override public Iterable> validateCustomAttributes( SQLDataSetDef dataSetDef, Object... params ) { assert params != null && params.length == 1; final Boolean isQuery = (Boolean) params[0]; Set> _violations = validator.validate( dataSetDef, SQLDataSetDefValidation.class, isQuery ? SQLDataSetDefDbSQLValidation.class : SQLDataSetDefDbTableValidation.class ); return toIterable( _violations ); } @Override public Iterable> validate( SQLDataSetDef dataSetDef, boolean isCacheEnabled, boolean isPushEnabled, boolean isRefreshEnabled, Object... params ) { assert params != null && params.length == 1; final Boolean isQuery = (Boolean) params[0]; Set> _violations = validator.validate( dataSetDef, getValidationGroups( isCacheEnabled, isPushEnabled, isRefreshEnabled, SQLDataSetDefValidation.class, isQuery ? SQLDataSetDefDbSQLValidation.class : SQLDataSetDefDbTableValidation.class ) ); return toIterable( _violations ); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/main/resources/org/dashbuilder/CommonValidations.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/test/java/org/dashbuilder/validations/dataset/AbstractValidationTest.java ================================================ package org.dashbuilder.validations.dataset; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validator; import javax.validation.metadata.BeanDescriptor; import static org.mockito.Mockito.*; public class AbstractValidationTest { protected Validator validator; public void setup() { validator = spy(new ValidatorMock()); } // Mockito is not able to mock javax.validation.Validator, so let's create an empty implementation and spy it. class ValidatorMock implements Validator { @Override public Set> validate(T object, Class... groups) { return null; } @Override public Set> validateProperty(T object, String propertyName, Class... groups) { return null; } @Override public Set> validateValue(Class beanType, String propertyName, Object value, Class... groups) { return null; } @Override public BeanDescriptor getConstraintsForClass(Class clazz) { return null; } @Override public T unwrap(Class type) { return null; } } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/test/java/org/dashbuilder/validations/dataset/BeanDataSetDefValidatorTest.java ================================================ package org.dashbuilder.validations.dataset; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.dataset.def.BeanDataSetDef; import org.dashbuilder.dataset.validation.groups.BeanDataSetDefValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefBasicAttributesGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefCacheRowsValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefProviderTypeGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefPushSizeValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefRefreshIntervalValidation; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class BeanDataSetDefValidatorTest extends AbstractValidationTest { @Mock BeanDataSetDef beanDataSetDef; private BeanDataSetDefValidator tested; @Before public void setup() { super.setup(); tested = spy(new BeanDataSetDefValidator( validator )); } @Test public void testValidateAttributes() { tested.validateCustomAttributes( beanDataSetDef); verify(validator, times(1)).validate(beanDataSetDef, BeanDataSetDefValidation.class); } @Test public void testValidate() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; tested.validate(beanDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled); verify(validator, times(1)).validate(beanDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, BeanDataSetDefValidation.class); } @Test public void testValidateNoCache() { final boolean isCacheEnabled = false; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; tested.validate(beanDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled); verify(validator, times(1)).validate(beanDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, BeanDataSetDefValidation.class); } @Test public void testValidateNoPush() { final boolean isCacheEnabled = true; final boolean isPushEnabled = false; final boolean isRefreshEnabled = true; tested.validate(beanDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled); verify(validator, times(1)).validate(beanDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefRefreshIntervalValidation.class, BeanDataSetDefValidation.class); } @Test public void testValidateNoRefresh() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = false; tested.validate(beanDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled); verify(validator, times(1)).validate(beanDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, BeanDataSetDefValidation.class); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/test/java/org/dashbuilder/validations/dataset/CSVDataSetDefValidatorTest.java ================================================ package org.dashbuilder.validations.dataset; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.dataset.def.CSVDataSetDef; import org.dashbuilder.dataset.validation.groups.CSVDataSetDefFilePathValidation; import org.dashbuilder.dataset.validation.groups.CSVDataSetDefFileURLValidation; import org.dashbuilder.dataset.validation.groups.CSVDataSetDefValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefBasicAttributesGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefCacheRowsValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefProviderTypeGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefPushSizeValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefRefreshIntervalValidation; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class CSVDataSetDefValidatorTest extends AbstractValidationTest { @Mock CSVDataSetDef csvDataSetDef; private CSVDataSetDefValidator tested; @Before public void setup() { super.setup(); tested = spy(new CSVDataSetDefValidator( validator)); } @Test public void testValidateAttributesUsingFilePath() { final boolean isUsingFilePath = true; tested.validateCustomAttributes( csvDataSetDef, isUsingFilePath); verify(validator, times(1)).validate(csvDataSetDef, CSVDataSetDefValidation.class, CSVDataSetDefFilePathValidation.class); } @Test public void testValidateAttributesUsingFileUrl() { final boolean isUsingFilePath = false; tested.validateCustomAttributes( csvDataSetDef, isUsingFilePath); verify(validator, times(1)).validate(csvDataSetDef, CSVDataSetDefValidation.class, CSVDataSetDefFileURLValidation.class); } @Test public void testValidateUsingFilePath() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; final boolean isUsingFilePath = true; tested.validate(csvDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingFilePath); verify(validator, times(1)).validate(csvDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, CSVDataSetDefValidation.class, CSVDataSetDefFilePathValidation.class); } @Test public void testValidateUsingFileUrl() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; final boolean isUsingFilePath = false; tested.validate(csvDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingFilePath); verify(validator, times(1)).validate(csvDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, CSVDataSetDefValidation.class, CSVDataSetDefFileURLValidation.class); } @Test public void testValidateNoCache() { final boolean isCacheEnabled = false; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; final boolean isUsingFilePath = false; tested.validate(csvDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingFilePath); verify(validator, times(1)).validate(csvDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, CSVDataSetDefValidation.class, CSVDataSetDefFileURLValidation.class); } @Test public void testValidateNoPush() { final boolean isCacheEnabled = true; final boolean isPushEnabled = false; final boolean isRefreshEnabled = true; final boolean isUsingFilePath = false; tested.validate(csvDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingFilePath); verify(validator, times(1)).validate(csvDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefRefreshIntervalValidation.class, CSVDataSetDefValidation.class, CSVDataSetDefFileURLValidation.class); } @Test public void testValidateNoRefresh() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = false; final boolean isUsingFilePath = false; tested.validate(csvDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingFilePath); verify(validator, times(1)).validate(csvDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, CSVDataSetDefValidation.class, CSVDataSetDefFileURLValidation.class); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/test/java/org/dashbuilder/validations/dataset/KafkaDataSetDefValidatorTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.dataset.def.KafkaDataSetDef; import org.dashbuilder.dataset.validation.groups.KafkaDataSetDefValidation; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class KafkaDataSetDefValidatorTest extends AbstractValidationTest { @Mock KafkaDataSetDef kafkaDataSetDef; private KafkaDataSetDefValidator tested; @Before public void setup() { super.setup(); tested = spy(new KafkaDataSetDefValidator(validator)); } @Test public void testValidate() { tested.validateCustomAttributes(kafkaDataSetDef); verify(validator).validate(kafkaDataSetDef, KafkaDataSetDefValidation.class); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/test/java/org/dashbuilder/validations/dataset/PrometheusDataSetDefValidatorTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.validations.dataset; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.dataset.def.PrometheusDataSetDef; import org.dashbuilder.dataset.validation.groups.PrometheusDataSetDefValidation; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @RunWith(GwtMockitoTestRunner.class) public class PrometheusDataSetDefValidatorTest extends AbstractValidationTest { @Mock PrometheusDataSetDef prometheusDataSetDef; private PrometheusDataSetDefValidator tested; @Before public void setup() { super.setup(); tested = spy(new PrometheusDataSetDefValidator(validator)); } @Test public void testValidate() { tested.validateCustomAttributes(prometheusDataSetDef); verify(validator).validate(prometheusDataSetDef, PrometheusDataSetDefValidation.class); } } ================================================ FILE: dashbuilder/dashbuilder-shared/dashbuilder-validations/src/test/java/org/dashbuilder/validations/dataset/SQLDataSetDefValidatorTest.java ================================================ package org.dashbuilder.validations.dataset; import com.google.gwtmockito.GwtMockitoTestRunner; import org.dashbuilder.dataset.def.SQLDataSetDef; import org.dashbuilder.dataset.validation.groups.DataSetDefBasicAttributesGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefCacheRowsValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefProviderTypeGroup; import org.dashbuilder.dataset.validation.groups.DataSetDefPushSizeValidation; import org.dashbuilder.dataset.validation.groups.DataSetDefRefreshIntervalValidation; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefDbSQLValidation; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefDbTableValidation; import org.dashbuilder.dataset.validation.groups.SQLDataSetDefValidation; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import static org.mockito.Mockito.*; @RunWith(GwtMockitoTestRunner.class) public class SQLDataSetDefValidatorTest extends AbstractValidationTest { @Mock SQLDataSetDef sqlDataSetDef; private SQLDataSetDefValidator tested; @Before public void setup() { super.setup(); tested = spy(new SQLDataSetDefValidator( validator )); } @Test public void testValidateAttributesUsingQuery() { final boolean isUsingQuery = true; tested.validateCustomAttributes( sqlDataSetDef, isUsingQuery); verify(validator, times(1)).validate(sqlDataSetDef, SQLDataSetDefValidation.class, SQLDataSetDefDbSQLValidation.class); } @Test public void testValidateAttributesUsingTable() { final boolean isUsingQuery = false; tested.validateCustomAttributes( sqlDataSetDef, isUsingQuery); verify(validator, times(1)).validate(sqlDataSetDef, SQLDataSetDefValidation.class, SQLDataSetDefDbTableValidation.class); } @Test public void testValidateUsingQuery() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; final boolean isUsingQuery = true; tested.validate(sqlDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingQuery); verify(validator, times(1)).validate(sqlDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, SQLDataSetDefValidation.class, SQLDataSetDefDbSQLValidation.class); } @Test public void testValidateUsingTable() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; final boolean isUsingQuery = false; tested.validate(sqlDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingQuery); verify(validator, times(1)).validate(sqlDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, SQLDataSetDefValidation.class, SQLDataSetDefDbTableValidation.class); } @Test public void testValidateNoCache() { final boolean isCacheEnabled = false; final boolean isPushEnabled = true; final boolean isRefreshEnabled = true; final boolean isUsingQuery = false; tested.validate(sqlDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingQuery); verify(validator, times(1)).validate(sqlDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefPushSizeValidation.class, DataSetDefRefreshIntervalValidation.class, SQLDataSetDefValidation.class, SQLDataSetDefDbTableValidation.class); } @Test public void testValidateNoPush() { final boolean isCacheEnabled = true; final boolean isPushEnabled = false; final boolean isRefreshEnabled = true; final boolean isUsingQuery = false; tested.validate(sqlDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingQuery); verify(validator, times(1)).validate(sqlDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefRefreshIntervalValidation.class, SQLDataSetDefValidation.class, SQLDataSetDefDbTableValidation.class); } @Test public void testValidateNoRefresh() { final boolean isCacheEnabled = true; final boolean isPushEnabled = true; final boolean isRefreshEnabled = false; final boolean isUsingQuery = false; tested.validate(sqlDataSetDef, isCacheEnabled, isPushEnabled, isRefreshEnabled, isUsingQuery); verify(validator, times(1)).validate(sqlDataSetDef, DataSetDefBasicAttributesGroup.class, DataSetDefProviderTypeGroup.class, DataSetDefCacheRowsValidation.class, DataSetDefPushSizeValidation.class, SQLDataSetDefValidation.class, SQLDataSetDefDbTableValidation.class); } } ================================================ FILE: dashbuilder/dashbuilder-shared/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT ../pom.xml dashbuilder-shared pom Dashbuilder Shared dashbuilder-displayer-api dashbuilder-validations dashbuilder-navigation-api dashbuilder-services-api dashbuilder-kie-server-api dashbuilder-js dashbuilder-dsl ================================================ FILE: dashbuilder/dashbuilder-webapp/.gitignore ================================================ *.deploy /src/main/gwt-unitCache /src/main/webapp/WEB-INF/classes/ /src/main/webapp/WEB-INF/lib /src/main/webapp/org.dashbuilder.DashbuilderShowcase/ ================================================ FILE: dashbuilder/dashbuilder-webapp/README.md ================================================ Dashbuilder web application ============================ System metrics dashboard ------------------------ This web application provides an example dashboard for monitoring real time system metrics. The dashboard is called **System metrics** and can be found in the tree menu *combined* of the gallery perspective. In order to run this example you must enable and configure the collectd daemon (Unix/Linux systems) as: 1.- Install collectd package sudo yum install collectd 2.- Configure /etc/collectd.conf as the following example: Hostname "host.example.com" Interval 1 LoadPlugin memory LoadPlugin csv # Use a custom data dir location. DataDir "/tmp/metrics/csv" StoreRates false 3.- Start the service service collectd start 4.- Check service is up service collectd status 5.- Create a new data set definition or modify the filePath value of existing file located at [here](./src/main/webapp/datasets/metrics_csv.dset) as: { "uuid": "metrics_csv", "provider": "CSV", "isPublic": true, "refreshTime": "1second", "refreshAlways": "true", "filePath": "/tmp/metrics/csv/host.example.com/memory/memory-used-2015-02-04", "separatorChar": ",", "quoteChar": "\"", "escapeChar": "\\", "datePattern": "epoch", "numberPattern": "#.##", "columns": [ {"id": "epoch", "type": "date", "pattern": "epoch"}, {"id": "value", "type": "number", "pattern": "#.##"} ] } 6.- Run the web application and navigate to *System metrics* dashboard ================================================ FILE: dashbuilder/dashbuilder-webapp/pom.xml ================================================ 4.0.0 org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT ../pom.xml dashbuilder-webapp war Dashbuilder WebApp Dashbuilder WebApp ${project.build.directory}/wildfly-${version.org.wildfly} false 4 org.jboss.xnio xnio-api jakarta.servlet.jsp jakarta.servlet.jsp-api provided jakarta.xml.bind jakarta.xml.bind-api provided jakarta.security.jacc jakarta.security.jacc-api provided org.apache.commons commons-lang3 org.dashbuilder dashbuilder-server-all org.dashbuilder dashbuilder-dataset-cdi org.kie.soup kie-soup-dataset-api org.dashbuilder dashbuilder-client-all provided org.dashbuilder dashbuilder-common-client provided org.dashbuilder dashbuilder-dataset-client provided org.dashbuilder dashbuilder-kie-server-client provided org.dashbuilder dashbuilder-kie-server-api org.dashbuilder dashbuilder-kie-server-backend org.dashbuilder dashbuilder-external-backend org.dashbuilder dashbuilder-displayer-api org.dashbuilder dashbuilder-displayer-client provided org.dashbuilder dashbuilder-displayer-screen provided org.dashbuilder dashbuilder-dataset-editor provided org.dashbuilder dashbuilder-displayer-editor provided org.dashbuilder dashbuilder-renderer-default provided org.dashbuilder dashbuilder-renderer-c3 provided org.dashbuilder dashbuilder-renderer-chartjs provided org.dashbuilder dashbuilder-navigation-api org.dashbuilder dashbuilder-services-api org.dashbuilder dashbuilder-navigation-client provided org.dashbuilder dashbuilder-cms-client provided org.uberfire uberfire-server-all org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-commons-editor-api org.uberfire uberfire-commons-editor-client provided org.uberfire uberfire-widgets-core-client provided org.uberfire appformer-js-bridge org.uberfire uberfire-api org.uberfire uberfire-js org.uberfire uberfire-client-api provided org.uberfire uberfire-io org.uberfire uberfire-backend-api org.uberfire uberfire-backend-server org.uberfire uberfire-nio2-api org.uberfire uberfire-nio2-model org.uberfire uberfire-workbench-client provided org.uberfire uberfire-workbench-processors provided org.uberfire uberfire-runtime-plugins-api org.uberfire uberfire-runtime-plugins-client provided org.uberfire uberfire-runtime-plugins-backend org.uberfire uberfire-layout-editor-client provided org.uberfire uberfire-layout-editor-api org.uberfire uberfire-layout-editor-backend org.uberfire uberfire-widgets-service-api org.uberfire uberfire-widgets-properties-editor-api org.uberfire uberfire-widgets-properties-editor-client provided org.uberfire uberfire-widgets-properties-editor-backend org.uberfire uberfire-workbench-client-views-patternfly provided org.uberfire uberfire-widgets-commons provided org.uberfire uberfire-widgets-table provided org.uberfire uberfire-simple-docks-client provided org.uberfire uberfire-preferences-api org.uberfire uberfire-preferences-backend org.uberfire uberfire-preferences-ui-client provided org.uberfire uberfire-preferences-client provided org.uberfire uberfire-preferences-client-backend provided org.uberfire uberfire-security-api org.uberfire uberfire-security-client-backend provided org.uberfire uberfire-servlet-security org.uberfire uberfire-security-management-api org.uberfire uberfire-security-management-backend org.uberfire uberfire-security-management-wildfly org.uberfire uberfire-security-management-client provided org.uberfire uberfire-widgets-security-management provided org.uberfire uberfire-security-management-client-wb provided org.uberfire uberfire-experimental-api org.uberfire uberfire-experimental-backend org.uberfire uberfire-experimental-client provided org.slf4j slf4j-api provided org.slf4j log4j-over-slf4j org.jboss.errai errai-common org.jboss.errai errai-marshalling de.benediktmeurer.gwt-slf4j gwt-slf4j provided org.jboss.errai errai-ui provided org.jboss.errai errai-ioc org.jboss.errai errai-security-server org.jboss.errai errai-javax-enterprise provided org.jboss.errai errai-security-client provided org.jboss.errai errai-jboss-as-support org.jboss.errai errai-cdi-server org.owasp.encoder encoder org.jboss.errai errai-codegen-gwt provided org.jboss.errai errai-validation provided javax.validation validation-api provided javax.validation validation-api sources provided org.hibernate hibernate-validator provided org.hibernate hibernate-validator provided sources jakarta.enterprise jakarta.enterprise.cdi-api provided jakarta.inject jakarta.inject-api provided org.jboss.errai errai-cdi-jboss provided xml-apis xml-apis provided com.sun.xml.bind jaxb-impl provided org.jboss.resteasy resteasy-cdi provided org.jboss.resteasy resteasy-jaxrs provided com.google.gwt gwt-user provided javax.servlet javax.servlet-api org.gwtbootstrap3 gwtbootstrap3 provided org.gwtbootstrap3 gwtbootstrap3-extras provided org.uberfire uberfire-ssh-api org.uberfire uberfire-ssh-client org.uberfire uberfire-ssh-backend com.google.inject guice org.jboss.errai errai-data-binding org.jboss.errai errai-cdi-shared ${project.artifactId} src/main/webapp/WEB-INF/classes org.codehaus.mojo gwt-maven-plugin ${project.build.directory}/gwt-symbols-deploy ${gwt.compiler.localWorkers} org.dashbuilder.FastCompiledDashbuilderShowcase true INFO true org.kie.soup:kie-soup-json org.dashbuilder:dashbuilder-widgets org.dashbuilder:dashbuilder-validations org.dashbuilder:dashbuilder-common-client org.dashbuilder:dashbuilder-services-api org.kie.soup:kie-soup-dataset-api org.kie.soup:kie-soup-dataset-shared org.dashbuilder:dashbuilder-dataset-client org.dashbuilder:dashbuilder-displayer-api org.dashbuilder:dashbuilder-displayer-client org.dashbuilder:dashbuilder-displayer-screen org.dashbuilder:dashbuilder-displayer-editor org.dashbuilder:dashbuilder-dataset-editor org.dashbuilder:dashbuilder-renderer-default org.dashbuilder:dashbuilder-renderer-chartjs org.dashbuilder:dashbuilder-renderer-c3 org.dashbuilder:dashbuilder-navigation-api org.dashbuilder:dashbuilder-navigation-client org.dashbuilder:dashbuilder-cms-client org.dashbuilder:dashbuilder-kie-server-api org.dashbuilder:dashbuilder-kie-server-client org.uberfire:uberfire-runtime-plugins-api org.uberfire:uberfire-runtime-plugins-client org.uberfire:uberfire-layout-editor-api org.uberfire:uberfire-layout-editor-client org.uberfire:uberfire-commons-editor-api org.uberfire:uberfire-commons-editor-client org.uberfire:uberfire-widgets-core-client org.uberfire:uberfire-widgets-service-api org.uberfire:uberfire-widgets-commons org.uberfire:uberfire-widgets-table org.uberfire:uberfire-widgets-properties-editor-api org.uberfire:uberfire-widgets-properties-editor-client org.uberfire:uberfire-simple-docks-client org.uberfire:uberfire-preferences-api org.uberfire:uberfire-preferences-client-backend org.uberfire:uberfire-preferences-client org.uberfire:uberfire-preferences-ui-client org.kie.soup:kie-soup-commons org.uberfire:uberfire-commons org.uberfire:uberfire-nio2-model org.uberfire:uberfire-io org.uberfire:uberfire-api org.uberfire:uberfire-js org.uberfire:appformer-js-bridge org.uberfire:uberfire-security-api org.uberfire:uberfire-security-client org.uberfire:uberfire-client-api org.uberfire:uberfire-workbench-client org.uberfire:uberfire-workbench-client-backend org.uberfire:uberfire-workbench-client-views-patternfly org.uberfire:uberfire-backend-api org.uberfire:uberfire-ssh-client org.uberfire:uberfire-ssh-api org.uberfire:uberfire-security-management-api org.uberfire:uberfire-security-management-client org.uberfire:uberfire-security-management-client-wb org.uberfire:uberfire-widgets-security-management org.uberfire:uberfire-experimental-api org.uberfire:uberfire-experimental-client dashbuilder.html -Xmx4024m -XX:CompileThreshold=7000 -Derrai.jboss.home=${errai.jboss.home} -Derrai.jboss.debug.port=8787 -Ddashbuilder.components.enable=true -Ddashbuilder.export.dir=/tmp/dashbuilder/models -Ddashbuilder.runtime.location=http://localhost:8280 -Ddashbuilder.shareOpenModel=true -Ddashbuilder.kieserver.serverTemplate.default.location=http://localhost:8080/kie-server/services/rest/server -Ddashbuilder.kieserver.serverTemplate.default.user=kieserver -Ddashbuilder.kieserver.serverTemplate.default.password=kieserver1! -Ddashbuilder.kieserver.defaultServerTemplate=default -Ddashbuilder.kieserver.serverTemplates=default false org.jboss.errai.cdi.server.gwt.EmbeddedWildFlyLauncher src/main/webapp ${project.build.directory}/${project.build.finalName} true gwt-clean clean clean gwt-compile resources compile maven-war-plugin **/javax/**/*.*,**/client/**/*.class,**/*.symbolMap false maven-clean-plugin ${basedir} src/main/webapp/org.dashbuilder.DashbuilderShowcase/ src/main/webapp/WEB-INF/classes/ src/main/webapp/WEB-INF/deploy/ src/main/webapp/WEB-INF/lib/ **/gwt-unitCache/** .errai/ .niogit/** .index/** org.apache.maven.plugins maven-dependency-plugin unpack process-resources unpack org.jboss.errai wildfly-dist ${version.org.jboss.errai.wildfly} zip false ${project.build.directory} ${gwt.compiler.skip} maven-resources-plugin 2.6 copy-resources process-resources copy-resources ${project.build.directory}/wildfly-${version.org.wildfly}/standalone/deployments src/test/resources/datasources true fullProfile full org.codehaus.mojo gwt-maven-plugin org.dashbuilder.DashbuilderShowcase false true no-showcase org.codehaus.mojo gwt-maven-plugin true ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/backend/ApplicationScopedProducer.java ================================================ package org.dashbuilder.backend; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.service.AuthenticationService; import org.uberfire.backend.server.IOWatchServiceAllImpl; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; import org.uberfire.io.IOService; import org.uberfire.io.impl.IOServiceNio2WrapperImpl; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Named; @Startup(value = StartupType.BOOTSTRAP) @ApplicationScoped public class ApplicationScopedProducer { @Inject private AuthenticationService authenticationService; @Inject private IOWatchServiceAllImpl watchService; private IOService ioService; @PostConstruct public void setup() { ioService = new IOServiceNio2WrapperImpl("1", watchService); } @Produces @Named("ioStrategy") public IOService ioService() { return ioService; } @Produces @RequestScoped public User getIdentity() { return authenticationService.getUser(); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/backend/ClusterMetricsGenerator.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import org.apache.commons.lang3.StringUtils; import org.dashbuilder.dataset.*; import org.dashbuilder.dataset.date.TimeAmount; import java.util.*; /** * Generates metrics on an emulated cluster */ public class ClusterMetricsGenerator implements DataSetGenerator { public static final String COLUMN_SERVER = "server"; public static final String COLUMN_TIMESTAMP = "timestamp"; public static final String COLUMN_CPU0 = "cpu0"; public static final String COLUMN_CPU1 = "cpu1"; public static final String COLUMN_MEMORY_FREE = "mem_free"; public static final String COLUMN_MEMORY_USED = "mem_used"; public static final String COLUMN_NETWORK_TX = "tx"; public static final String COLUMN_NETWORK_RX = "rx"; public static final String COLUMN_PROCESSES_RUNNING = "p_running"; public static final String COLUMN_PROCESSES_SLEEPING = "p_sleeping"; public static final String COLUMN_DISK_FREE = "disk_free"; public static final String COLUMN_DISK_USED = "disk_used"; DataSet dataSet = null; long timeFrameMillis = 100000; List aliveNodes = new ArrayList<>(); List overloadedNodes = new ArrayList<>(); public ClusterMetricsGenerator() { dataSet = DataSetFactory.newDataSetBuilder() .column(COLUMN_SERVER, ColumnType.LABEL) .column(COLUMN_TIMESTAMP, ColumnType.DATE) .column(COLUMN_CPU0, ColumnType.NUMBER) .column(COLUMN_CPU1, ColumnType.NUMBER) .column(COLUMN_MEMORY_FREE, ColumnType.NUMBER) .column(COLUMN_MEMORY_USED, ColumnType.NUMBER) .column(COLUMN_NETWORK_TX, ColumnType.NUMBER) .column(COLUMN_NETWORK_RX, ColumnType.NUMBER) .column(COLUMN_PROCESSES_RUNNING, ColumnType.NUMBER) .column(COLUMN_PROCESSES_SLEEPING, ColumnType.NUMBER) .column(COLUMN_DISK_FREE, ColumnType.NUMBER) .column(COLUMN_DISK_USED, ColumnType.NUMBER) .buildDataSet(); } public synchronized DataSet buildDataSet(Map params) { // Check if the data set is up to date. long now = System.currentTimeMillis(); long last = dataSet.getRowCount() > 0 ? ((Date)dataSet.getValueAt(0, 1)).getTime() : -1; long diff = now-last; if (last != -1 && diff < 1000) { return dataSet; } if (!StringUtils.isBlank(params.get("timeFrame"))) { String p = params.get("timeFrame"); if (p != null && p.trim().length() > 0) { TimeAmount timeFrame = TimeAmount.parse(p); timeFrameMillis = timeFrame.toMillis(); } } if (params.containsKey("aliveNodes")) { aliveNodes.clear(); aliveNodes.addAll(Arrays.asList(StringUtils.split(params.get("aliveNodes"), ","))); } if (params.containsKey("overloadedNodes")) { overloadedNodes.clear(); overloadedNodes.addAll(Arrays.asList(StringUtils.split(params.get("overloadedNodes"), ","))); } if (aliveNodes.isEmpty()) { return dataSet; } if (diff > timeFrameMillis) { diff = timeFrameMillis; } // Create a new data set containing the missing metrics since the last update. if (last == -1) last = now-timeFrameMillis; DataSet newDataSet = dataSet.cloneEmpty(); long seconds = diff / 1000; for (long i = 1; i <=seconds; i++) { long metricTime = last + i*1000; for (int j = 0; j < aliveNodes.size(); j++) { Double lastCpu0 = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 2) : null; Double lastCpu1 = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 3) : null; Double lastFreeMem = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 4) : null; Double lastTx = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 6) : null; Double lastRx = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 7) : null; Double lastRunningProc = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 8) : null; Double lastSleepingProc = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 9) : null; Double lastFreeDisk = dataSet.getRowCount() > j ? (Double) dataSet.getValueAt(j, 10) : null; String node = aliveNodes.get(j); double memFree = mem(node, lastFreeMem, 16d, 12d); double diskFree = disk(node, lastFreeDisk, 4000d, 3600d); newDataSet.addValuesAt(0, node, new Date(metricTime), cpu(node, lastCpu0, 100d, 90d), cpu(node, lastCpu1, 100d, 90d), memFree, 16-memFree, net(node, lastTx, 4000d, 3000d), net(node, lastRx, 2000d, 1800d), proc(node, lastRunningProc, 1500d, 1024d), proc(node, lastSleepingProc, 500d, 400d), diskFree, 4000-diskFree); } } // Add the remain metric history boolean outOfBounds = false; Date threshold = new Date(now - timeFrameMillis); for (int i = 0; i < dataSet.getRowCount() && !outOfBounds; i++) { Date metricTime = (Date)dataSet.getValueAt(i, 1); if (metricTime.after(threshold)) { newDataSet.addValues( dataSet.getValueAt(i, 0), dataSet.getValueAt(i, 1), dataSet.getValueAt(i, 2), dataSet.getValueAt(i, 3), dataSet.getValueAt(i, 4), dataSet.getValueAt(i, 5), dataSet.getValueAt(i, 6), dataSet.getValueAt(i, 7), dataSet.getValueAt(i, 8), dataSet.getValueAt(i, 9), dataSet.getValueAt(i, 10), dataSet.getValueAt(i, 11)); } else { outOfBounds = true; } } return dataSet = newDataSet; } /** * Network (kbps) */ public Double net(String node, Double last, Double max, Double overloaded) { double r = Math.random() - 0.5; if (overloadedNodes.contains(node)) { if (last == null) { return max + 100 * r; } else { double v = last + 100 * r; if (v > max) return max; if (v < overloaded) return overloaded; return v; } } if (last == null) { return 1000 + 100 * r; } else { double v = last + 100 * r; if (v > max) return max; if (v < 0) return 0d; return v; } } /** * Processes (count) * Overloaded values : from 1024 to 1500 */ public Double proc(String node, Double last, Double max, Double overloaded) { double r = Math.random() - 0.5; if (overloadedNodes.contains(node)) { if (last == null) { return overloaded; } else { double v = last + 100 * r; if (v > max) return max; if (v < overloaded) return overloaded; return v; } } if (last == null) { return 280 + 10 * r; } else { double v = last + 10 * r; if (v > max) return max; if (v < 0) return 0d; return v; } } /** * Disk space (Gb) */ public Double disk(String node, Double last, Double max, Double overloaded) { double r = Math.random() - 0.5; if (overloadedNodes.contains(node)) { if (last == null) { return overloaded + 400 * r; } else { double v = last + 400 * r; if (v > max) return max; if (v < overloaded) return overloaded; return v; } } if (last == null) { return 500 + 400 * r; } else { double v = last + 400 * r; if (v > max) return max; if (v < 0) return 0d; return v; } } /** * CPU (%) * Overloaded values : from 90% to 100% */ public Double cpu(String node, Double last, Double max, Double overloaded) { double r = Math.random() - 0.5; if (overloadedNodes.contains(node)) { if (last == null) { return overloaded + 10 * r; } else { double v = last + 10 * r; if (v > max) return max; if (v < overloaded) return overloaded; return v; } } if (last == null) { return 20 + 20 * r; } else { double v = last + 10 * r; if (v > max) return max; if (v < 0) return 0d; return v; } } /** * Memory (Gb) * Overloaded values : from 3Gb to 4Gb */ public Double mem(String node, Double last, Double max, Double overloaded) { double r = Math.random() - 0.5; if (overloadedNodes.contains(node)) { if (last == null) { return overloaded + r; } else { double v = last + r; if (v > max) return max; if (v < overloaded) return overloaded; return v; } } if (last == null) { return 1 + r; } else { double v = last + r; if (v > max) return max; if (v < 0) return 0d; return v; } } public static void main(String[] args) throws Exception { ClusterMetricsGenerator g = new ClusterMetricsGenerator(); Map params = new HashMap<>(); params.put("aliveNodes", "server1"); params.put("timeFrame", "10second"); System.out.println("************* Single node not overloaded *******************************"); for (int i = 0; i < 5; i++) { DataSet dataSet = g.buildDataSet(params); printDataSet(dataSet); Thread.sleep(1000); } System.out.println("************* Two nodes and the second one overloaded *******************************"); g = new ClusterMetricsGenerator(); params = new HashMap<>(); params.put("aliveNodes", "server1,server2"); params.put("overloadedNodes", "server2"); params.put("timeFrame", "10second"); for (int i = 0; i < 5; i++) { DataSet dataSet = g.buildDataSet(params); printDataSet(dataSet); Thread.sleep(1000); } } /** * Helper method to print to standard output the dataset values. */ protected static void printDataSet(DataSet dataSet) { final String SPACER = "| \t |"; if (dataSet == null) System.out.println("DataSet is null"); if (dataSet.getRowCount() == 0) System.out.println("DataSet is empty"); List dataSetColumns = dataSet.getColumns(); int colColunt = dataSetColumns.size(); int rowCount = dataSet.getRowCount(); System.out.println("********************************************************************************************************************************************************"); for (int row = 0; row < rowCount; row++) { System.out.print(SPACER); for (int col= 0; col< colColunt; col++) { Object value = dataSet.getValueAt(row, col); String colId = dataSet.getColumnByIndex(col).getId(); System.out.print(colId + ": " + value); System.out.print(SPACER); } System.out.println(""); } System.out.println("********************************************************************************************************************************************************"); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/backend/RepositoryServiceImpl.java ================================================ /* * Copyright 2022 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Default; import org.guvnor.structure.organizationalunit.OrganizationalUnit; import org.guvnor.structure.repositories.Repository; import org.guvnor.structure.repositories.RepositoryAlreadyExistsException; import org.guvnor.structure.repositories.RepositoryEnvironmentConfigurations; import org.guvnor.structure.repositories.RepositoryInfo; import org.guvnor.structure.repositories.RepositoryService; import org.uberfire.backend.vfs.Path; import org.uberfire.java.nio.base.version.VersionRecord; import org.uberfire.security.Contributor; import org.uberfire.spaces.Space; /** * This is not used with Dashbuilder WebApp, but mocks the service so dashbuilder webapp can run * */ @Default @ApplicationScoped public class RepositoryServiceImpl implements RepositoryService { @Override public void addGroup(Repository arg0, String arg1) { // empty } @Override public Repository createRepository(OrganizationalUnit arg0, String arg1, String arg2, RepositoryEnvironmentConfigurations arg3) throws RepositoryAlreadyExistsException { // empty return null; } @Override public Repository createRepository(OrganizationalUnit arg0, String arg1, String arg2, RepositoryEnvironmentConfigurations arg3, Collection arg4) throws RepositoryAlreadyExistsException { // empty return null; } @Override public Collection getAllDeletedRepositories(Space arg0) { return Collections.emptyList(); } @Override public Collection getAllRepositories(Space arg0) { return Collections.emptyList(); } @Override public Collection getAllRepositories(Space arg0, boolean arg1) { return Collections.emptyList(); } @Override public Collection getAllRepositoriesFromAllUserSpaces() { return Collections.emptyList(); } @Override public Collection getRepositories(Space arg0) { return Collections.emptyList(); } @Override public Repository getRepository(Path arg0) { return null; } @Override public Repository getRepository(Space arg0, Path arg1) { return null; } @Override public Repository getRepositoryFromSpace(Space arg0, String arg1) { return null; } @Override public List getRepositoryHistory(Space arg0, String arg1, int arg2) { return Collections.emptyList(); } @Override public List getRepositoryHistory(Space arg0, String arg1, int arg2, int arg3) { return Collections.emptyList(); } @Override public List getRepositoryHistoryAll(Space arg0, String arg1) { return Collections.emptyList(); } @Override public RepositoryInfo getRepositoryInfo(Space arg0, String arg1) { return null; } @Override public String normalizeRepositoryName(String arg0) { return null; } @Override public void removeGroup(Repository arg0, String arg1) { // empty } @Override public void removeRepositories(Space arg0, Set arg1) { // empty } @Override public void removeRepository(Space arg0, String arg1) { // empty } @Override public void updateContributors(Repository arg0, List arg1) { // empty } @Override public boolean validateRepositoryName(String arg0) { // empty return false; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/backend/RuntimeJaxApp.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("/rest") public class RuntimeJaxApp extends Application { } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/backend/SalesDataSetGenerator.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend; import java.util.Calendar; import java.util.Date; import java.util.Map; import java.util.Random; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.dataset.DataSet; import org.dashbuilder.dataset.DataSetBuilder; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.dataset.DataSetGenerator; import static org.dashbuilder.shared.sales.SalesConstants.*; /** * Generates a random data set containing sales opportunity records. */ @ApplicationScoped public class SalesDataSetGenerator implements DataSetGenerator { private static String[] DIC_PIPELINE = {"EARLY", "STANDBY", "ADVANCED"}; private static String[] DIC_STATUS = {"CONTACTED", "STANDBY", "DEMO", "SHORT LISTED", "LOST", "WIN", "VERBAL COMMITMENT", "QUALIFIED"}; private static String[] DIC_COUNTRIES = {"United States", "China", "Japan", "Germany", "France", "United Kingdom", "Brazil", "Italy", "India", "Canada", "Russia", "Spain", "Australia", "Mexico", "South Korea", "Netherlands", "Turkey", "Indonesia", "Switzerland", "Poland", "Belgium", "Sweden", "Saudi Arabia", "Norway"}; private static String[] DIC_PRODUCT = {"PRODUCT 1", "PRODUCT 2", "PRODUCT 3", "PRODUCT 4", "PRODUCT 5", "PRODUCT 6", "PRODUCT 7", "PRODUCT 8", "PRODUCT 8", "PRODUCT 10", "PRODUCT 11"}; private static String[] DIC_SALES_PERSON = {"Roxie Foraker", "Jamie Gilbeau", "Nita Marling", "Darryl Innes", "Julio Burdge", "Neva Hunger", "Kathrine Janas", "Jerri Preble"}; private static String[] DIC_CUSTOMER = {"Company 1", "Company 2", "Company 3", "Company 3", "Company 4", "Company 5", "Company 6", "Company 7", "Company 8", "Company 9"}; private static String[] DIC_SOURCE = {"Customer", "Reference", "Personal contact", "Partner", "Website", "Lead generation", "Event"}; private static double MAX_AMOUNT = 15000; private static double MIN_AMOUNT = 8000; private static double AVG_CLOSING_DAYS = 90; private Random random = new Random(System.currentTimeMillis()); public DataSet buildDataSet(Map params) { int currentYear = Calendar.getInstance().get(Calendar.YEAR); int startYear = currentYear + parseParam(params.get("startYear"), -2); int endYear = currentYear + parseParam(params.get("endYear"), 2); int opportunitiesPerMonth = parseParam(params.get("oppsPerMonth"), 30); DataSetBuilder builder = DataSetFactory.newDataSetBuilder() .number(AMOUNT) .date(CREATION_DATE) .date(CLOSING_DATE) .label(PIPELINE) .label(STATUS) .label(CUSTOMER) .label(COUNTRY) .label(PRODUCT) .label(SALES_PERSON) .number(PROBABILITY) .label(SOURCE) .number(EXPECTED_AMOUNT) .label(COLOR); for (int year = startYear; year <= endYear; year++) { for (int month = 0; month < 12; month++) { for (int i = 0; i < opportunitiesPerMonth; i++) { double amount = MIN_AMOUNT + random.nextDouble() * (MAX_AMOUNT - MIN_AMOUNT); double probability = random.nextDouble() * 100.0; Date creationDate = buildDate(month, year); String color = "GREEN"; if (probability < 25) color = "RED"; else if (probability < 50) color = "GREY"; else if (probability < 75) color = "YELLOW"; builder.row(amount, creationDate, addDates(creationDate, (int) (AVG_CLOSING_DAYS + random.nextDouble() * AVG_CLOSING_DAYS * 0.5)), randomValue(DIC_PIPELINE), randomValue(DIC_STATUS), randomValue(DIC_CUSTOMER), randomValue(DIC_COUNTRIES), randomValue(DIC_PRODUCT), randomValue(DIC_SALES_PERSON), probability, randomValue(DIC_SOURCE), amount * (1 + (random.nextDouble() * ((month*i)%10)/10)), color); } } } return builder.buildDataSet(); } protected int parseParam(String param, int defaultValue) { try { return Integer.parseInt(param); } catch (NumberFormatException e) { return defaultValue; } } private Date buildDate(int month, int year) { Calendar c = Calendar.getInstance(); c.set(Calendar.DAY_OF_MONTH, random.nextInt(28)); // No sales on 29, 30 and 31 ;-) c.set(Calendar.YEAR, year); c.set(Calendar.MONTH, month - 1); // Some genius thought that the first month is 0 c.set(Calendar.HOUR_OF_DAY, random.nextInt(24)); c.set(Calendar.MINUTE, random.nextInt(60)); return c.getTime(); } private Date addDates(Date d, int days) { Calendar c = Calendar.getInstance(); c.setTime(d); c.add(Calendar.DAY_OF_MONTH, days); return c.getTime(); } private String randomValue(String[] dic) { return dic[random.nextInt(dic.length)]; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/backend/command/CommandEvent.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.command; public class CommandEvent { protected String command; public CommandEvent() { } public CommandEvent(String command) { this.command = command; } public String getCommand() { return command; } public void setCommand(String command) { this.command = command; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/backend/command/CommandServer.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.backend.command; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.config.Config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.services.cdi.Startup; /** * This class receives string commands from a TCP socket and transform such commend into CDI event instances * to be consumed by server side components/services. */ @ApplicationScoped @Startup public class CommandServer implements Runnable { private static Logger log = LoggerFactory.getLogger(CommandServer.class); @Inject @Config("10000") private int portNumber; @Inject private Event commandEvent; private Thread serverSocketThread = new Thread(this); @PostConstruct private void init() { serverSocketThread.start(); } public void run() { try { ServerSocket serverSocket = new ServerSocket(portNumber); Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String commandStr; while ((commandStr = in.readLine()) != null) { commandEvent.fire(new CommandEvent(commandStr)); out.println(">>> " + commandStr + " [OK]"); } } catch (Exception e) { log.error("Command server error", e); } } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/ShowcaseEntryPoint.java ================================================ /* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.dashbuilder.client; import javax.annotation.PostConstruct; import javax.inject.Inject; import com.google.gwt.animation.client.Animation; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; import com.google.gwt.user.client.ui.RootPanel; import elemental2.dom.DomGlobal; import org.dashbuilder.client.cms.screen.explorer.NavigationExplorerScreen; import org.dashbuilder.client.dashboard.DashboardManager; import org.dashbuilder.client.navbar.AppHeader; import org.dashbuilder.client.navigation.NavTreeDefinitions; import org.dashbuilder.client.navigation.NavigationManager; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.security.PermissionTreeSetup; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeImpl; import org.jboss.errai.common.client.api.Caller; import org.jboss.errai.ioc.client.api.EntryPoint; import org.jboss.errai.security.shared.service.AuthenticationService; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.ext.security.management.client.ClientUserSystemManager; import org.uberfire.mvp.Command; /** * Entry-point for the Dashbuilder showcase */ @EntryPoint public class ShowcaseEntryPoint { private AppConstants constants = AppConstants.INSTANCE; @Inject private PlaceManager placeManager; @Inject private ClientUserSystemManager userSystemManager; @Inject private DashboardManager dashboardManager; @Inject private Caller authService; @Inject private NavigationManager navigationManager; @Inject NavigationExplorerScreen navigationExplorerScreen; @Inject private PermissionTreeSetup permissionTreeSetup; @Inject private AppHeader appHeader; @PostConstruct public void startApp() { // OPTIONAL: Rename perspectives to dashboards in CMS userSystemManager.waitForInitialization(() -> dashboardManager.loadDashboards(t -> navigationManager.init(() -> { permissionTreeSetup.configureTree(); initNavBar(); initNavigation(); hideLoadingPopup(); }))); } private void initNavBar() { // Show the top menu bar appHeader.setOnLogoutCommand(onLogoutCommand); appHeader.setupMenu(NavTreeDefinitions.NAV_TREE_DEFAULT); } private void initNavigation() { // Set the dashbuilder's default nav tree navigationManager.setDefaultNavTree(NavTreeDefinitions.INITIAL_EMPTY); // Allow links to core perspectives only under the top menu's nav group navigationExplorerScreen.getNavTreeEditor() .setOnlyRuntimePerspectives(NavTreeDefinitions.DASHBOARDS_GROUP, true) .applyToAllChildren(); // Disable perspective context setup under the top menu nav's group navigationExplorerScreen.getNavTreeEditor() .setPerspectiveContextEnabled(NavTreeDefinitions.DASHBOARDS_GROUP, false) .applyToAllChildren(); } // Fade out the "Loading application" pop-up private void hideLoadingPopup() { final Element e = RootPanel.get("loading").getElement(); new Animation() { @Override protected void onUpdate(double progress) { e.getStyle().setOpacity(1.0 - progress); } @Override protected void onComplete() { e.getStyle().setVisibility(Style.Visibility.HIDDEN); } }.run(500); } private Command onLogoutCommand = () -> { authService.call(r -> { final String location = GWT.getModuleBaseURL().replaceFirst("/" + GWT.getModuleName() + "/", "/logout.jsp"); DomGlobal.window.location.assign(location); }).logout(); }; } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/dashboard/DashboardManager.java ================================================ /* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.dashbuilder.client.dashboard; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.shared.dashboard.events.DashboardDeletedEvent; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.jboss.errai.ioc.client.container.SyncBeanManagerImpl; import org.uberfire.client.mvp.Activity; import org.uberfire.client.mvp.ActivityBeansCache; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PerspectiveManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.jsbridge.client.cdi.SingletonBeanDefinition; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.workbench.model.PerspectiveDefinition; import static org.jboss.errai.ioc.client.QualifierUtil.DEFAULT_QUALIFIERS; /** * @deprecated Since version 0.7, dashboards are created from the Content Manager perspective. This class is * still needed in order to deal with old dashboards created from existing installations. */ @ApplicationScoped public class DashboardManager { private SyncBeanManager beanManager; private PlaceManager placeManager; private PerspectiveManager perspectiveManager; private PerspectiveCoordinator perspectiveCoordinator; private ActivityBeansCache activityBeansCache; private Event dashboardDeletedEvent; @Inject public DashboardManager(SyncBeanManager beanManager, PlaceManager placeManager, PerspectiveManager perspectiveManager, PerspectiveCoordinator perspectiveCoordinator, ActivityBeansCache activityBeansCache, Event dashboardDeletedEvent) { this.beanManager = beanManager; this.placeManager = placeManager; this.perspectiveManager = perspectiveManager; this.perspectiveCoordinator = perspectiveCoordinator; this.activityBeansCache = activityBeansCache; this.dashboardDeletedEvent = dashboardDeletedEvent; } public void loadDashboards(ParameterizedCommand> callback) { perspectiveManager.loadPerspectiveStates(new ParameterizedCommand>() { public void execute(Set list) { HashSet dashboards = new HashSet<>(); for (PerspectiveDefinition p : list) { String id = p.getName(); if (id.startsWith("dashboard-")) { dashboards.add(registerPerspective(id)); } } callback.execute(dashboards); } }); } @SuppressWarnings( "unchecked" ) protected DashboardPerspectiveActivity registerPerspective(String id) { DashboardPerspectiveActivity activity = new DashboardPerspectiveActivity(id, this, beanManager, perspectiveManager, placeManager, perspectiveCoordinator); SyncBeanManagerImpl beanManager = (SyncBeanManagerImpl) IOC.getBeanManager(); final SyncBeanDef beanDef = new SingletonBeanDefinition<>(activity, PerspectiveActivity.class, new HashSet( Arrays.asList( DEFAULT_QUALIFIERS ) ), id, true ); beanManager.registerBean( beanDef ); activityBeansCache.addNewPerspectiveActivity(beanManager.lookupBeans(id).iterator().next()); return activity; } public DashboardPerspectiveActivity getDashboardById(String id) { for (DashboardPerspectiveActivity d : getDashboards()) { if (d.getIdentifier().equals(id)) return d; } return null; } public DashboardPerspectiveActivity getDashboardByName(String name) { for (DashboardPerspectiveActivity d : getDashboards()) { if (d.getDisplayName().equals(name)) return d; } return null; } public void removeDashboard(String id) { DashboardPerspectiveActivity activity = getDashboardById(id); if (activity != null) { activity.setPersistent(false); activityBeansCache.removeActivity(id); dashboardDeletedEvent.fire(new DashboardDeletedEvent(activity.getIdentifier(), activity.getDisplayName())); } } public Set getDashboards() { Set activities = new HashSet<>(); for (String activityId : activityBeansCache.getActivitiesById()) { SyncBeanDef activityDef = activityBeansCache.getActivity(activityId); if (activityDef != null && activityDef.getBeanClass().equals(DashboardPerspectiveActivity.class)) { activities.add((DashboardPerspectiveActivity) activityDef.getInstance()); } } return activities; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/dashboard/DashboardPerspectiveActivity.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.dashboard; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.function.Consumer; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.PerspectiveCoordinator; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.displayer.client.widgets.DisplayerEditorPopup; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.ioc.client.container.SyncBeanDef; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.jboss.errai.ioc.client.container.SyncBeanManagerImpl; import org.uberfire.client.mvp.PerspectiveActivity; import org.uberfire.client.mvp.PerspectiveManager; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.workbench.panels.impl.MultiListWorkbenchPanelPresenter; import org.uberfire.ext.widgets.common.client.common.popups.YesNoCancelPopup; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.Menus; import org.uberfire.workbench.model.toolbar.ToolBar; /** * @deprecated Since version 0.7, dashboards are created from the Content Manager perspective. This class is * still needed in order to deal with old dashboards created from existing installations. */ public class DashboardPerspectiveActivity implements PerspectiveActivity { private SyncBeanManager beanManager; private DashboardManager dashboardManager; private PerspectiveManager perspectiveManager; private PlaceManager placeManager; private DisplayerSettingsJSONMarshaller jsonMarshaller = DisplayerSettingsJSONMarshaller.get(); private PerspectiveCoordinator perspectiveCoordinator; private PlaceRequest place; private String id; private boolean persistent; public DashboardPerspectiveActivity() { } public DashboardPerspectiveActivity(String id, DashboardManager dashboardManager, SyncBeanManager beanManager, PerspectiveManager perspectiveManager, PlaceManager placeManager, PerspectiveCoordinator perspectiveCoordinator) { this.id = id; this.beanManager = beanManager; this.persistent = true; this.dashboardManager = dashboardManager; this.perspectiveManager = perspectiveManager; this.placeManager = placeManager; this.perspectiveCoordinator = perspectiveCoordinator; } public String getDisplayName() { return id.substring(10); } @Override public PlaceRequest getPlace() { return place; } @Override public void onStartup(final PlaceRequest place) { this.place = place; } @Override public void onOpen() { } @Override public void onClose() { } @Override public void onShutdown() { } @Override public PerspectiveDefinition getDefaultPerspectiveLayout() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(MultiListWorkbenchPanelPresenter.class.getName()); perspective.setName(id); return perspective; } @Override public String getIdentifier() { return id; } @Override public ResourceType getResourceType() { return ActivityResourceType.PERSPECTIVE; } @Override public boolean isDefault() { return false; } @Override public boolean isTransient() { return !persistent; } @Override public void getMenus(final Consumer menusConsumer) { menusConsumer.accept(MenuFactory .newTopLevelMenu(AppConstants.INSTANCE.dashboard_new_displayer()) .respondsWith(getNewDisplayerCommand()) .endMenu() .newTopLevelMenu(AppConstants.INSTANCE.dashboard_delete_dashboard()) .respondsWith(getShowDeletePopupCommand()) .endMenu().build()); } @Override public ToolBar getToolBar() { return null; } // Internal stuff public boolean isPersistent() { return persistent; } public void setPersistent(boolean persistent) { this.persistent = persistent; } protected YesNoCancelPopup deleteDashboardPopup; private Command getShowDeletePopupCommand() { return new Command() { public void execute() { deleteDashboardPopup = YesNoCancelPopup.newYesNoCancelPopup( AppConstants.INSTANCE.dashboard_delete_popup_title(), AppConstants.INSTANCE.dashboard_delete_popup_content(), getDoDeleteCommand(), getCancelDeleteCommand(), null); deleteDashboardPopup.show(); } }; } private Command getCancelDeleteCommand() { return new Command() { public void execute() { deleteDashboardPopup.hide(); } }; } private Command getDoDeleteCommand() { return new Command() { public void execute() { perspectiveManager.removePerspectiveState(id, new Command() { public void execute() { dashboardManager.removeDashboard(id); placeManager.goTo(getDefaultPerspectiveActivity().getIdentifier()); } }); } }; } private Command getNewDisplayerCommand() { return new Command() { public void execute() { /* Displayer settings == null => Create a brand new displayer */ perspectiveCoordinator.editOn(); DisplayerEditorPopup displayerEditor = beanManager.lookupBean(DisplayerEditorPopup.class).newInstance(); displayerEditor.init(null); displayerEditor.setOnSaveCommand(getSaveDisplayerCommand(displayerEditor)); displayerEditor.setOnCloseCommand(getCloseDisplayerCommand(displayerEditor)); } }; } protected Command getSaveDisplayerCommand(final DisplayerEditorPopup editor) { return new Command() { public void execute() { perspectiveCoordinator.editOff(); beanManager.destroyBean(editor); placeManager.goTo(createPlaceRequest(editor.getDisplayerSettings())); perspectiveManager.savePerspectiveState(new Command() { public void execute() { } }); } }; } protected Command getCloseDisplayerCommand(final DisplayerEditorPopup editor) { return new Command() { public void execute() { perspectiveCoordinator.editOff(); beanManager.destroyBean(editor); } }; } private PlaceRequest createPlaceRequest(DisplayerSettings displayerSettings) { String json = jsonMarshaller.toJsonString(displayerSettings); Map params = new HashMap<>(); params.put("json", json); params.put("edit", "true"); params.put("clone", "true"); return new DefaultPlaceRequest("DisplayerScreen", params); } private PerspectiveActivity getDefaultPerspectiveActivity() { PerspectiveActivity first = null; SyncBeanManagerImpl beanManager = (SyncBeanManagerImpl) IOC.getBeanManager(); Collection> perspectives = beanManager.lookupBeans(PerspectiveActivity.class); Iterator> perspectivesIterator = perspectives.iterator(); while (perspectivesIterator.hasNext() ) { SyncBeanDef perspective = perspectivesIterator.next(); PerspectiveActivity instance = perspective.getInstance(); if (instance.isDefault()) { return instance; } if (first == null) { first = instance; } } return first; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/expenses/ExpenseConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.expenses; public interface ExpenseConstants { String EXPENSES = "expenseReports"; String OFFICE = "office"; String DEPARTMENT = "department"; String EMPLOYEE = "employee"; String AMOUNT = "amount"; String DATE = "date"; } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/expenses/ExpensesDashboard.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.expenses; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.gallery.GalleryWidget; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerCoordinator; import org.dashbuilder.displayer.client.DisplayerLocator; import static org.dashbuilder.dataset.group.DateIntervalType.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.client.expenses.ExpenseConstants.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; /** * A composite widget that represents an entire dashboard sample based on a UI binder template. * The dashboard itself is composed by a set of Displayer instances.

    *

    The data set that feeds this dashboard is a CSV file stored into an specific server folder so * that is auto-deployed during server start up: dashbuilder-webapp/src/main/webapp/datasets/expenseReports.csv

    */ @Dependent public class ExpensesDashboard extends Composite implements GalleryWidget { interface ExpensesDashboardBinder extends UiBinder{} private static final ExpensesDashboardBinder uiBinder = GWT.create(ExpensesDashboardBinder.class); @UiField(provided = true) Displayer pieByOffice; @UiField(provided = true) Displayer barByDepartment; @UiField(provided = true) Displayer lineByDate; @UiField(provided = true) Displayer bubbleByEmployee; @UiField(provided = true) Displayer tableAll; DisplayerCoordinator displayerCoordinator; DisplayerLocator displayerLocator; @Inject public ExpensesDashboard(DisplayerCoordinator displayerCoordinator, DisplayerLocator displayerLocator) { this.displayerCoordinator = displayerCoordinator; this.displayerLocator = displayerLocator; } @Override public String getTitle() { return AppConstants.INSTANCE.expensesdb_title(); } @Override public void onClose() { displayerCoordinator.closeAll(); } @Override public boolean feedsFrom(String dataSetId) { return EXPENSES.equals(dataSetId); } @PostConstruct public void init() { // Create the chart definitions pieByOffice = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newPieChartSettings() .dataset(EXPENSES) .group(OFFICE) .column(OFFICE) .column(AMOUNT, SUM, "sum1") .format(AppConstants.INSTANCE.expensesdb_pie_column1(), "$ #,##0.00") .group(DEPARTMENT) .column(DEPARTMENT) .column(AMOUNT, SUM, "sum2") .format(AppConstants.INSTANCE.expensesdb_pie_column2(), "$ #,##0.00") .group(EMPLOYEE) .column(EMPLOYEE) .column(AMOUNT, SUM, "sum3") .format(AppConstants.INSTANCE.expensesdb_pie_column3(), "$ #,##0.00") .title(AppConstants.INSTANCE.expensesdb_pie_title()) .width(250).height(250) .margins(10, 10, 10, 0) .filterOn(true, true, true) .buildSettings()); barByDepartment = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newBarChartSettings() .dataset(EXPENSES) .group(DEPARTMENT) .column(DEPARTMENT) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.expensesdb_bar_column1(), "$ #,##0.00") .title(AppConstants.INSTANCE.expensesdb_bar_title()) .width(350).height(250) .margins(10, 50, 100, 20) .filterOn(false, true, true) .buildSettings()); bubbleByEmployee = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newBubbleChartSettings() .dataset(EXPENSES) .group(EMPLOYEE) .column(EMPLOYEE) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.expensesdb_bubble_column1(), "$ #,##0.00") .column(AMOUNT, AVERAGE).format(AppConstants.INSTANCE.expensesdb_bubble_column2(), "$ #,##0.00") .column(EMPLOYEE, AppConstants.INSTANCE.expensesdb_bubble_column3()) .column(COUNT, AppConstants.INSTANCE.expensesdb_bubble_column4()) .title(AppConstants.INSTANCE.expensesdb_bubble_title()) .titleVisible(false) .width(600).height(280) .margins(10, 50, 80, 0) .filterOn(false, true, true) .buildSettings()); lineByDate = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newAreaChartSettings() .dataset(EXPENSES) .group(DATE).dynamic(8, DAY_OF_WEEK, true) .column(DATE) .column(AMOUNT, SUM) .format(AppConstants.INSTANCE.expensesdb_line_column1(), "$ #,##0.00") .title(AppConstants.INSTANCE.expensesdb_line_title()) .titleVisible(false) .width(500).height(250) .margins(10, 50, 50, 50) .filterOn(true, true, true) .buildSettings()); tableAll = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(EXPENSES) .title(AppConstants.INSTANCE.expensesdb_table_title()) .titleVisible(false) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .tableColumnPickerEnabled(false) .column(OFFICE).format(AppConstants.INSTANCE.expensesdb_table_column1()) .column(DEPARTMENT).format(AppConstants.INSTANCE.expensesdb_table_column2()) .column(EMPLOYEE).format(AppConstants.INSTANCE.expensesdb_table_column3()) .column(AMOUNT).format(AppConstants.INSTANCE.expensesdb_table_column4(), "$ #,##0.00") .column(DATE).format(AppConstants.INSTANCE.expensesdb_table_column5(), "MMM E dd, yyyy") .filterOn(true, true, true) .tableWidth(600) .buildSettings()); // Make that charts interact among them displayerCoordinator.addDisplayer(pieByOffice); displayerCoordinator.addDisplayer(barByDepartment); displayerCoordinator.addDisplayer(bubbleByEmployee); displayerCoordinator.addDisplayer(lineByDate); displayerCoordinator.addDisplayer(tableAll); // Init the dashboard from the UI Binder template initWidget(uiBinder.createAndBindUi(this)); // Draw the charts displayerCoordinator.drawAll(); } public void redrawAll() { displayerCoordinator.redrawAll(); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/expenses/ExpensesDashboard.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryPlaceRequest.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import org.uberfire.mvp.PlaceRequest; /** * A gallery node holding a PlaceRequest. */ public class GalleryPlaceRequest extends GalleryTreeNode { protected PlaceRequest placeRequest = null; public GalleryPlaceRequest(String name, PlaceRequest placeRequest) { super(name); this.placeRequest = placeRequest; } public PlaceRequest getPlaceRequest() { return placeRequest; } public void setPlaceRequest(PlaceRequest placeRequest) { this.placeRequest = placeRequest; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryTree.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.dashbuilder.renderer.client.DefaultRenderer; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import static org.dashbuilder.dataset.group.DateIntervalType.*; import static org.dashbuilder.dataset.filter.FilterFactory.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.dataset.date.Month.*; import static org.dashbuilder.shared.sales.SalesConstants.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; /** * The Gallery tree. */ @Dependent public class GalleryTree { private List mainNodes = new ArrayList<>(); private DisplayerSettingsJSONMarshaller jsonMarshaller = DisplayerSettingsJSONMarshaller.get(); public List getMainNodes() { return mainNodes; } @PostConstruct private void init() { initBarChartCategory(); initPieChartCategory(); initLineChartCategory(); initAreaChartCategory(); initBubbleChartCategory(); initTableReportCategory(); initMeterChartCategory(); initMetricCategory(); initMapChartCategory(); initSelectorCategory(); initDashboardCategory(); } private PlaceRequest createPlaceRequest(DisplayerSettings displayerSettings) { String json = jsonMarshaller.toJsonString(displayerSettings); Map params = new HashMap<>(); params.put("json", json); params.put("edit", "false"); params.put("showRendererSelector", "true"); return new DefaultPlaceRequest("DisplayerScreen", params); } private PlaceRequest createPlaceRequest(String widgetId) { Map params = new HashMap<>(); params.put("widgetId", widgetId); return new DefaultPlaceRequest("GalleryWidgetScreen", params); } private void initBarChartCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_bar()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_bar_horiz(), createPlaceRequest( DisplayerSettingsFactory.newBarChartSettings() .subType_Bar() .dataset(SALES_OPPS) .group(PRODUCT) .column(PRODUCT, "Product") .column(AMOUNT, SUM) .expression("value/1000") .format(AppConstants.INSTANCE.gallerytree_bar_horiz_column1(), "$ #,### K") .title(AppConstants.INSTANCE.gallerytree_bar_horiz_title()) .width(600).height(400) .resizableOn(1200, 800) .margins(50, 80, 120, 120) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_bar_vert(), createPlaceRequest( DisplayerSettingsFactory.newBarChartSettings() .subType_Column() .dataset(SALES_OPPS) .group(PRODUCT) .column(PRODUCT, "Product") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_bar_vert_column1(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_bar_vert_title()) .set3d(true) .width(600).height(400) .resizableOn(1200, 800) .margins(50, 80, 120, 120) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_bar_multi(), createPlaceRequest( DisplayerSettingsFactory.newBarChartSettings() .subType_Bar() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(AMOUNT, MIN).format(AppConstants.INSTANCE.gallerytree_bar_multi_column1(), "$ #,###") .column(AMOUNT, MAX).format(AppConstants.INSTANCE.gallerytree_bar_multi_column2(), "$ #,###") .column(AMOUNT, AVERAGE).format(AppConstants.INSTANCE.gallerytree_bar_multi_column3(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_bar_multi_title()) .width(700).height(600) .resizableOn(1200, 800) .margins(50, 80, 120, 120) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_bar_stacked(), createPlaceRequest( DisplayerSettingsFactory.newBarChartSettings() .subType_StackedColumn() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(AMOUNT, MIN).format(AppConstants.INSTANCE.gallerytree_bar_multi_column1(), "$ #,###") .column(AMOUNT, MAX).format(AppConstants.INSTANCE.gallerytree_bar_multi_column2(), "$ #,###") .column(AMOUNT, AVERAGE).format(AppConstants.INSTANCE.gallerytree_bar_multi_column3(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_bar_multi_title()) .width(800).height(400) .margins(50, 80, 120, 120) .legendOn("top") .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_bar_vert_dd(), createPlaceRequest( DisplayerSettingsFactory.newBarChartSettings() .subType_Column() .dataset(SALES_OPPS) .group(PIPELINE) .column(PIPELINE, "Pipeline") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_bar_vert_dd_column1(), "$ #,###") .group(STATUS) .column(STATUS, "Status") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_bar_vert_dd_column2(), "$ #,###") .group(SALES_PERSON) .column(SALES_PERSON, "Sales person") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_bar_vert_dd_column3(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_bar_vert_dd_title()) .width(600).height(400) .resizableOn(1200, 800) .margins(50, 80, 120, 120) .filterOn(true, false, false) .buildSettings() ))); } private void initPieChartCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_pie()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_pie_basic(), createPlaceRequest( DisplayerSettingsFactory.newPieChartSettings() .dataset(SALES_OPPS) .group(STATUS) .column(STATUS) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_pie_basic_column1(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_pie_basic_title()) .width(500) .margins(10, 10, 10, 150) .subType_Pie() .legendOn("right") .resizableOn(1200, 800) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_pie_3d(), createPlaceRequest( DisplayerSettingsFactory.newPieChartSettings() .dataset(SALES_OPPS) .group(STATUS) .column(STATUS) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_pie_3d_column1(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_pie_3d_title()) .width(500) .margins(10, 10, 10, 150) .subType_Pie_3d() .legendOn("right") .resizableOn(1200, 800) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_pie_donut(), createPlaceRequest( DisplayerSettingsFactory.newPieChartSettings() .dataset(SALES_OPPS) .group(STATUS) .column(STATUS) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_pie_donut_column1(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_pie_donut_title()) .width(500) .margins(10, 10, 10, 150) .subType_Donut() .legendOn("right") .margins(10, 10, 10, 10) .resizableOn(1200, 800) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_pie_dd(), createPlaceRequest( DisplayerSettingsFactory.newPieChartSettings() .dataset(SALES_OPPS) .group(PIPELINE) .column(PIPELINE, "Pipeline") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_pie_dd_column1(), "$ #,###") .group(STATUS) .column(STATUS, "Status") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_pie_dd_column2(), "$ #,###") .group(SALES_PERSON) .column(SALES_PERSON, "Sales person") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_pie_dd_column3(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_pie_dd_title()) .margins(10, 10, 10, 10) .resizableOn(1200, 800) .filterOn(true, false, false) .buildSettings() ))); } private void initLineChartCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_line()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_line_basic(), createPlaceRequest( DisplayerSettingsFactory.newLineChartSettings() .dataset(SALES_OPPS) .group(CLOSING_DATE).dynamic(12, MONTH, true) .column(CLOSING_DATE).format(AppConstants.INSTANCE.gallerytree_line_basic_column1(), "MMM dd, yyyy") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_line_basic_column2(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_line_basic_title()) .margins(20, 50, 100, 120) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_line_multi(), createPlaceRequest( DisplayerSettingsFactory.newLineChartSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(AMOUNT, MIN).format(AppConstants.INSTANCE.gallerytree_line_multi_column1(), "$ #,###") .column(AMOUNT, MAX).format(AppConstants.INSTANCE.gallerytree_line_multi_column2(), "$ #,###") .column(AMOUNT, AVERAGE).format(AppConstants.INSTANCE.gallerytree_line_multi_column3(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_line_multi_title()) .margins(30, 100, 80, 80) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_line_multi_static(), createPlaceRequest( DisplayerSettingsFactory.newLineChartSettings() .title(AppConstants.INSTANCE.gallerytree_line_multi_static_title()) .margins(20, 80, 50, 120) .column("month", "Month") .column("2014").format(AppConstants.INSTANCE.gallerytree_line_multi_static_column1(), "$ #,###") .column("2015").format(AppConstants.INSTANCE.gallerytree_line_multi_static_column2(), "$ #,###") .column("2016").format(AppConstants.INSTANCE.gallerytree_line_multi_static_column3(), "$ #,###") .dataset(DataSetFactory.newDataSetBuilder() .label("month") .number("2014") .number("2015") .number("2016") .row(JANUARY, 1000d, 2000d, 3000d) .row(FEBRUARY, 1400d, 2300d, 2000d) .row(MARCH, 1300d, 2000d, 1400d) .row(APRIL, 900d, 2100d, 1500d) .row(MAY, 1300d, 2300d, 1600d) .row(JUNE, 1010d, 2000d, 1500d) .row(JULY, 1050d, 2400d, 3000d) .row(AUGUST, 2300d, 2000d, 3200d) .row(SEPTEMBER, 1900d, 2700d, 3000d) .row(OCTOBER, 1200d, 2200d, 3100d) .row(NOVEMBER, 1400d, 2100d, 3100d) .row(DECEMBER, 1100d, 2100d, 4200d) .buildDataSet()) .buildSettings() ))); } private void initAreaChartCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_area()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_area_basic(), createPlaceRequest( DisplayerSettingsFactory.newAreaChartSettings() .dataset(SALES_OPPS) .group(CLOSING_DATE).dynamic(24, MONTH, true) .column(CLOSING_DATE, "Closing date") .column(EXPECTED_AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_area_basic_column1(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_area_basic_title()) .width(700).height(300) .margins(20, 50, 100, 120) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_area_fixed(), createPlaceRequest( DisplayerSettingsFactory.newAreaChartSettings() .dataset(SALES_OPPS) .group(CLOSING_DATE).fixed(MONTH, true).firstMonth(JANUARY).asc() .column(CLOSING_DATE).format(AppConstants.INSTANCE.gallerytree_area_fixed_column1()) .column(EXPECTED_AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_area_fixed_column2(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_area_fixed_title()) .margins(20, 80, 100, 100) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_area_dd(), createPlaceRequest( DisplayerSettingsFactory.newAreaChartSettings() .dataset(SALES_OPPS) .group(CLOSING_DATE).dynamic(12, true) .column(CLOSING_DATE).format(AppConstants.INSTANCE.gallerytree_area_dd_column1()) .column(EXPECTED_AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_area_dd_column2(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_area_dd_title()) .margins(20, 70, 100, 120) .filterOn(true, true, true) .buildSettings() ))); } private void initBubbleChartCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_bubble()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_bubble_basic(), createPlaceRequest( DisplayerSettingsFactory.newBubbleChartSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(COUNT, "#opps").format(AppConstants.INSTANCE.gallerytree_bubble_basic_column1(), "#,###") .column(PROBABILITY, AVERAGE).format(AppConstants.INSTANCE.gallerytree_bubble_basic_column2(), "#,###") .column(COUNTRY, AppConstants.INSTANCE.gallerytree_bubble_basic_column4()) .column(EXPECTED_AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_bubble_basic_column3(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_bubble_basic_title()) .width(700).height(400) .margins(20, 50, 50, 0) .filterOn(false, true, true) .buildSettings() ))); } private void initMeterChartCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_meter()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_meter_basic(), createPlaceRequest( DisplayerSettingsFactory.newMeterChartSettings() .title(AppConstants.INSTANCE.gallerytree_meter_basic_title()) .dataset(SALES_OPPS) .column(AMOUNT, SUM, AppConstants.INSTANCE.gallerytree_meter_basic_column1()) .expression("value/1000") .format(AppConstants.INSTANCE.gallerytree_meter_basic_column1(), "$ #,### K") .width(400).height(200) .meter(0, 15000, 25000, 35000) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_meter_multi(), createPlaceRequest( DisplayerSettingsFactory.newMeterChartSettings() .title(AppConstants.INSTANCE.gallerytree_meter_multi_title()) .dataset(SALES_OPPS) .group(CREATION_DATE).dynamic(12, YEAR, true) .column(CREATION_DATE, "Year") .column(AMOUNT, SUM) .expression("value/1000") .format(AppConstants.INSTANCE.gallerytree_meter_multi_column1(), "$ #,###") .width(600).height(200) .meter(0, 1000, 3000, 5000) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_meter_multi_static(), createPlaceRequest( DisplayerSettingsFactory.newMeterChartSettings() .title(AppConstants.INSTANCE.gallerytree_meter_multi_static_title()) .width(500).height(200) .meter(30, 160, 190, 220) .column("person").format(AppConstants.INSTANCE.gallerytree_meter_multi_static_column1()) .column("heartRate").format(AppConstants.INSTANCE.gallerytree_meter_multi_static_column2(), "#,### bpm") .dataset(DataSetFactory.newDataSetBuilder() .label("person") .number("heartRate") .row("David", 52) .row("Roger", 120) .row("Mark", 74) .row("Michael", 78) .row("Kris", 74) .buildDataSet()) .buildSettings() ))); } private void initMetricCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_metrics()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_metrics_basic(), createPlaceRequest( DisplayerSettingsFactory.newMetricSettings() .title(AppConstants.INSTANCE.gallerytree_metrics_basic_title()) .titleVisible(true) .dataset(SALES_OPPS) .filter(CLOSING_DATE, timeFrame("begin[quarter February] till now")) .column(AMOUNT, SUM).expression("value/1000").format(AppConstants.INSTANCE.gallerytree_metrics_basic_column1(), "$ #,### K") .width(300).height(150) .margins(50, 50, 50, 50) .backgroundColor("FDE8D4") .filterOn(false, false, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_metrics_basic_static(), createPlaceRequest( DisplayerSettingsFactory.newMetricSettings() .title(AppConstants.INSTANCE.gallerytree_metrics_basic_static_title()) .titleVisible(true) .column("tweets").format(AppConstants.INSTANCE.gallerytree_metrics_basic_static_column1(), "#,###") .width(300).height(150) .margins(50, 50, 50, 50) .backgroundColor("ADE8D4") .filterOff(true) .dataset(DataSetFactory.newDataSetBuilder() .number("tweets") .row(54213d) .buildDataSet()) .buildSettings() ))); } private void initMapChartCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_map()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_map_region(), createPlaceRequest( DisplayerSettingsFactory.newMapChartSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_map_region_column1(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_map_region_title()) .subType_Region_Map() .width(700).height(500) .margins(10, 10, 10, 10) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_map_marker(), createPlaceRequest( DisplayerSettingsFactory.newMapChartSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_map_marker_column1(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_map_marker_title()) .subType_Marker_Map() .width(700).height(500) .margins(10, 10, 10, 10) .filterOn(false, true, true) .buildSettings() ))); } private void initTableReportCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_table()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_table_basic(), createPlaceRequest( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .column(COUNTRY, AppConstants.INSTANCE.gallerytree_table_basic_column1()) .column(CUSTOMER, AppConstants.INSTANCE.gallerytree_table_basic_column2()) .column(PRODUCT, AppConstants.INSTANCE.gallerytree_table_basic_column3()) .column(SALES_PERSON, AppConstants.INSTANCE.gallerytree_table_basic_column4()) .column(STATUS, AppConstants.INSTANCE.gallerytree_table_basic_column5()) .column(SOURCE, AppConstants.INSTANCE.gallerytree_table_basic_column6()) .column(CREATION_DATE, AppConstants.INSTANCE.gallerytree_table_basic_column7()) .column(EXPECTED_AMOUNT, AppConstants.INSTANCE.gallerytree_table_basic_column8()) .column(CLOSING_DATE).format(AppConstants.INSTANCE.gallerytree_table_basic_column9(), "MMM dd, yyyy") .column(AMOUNT).format(AppConstants.INSTANCE.gallerytree_table_basic_column10(), "$ #,##0.00") .title(AppConstants.INSTANCE.gallerytree_table_basic_title()) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_table_filtered(), createPlaceRequest( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .column(CUSTOMER, AppConstants.INSTANCE.gallerytree_table_filtered_column1()) .column(PRODUCT, AppConstants.INSTANCE.gallerytree_table_filtered_column2()) .column(STATUS, AppConstants.INSTANCE.gallerytree_table_filtered_column3()) .column(SOURCE, AppConstants.INSTANCE.gallerytree_table_filtered_column4()) .column(CREATION_DATE, AppConstants.INSTANCE.gallerytree_table_filtered_column5()) .column(EXPECTED_AMOUNT).format(AppConstants.INSTANCE.gallerytree_table_filtered_column6(), "$ #,##0.00") .column(CLOSING_DATE).format(AppConstants.INSTANCE.gallerytree_table_filtered_column7(), "MMM dd, yyyy") .column(AMOUNT).format(AppConstants.INSTANCE.gallerytree_table_filtered_column8(), "$ #,##0.00") .filter(COUNTRY, OR(equalsTo("United States"), equalsTo("Brazil"))) .title(AppConstants.INSTANCE.gallerytree_table_filtered_title()) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_table_grouped(), createPlaceRequest( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, AppConstants.INSTANCE.gallerytree_table_grouped_column1()) .column(COUNT, "#Opps").format(AppConstants.INSTANCE.gallerytree_table_grouped_column2(), "#,##0") .column(AMOUNT, MIN).format(AppConstants.INSTANCE.gallerytree_table_grouped_column3(), "$ #,###") .column(AMOUNT, MAX).format(AppConstants.INSTANCE.gallerytree_table_grouped_column4(), "$ #,###") .column(AMOUNT, AVERAGE).format(AppConstants.INSTANCE.gallerytree_table_grouped_column5(), "$ #,###") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.gallerytree_table_grouped_column6(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_table_grouped_title()) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(COUNTRY, DESCENDING) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_table_default_dd(), createPlaceRequest( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .column(COUNTRY, AppConstants.INSTANCE.gallerytree_table_default_dd_column1()) .column(CUSTOMER, AppConstants.INSTANCE.gallerytree_table_default_dd_column2()) .column(PRODUCT, AppConstants.INSTANCE.gallerytree_table_default_dd_column3()) .column(SALES_PERSON, AppConstants.INSTANCE.gallerytree_table_default_dd_column4()) .column(STATUS, AppConstants.INSTANCE.gallerytree_table_default_dd_column5()) .column(SOURCE, AppConstants.INSTANCE.gallerytree_table_default_dd_column6()) .column(CREATION_DATE, AppConstants.INSTANCE.gallerytree_table_default_dd_column7()) .column(EXPECTED_AMOUNT).format(AppConstants.INSTANCE.gallerytree_table_default_dd_column8(), "$ #,###") .column(CLOSING_DATE).format(AppConstants.INSTANCE.gallerytree_table_default_dd_column9(), "MMM dd, yyyy") .column(AMOUNT).format(AppConstants.INSTANCE.gallerytree_table_default_dd_column10(), "$ #,###") .title(AppConstants.INSTANCE.gallerytree_table_default_dd_title()) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .filterOn(true, true, true) .renderer(DefaultRenderer.UUID) .buildSettings() ))); } private void initSelectorCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_selector()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_selector_dropdown(), createPlaceRequest( DisplayerSettingsFactory.newSelectorSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(COUNT, "#Opps").format("#Opps", "#,###") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_bydate_selector_total(), "$ #,##0.00") .sort(COUNTRY, ASCENDING) .title(AppConstants.INSTANCE.gallerytree_selector_dropdown()).titleVisible(true) .subtype(DisplayerSubType.SELECTOR_DROPDOWN) .width(200) .margins(20, 0, 20, 0) .multiple(true) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_selector_labels(), createPlaceRequest( DisplayerSettingsFactory.newSelectorSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(COUNT, "#Opps").format("#Opps", "#,###") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_bydate_selector_total(), "$ #,##0.00") .sort(COUNTRY, ASCENDING) .title(AppConstants.INSTANCE.gallerytree_selector_labels()).titleVisible(true) .subtype(DisplayerSubType.SELECTOR_LABELS) .width(-1) .margins(20, 0, 20, 0) .multiple(true) .filterOn(false, true, true) .buildSettings() ))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_selector_slider(), createPlaceRequest( DisplayerSettingsFactory.newSelectorSettings() .dataset(SALES_OPPS) .title(AppConstants.INSTANCE.gallerytree_selector_slider()).titleVisible(true) .subtype(DisplayerSubType.SELECTOR_SLIDER) .column(CREATION_DATE).format("Creation date", "dd MMM, yyyy") .margins(20, 0, 20, 0) .width(-1) .filterOn(false, true, true) .buildSettings() ))); } private void initDashboardCategory() { GalleryTreeNodeList nodeList = new GalleryTreeNodeList(AppConstants.INSTANCE.gallerytree_db()); mainNodes.add(nodeList); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_db_salesgoals(), createPlaceRequest("salesGoal"))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_db_salespipe(), createPlaceRequest("salesPipeline"))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_db_salespcountry(), createPlaceRequest("salesPerCountry"))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_db_salesreps(), createPlaceRequest("salesReports"))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_db_expreps(), createPlaceRequest("expenseReports"))); nodeList.add(new GalleryPlaceRequest(AppConstants.INSTANCE.gallerytree_db_clustermetrics(), createPlaceRequest("clusterMetrics"))); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryTreeNode.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import java.util.List; /** * Base class for all gallery nodes. */ public abstract class GalleryTreeNode { protected String name = null; protected List children = null; public GalleryTreeNode(String name) { this.name = name; } public String getName() { return name; } public List getChildren() { return children; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryTreeNodeList.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import java.util.ArrayList; /** * A list of gallery nodes. */ public class GalleryTreeNodeList extends GalleryTreeNode { public GalleryTreeNodeList(String name) { super(name); } public void add(GalleryTreeNode node) { if (children == null) children = new ArrayList(); children.add(node); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryTreePresenter.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.dashbuilder.client.resources.i18n.AppConstants; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.PlaceRequest; @WorkbenchScreen(identifier = "GalleryTreeScreen") @Dependent public class GalleryTreePresenter { public interface GalleryTreeView extends UberView { } @Inject GalleryTreeView view; @Inject PlaceManager placeManager; @WorkbenchPartTitle public String getTitle() { return AppConstants.INSTANCE.gallerytree_title(); } @WorkbenchPartView public UberView getView() { return view; } public void navigateToNode(GalleryTreeNode node) { if (node instanceof GalleryPlaceRequest) { PlaceRequest placeRequest = ((GalleryPlaceRequest) node).getPlaceRequest(); placeManager.goTo(placeRequest); } } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryTreeViewImpl.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Inject; import com.google.gwt.dom.client.Style; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HasTreeItems; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Tree; import com.google.gwt.user.client.ui.TreeItem; public class GalleryTreeViewImpl extends Composite implements GalleryTreePresenter.GalleryTreeView { GalleryTreePresenter presenter; @Inject GalleryTree galleryTree; private final SimplePanel mainPanel = new SimplePanel(); public void init(GalleryTreePresenter presenter) { this.presenter = presenter; } @PostConstruct private void initUI() { initWidget(mainPanel); Tree tree = initNavigationTree(); tree.setWidth("150px"); Style leftStyle = mainPanel.getElement().getStyle(); leftStyle.setPropertyPx("margin", 5); mainPanel.add(tree); } private Tree initNavigationTree() { Tree navTree = new Tree(); List mainNodes = galleryTree.getMainNodes(); populateNavigationTree(mainNodes, navTree); navTree.addSelectionHandler(new SelectionHandler() { public void onSelection(SelectionEvent event) { TreeItem ti = event.getSelectedItem(); GalleryTreeNode node = (GalleryTreeNode) ti.getUserObject(); treeItemClicked(ti, node); } }); return navTree; } private void populateNavigationTree(List nodes, HasTreeItems items) { if (nodes == null) return; for (GalleryTreeNode node: nodes) { TreeItem ti = new TreeItem(); ti.setText(node.getName()); ti.setUserObject(node); ti.getElement().getStyle().setCursor(Style.Cursor.POINTER); items.addItem(ti); populateNavigationTree(node.getChildren(), ti); } } private void treeItemClicked(TreeItem ti, GalleryTreeNode node) { presenter.navigateToNode(node); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryWidget.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import com.google.gwt.user.client.ui.IsWidget; public interface GalleryWidget extends IsWidget { String getTitle(); void onClose(); boolean feedsFrom(String dataSetId); void redrawAll(); } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/gallery/GalleryWidgetPresenter.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.gallery; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.client.expenses.ExpensesDashboard; import org.dashbuilder.client.metrics.ClusterMetricsDashboard; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.sales.widgets.SalesDistributionByCountry; import org.dashbuilder.client.sales.widgets.SalesExpectedByDate; import org.dashbuilder.client.sales.widgets.SalesGoals; import org.dashbuilder.client.sales.widgets.SalesTableReports; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.date.TimeAmount; import org.dashbuilder.dataset.def.DataSetDef; import org.dashbuilder.dataset.events.DataSetModifiedEvent; import org.dashbuilder.dataset.events.DataSetPushOkEvent; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.lifecycle.OnClose; import org.uberfire.lifecycle.OnStartup; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.events.NotificationEvent; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.uberfire.workbench.events.NotificationEvent.NotificationType.INFO; @WorkbenchScreen(identifier = "GalleryWidgetScreen") public class GalleryWidgetPresenter { private GalleryWidget widget; private SalesGoals salesGoals; private SalesExpectedByDate salesExpectedByDate; private SalesDistributionByCountry salesDistributionByCountry; private SalesTableReports salesTableReports; private ExpensesDashboard expensesDashboard; private ClusterMetricsDashboard clusterMetricsDashboard; private Event workbenchNotification; @Inject public GalleryWidgetPresenter(SalesGoals salesGoals, SalesExpectedByDate salesExpectedByDate, SalesDistributionByCountry salesDistributionByCountry, SalesTableReports salesTableReports, ExpensesDashboard expensesDashboard, ClusterMetricsDashboard clusterMetricsDashboard, Event workbenchNotification) { this.salesGoals = salesGoals; this.salesExpectedByDate = salesExpectedByDate; this.salesDistributionByCountry = salesDistributionByCountry; this.salesTableReports = salesTableReports; this.expensesDashboard = expensesDashboard; this.clusterMetricsDashboard = clusterMetricsDashboard; this.workbenchNotification = workbenchNotification; } @WorkbenchPartTitle public String getTitle() { return widget.getTitle(); } @WorkbenchPartView public IsWidget getView() { return widget; } @OnStartup public void onStartup(final PlaceRequest placeRequest) { String widgetId = placeRequest.getParameter("widgetId", ""); widget = getWidget(widgetId); } @OnClose public void onClose() { widget.onClose(); } private GalleryWidget getWidget(String widgetId) { if ("salesGoal".equals(widgetId)) { return salesGoals; } if ("salesPipeline".equals(widgetId)) { return salesExpectedByDate; } if ("salesPerCountry".equals(widgetId)) { return salesDistributionByCountry; } if ("salesReports".equals(widgetId)) { return salesTableReports; } if ("expenseReports".equals(widgetId)) { return expensesDashboard; } if ("clusterMetrics".equals(widgetId)) { return clusterMetricsDashboard; } throw new IllegalArgumentException(AppConstants.INSTANCE.gallerywidget_unknown() + widgetId); } // Catch some data set related events and display workbench notifications only and only if: // - The data set refresh is enabled and // - It's refresh rate is greater than 60 seconds (avoid tons of notifications in "real-time" scenarios) private void onDataSetModifiedEvent(@Observes DataSetModifiedEvent event) { checkNotNull("event", event); DataSetDef def = event.getDataSetDef(); String targetUUID = event.getDataSetDef().getUUID(); TimeAmount timeFrame = def.getRefreshTimeAmount(); boolean noRealTime = timeFrame == null || timeFrame.toMillis() > 60000; if ((!def.isRefreshAlways() || noRealTime) && widget != null && widget.feedsFrom(targetUUID)) { workbenchNotification.fire(new NotificationEvent(AppConstants.INSTANCE.gallerywidget_dataset_modif(), INFO)); widget.redrawAll(); } } private void onDataSetPushOkEvent(@Observes DataSetPushOkEvent event) { checkNotNull("event", event); checkNotNull("event", event.getDataSetMetadata()); DataSetMetadata metadata = event.getDataSetMetadata(); DataSetDef def = metadata.getDefinition(); TimeAmount timeFrame = def.getRefreshTimeAmount(); if (timeFrame == null || timeFrame.toMillis() > 60000) { int estimazedSizeKbs = event.getDataSetMetadata().getEstimatedSize() / 1000; workbenchNotification.fire(new NotificationEvent( AppConstants.INSTANCE.gallerywidget_dataset_loaded(def.getProvider().toString(), estimazedSizeKbs), INFO)); } } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/metrics/ClusterMetricsDashboard.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.metrics; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import java.util.Map; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.Callback; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.gallery.GalleryWidget; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.dataset.DataSetBuilder; import org.dashbuilder.displayer.BarChartSettingsBuilder; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsBuilder; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerType; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerCoordinator; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.displayer.impl.BarChartSettingsBuilderImpl; import org.dashbuilder.renderer.client.DefaultRenderer; import org.uberfire.mvp.Command; import static org.dashbuilder.backend.ClusterMetricsGenerator.*; import static org.dashbuilder.dataset.group.DateIntervalType.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; import static org.dashbuilder.dataset.filter.FilterFactory.*; /** * A composite widget that represents an entire dashboard sample composed using an UI binder template. *

    The dashboard itself is composed by a set of Displayer instances.

    */ @Dependent public class ClusterMetricsDashboard extends Composite implements GalleryWidget { public static final String CPU = AppConstants.INSTANCE.metrics_cluster_metricselector_cpu(); public static final String MEMORY = AppConstants.INSTANCE.metrics_cluster_metricselector_mem(); public static final String DISK = AppConstants.INSTANCE.metrics_cluster_metricselector_disk(); public static final String NETWORK = AppConstants.INSTANCE.metrics_cluster_metricselector_netw(); interface Binder extends UiBinder {} private static final Binder uiBinder = GWT.create(Binder.class); @UiField Panel messagePanel; @UiField Panel mainPanel; @UiField Panel leftPanel; @UiField Panel rightPanel; @UiField ListBox metricSelector; @UiField ListBox chartTypeSelector; @UiField Panel metricChartPanel; @UiField(provided = true) Displayer metricsTable; List metricDefList = new ArrayList<>(); Map> metricChartDef = new HashMap<>(); DisplayerCoordinator displayerCoordinator; DisplayerLocator displayerLocator; Displayer currentMetricChart = null; Timer refreshTimer = new Timer() { public void run() { displayerCoordinator.redrawAll( // On success new Command() { public void execute() { refreshTimer.schedule(1000); } }, // On Failure new Command() { public void execute() { } } ); } }; @Inject public ClusterMetricsDashboard(DisplayerCoordinator displayerCoordinator, DisplayerLocator displayerLocator) { this.displayerCoordinator = displayerCoordinator; this.displayerLocator = displayerLocator; } @Override public String getTitle() { return AppConstants.INSTANCE.metrics_cluster_title(); } @Override public void onClose() { displayerCoordinator.closeAll(); refreshTimer.cancel(); } @Override public boolean feedsFrom(String dataSetId) { return "clusterMetrics".equals(dataSetId); } @Override public void redrawAll() { displayerCoordinator.redrawAll(); } class ClusterMetric { String column; String title; String format; String expression; String bgColor; boolean tableVisible; String units; public ClusterMetric(String column, String title, String format, String expression, String bgColor, boolean tableVisible, String units) { this.column = column; this.title = title; this.format = format; this.expression = expression; this.bgColor = bgColor; this.tableVisible = tableVisible; this.units = units; } } @PostConstruct public void init() { // Create the metric definitions metricDefList.add(new ClusterMetric(COLUMN_CPU0, AppConstants.INSTANCE.metrics_cluster_column_cpu(), "#,##0", null, "84ADF4", true, AppConstants.INSTANCE.metrics_cluster_column_cpu_y())); metricDefList.add(new ClusterMetric(COLUMN_DISK_FREE, AppConstants.INSTANCE.metrics_cluster_column_df(), "#,##0 Gb", null, "BCF3EE", false, AppConstants.INSTANCE.metrics_cluster_column_df_y())); metricDefList.add(new ClusterMetric(COLUMN_DISK_USED, AppConstants.INSTANCE.metrics_cluster_column_du(), "#,##0 Gb", null, "BCF3EE", true, AppConstants.INSTANCE.metrics_cluster_column_du_y())); metricDefList.add(new ClusterMetric(COLUMN_MEMORY_FREE, AppConstants.INSTANCE.metrics_cluster_column_memf(), "#,##0.00 Gb", null, "F9AEAF", false, AppConstants.INSTANCE.metrics_cluster_column_memf_y())); metricDefList.add(new ClusterMetric(COLUMN_MEMORY_USED, AppConstants.INSTANCE.metrics_cluster_column_memu(), "#,##0.00 Gb", null, "F9AEAF", true, AppConstants.INSTANCE.metrics_cluster_column_memu_y())); metricDefList.add(new ClusterMetric(COLUMN_PROCESSES_RUNNING, AppConstants.INSTANCE.metrics_cluster_column_procsrn(), "#,##0", null, "A4EEC8", false, AppConstants.INSTANCE.metrics_cluster_column_procsrn_y())); metricDefList.add(new ClusterMetric(COLUMN_PROCESSES_SLEEPING, AppConstants.INSTANCE.metrics_cluster_column_procssl(), "#,##0", null, "A4EEC8", true, AppConstants.INSTANCE.metrics_cluster_column_procssl_y())); metricDefList.add(new ClusterMetric(COLUMN_NETWORK_RX, AppConstants.INSTANCE.metrics_cluster_column_netrx(), "#,##0 Kb/s", null, "F5AC47", false, AppConstants.INSTANCE.metrics_cluster_column_netrx_y())); metricDefList.add(new ClusterMetric(COLUMN_NETWORK_TX, AppConstants.INSTANCE.metrics_cluster_column_nettx(), "#,##0 Kb/s", null, "F5AC47", true, AppConstants.INSTANCE.metrics_cluster_column_nettx_y())); metricChartDef.put(CPU, Arrays.asList(0)); metricChartDef.put(DISK, Arrays.asList(1,2)); metricChartDef.put(MEMORY, Arrays.asList(3,4)); metricChartDef.put(NETWORK, Arrays.asList(7,8)); // Init the metrics table DisplayerSettingsBuilder tableBuilder = DisplayerSettingsFactory.newTableSettings() .renderer(DefaultRenderer.UUID) .tableWidth(700) .tableOrderDefault(COLUMN_SERVER, ASCENDING) .filterOn(true, true, false) .dataset("clusterMetrics") .tableColumnPickerEnabled(false) .filter(COLUMN_TIMESTAMP, timeFrame("now -2second till now")) .group(COLUMN_SERVER) .column(COLUMN_SERVER).format("Server") .column(COLUMN_TIMESTAMP).format(AppConstants.INSTANCE.metrics_cluster_column_time(), "HH:mm:ss"); for (ClusterMetric metric : metricDefList) { if (metric.tableVisible) { tableBuilder.column(metric.column, AVERAGE); tableBuilder.format(metric.title, metric.format); tableBuilder.expression(metric.column, metric.expression); } } metricsTable = displayerLocator.lookupDisplayer(tableBuilder.buildSettings()); displayerCoordinator.addDisplayer(metricsTable); // Init the dashboard from the UI Binder template initWidget(uiBinder.createAndBindUi(this)); mainPanel.getElement().setAttribute("cellpadding", "5"); // Init the box metrics leftPanel.clear(); for (Integer metricIdx : Arrays.asList(0, 1, 3, 5, 7)) { ClusterMetric metric = metricDefList.get(metricIdx); Displayer metricDisplayer = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newMetricSettings() .dataset("clusterMetrics") .filter(COLUMN_TIMESTAMP, timeFrame("now -2second till now")) .column(metric.column, AVERAGE) .expression(metric.expression) .format(metric.title, metric.format) .title(metric.title) .titleVisible(true) .width(200).height(90) .margins(10, 10, 10, 10) .backgroundColor(metric.bgColor) .filterOff(true) .buildSettings()); displayerCoordinator.addDisplayer(metricDisplayer); leftPanel.add(metricDisplayer); } // Init the metric selector metricSelector.clear(); metricSelector.addItem(CPU); metricSelector.addItem(MEMORY); metricSelector.addItem(DISK); metricSelector.addItem(NETWORK); // Init the chart type selector chartTypeSelector.clear(); chartTypeSelector.addItem(AppConstants.INSTANCE.metrics_cluster_chartselector_bar()); chartTypeSelector.addItem(AppConstants.INSTANCE.metrics_cluster_chartselector_line()); chartTypeSelector.addItem(AppConstants.INSTANCE.metrics_cluster_chartselector_area()); // Init the metric chart currentMetricChart = createChartMetric(CPU); metricChartPanel.clear(); metricChartPanel.add(currentMetricChart); displayerCoordinator.addDisplayer(currentMetricChart); // Draw the charts displayerCoordinator.drawAll( // On success new Command() { public void execute() { messagePanel.setVisible(false); mainPanel.setVisible(true); refreshTimer.schedule(1000); } }, // On Failure new Command() { public void execute() { } } ); } protected Displayer createChartMetric(String group) { DisplayerType type = DisplayerType.BARCHART; switch (chartTypeSelector.getSelectedIndex()) { case 1: type = DisplayerType.LINECHART; break; case 2: type = DisplayerType.AREACHART; break; } BarChartSettingsBuilder builder = DisplayerSettingsFactory.newBarChartSettings() .title(group) .titleVisible(false) .width(700).height(200) .margins(30, 5, 60, 10) .legendOff() .filterOff(true) .dataset("clusterMetrics"); if (DisplayerType.BARCHART.equals(type)) { builder.filter(COLUMN_TIMESTAMP, timeFrame("begin[minute] till end[minute]")); builder.group(COLUMN_TIMESTAMP).fixed(SECOND, true); builder.column(COLUMN_TIMESTAMP).format(AppConstants.INSTANCE.metrics_cluster_column_time()); builder.subType_StackedColumn(); } else { builder.filter(COLUMN_TIMESTAMP, timeFrame("-60second till now")); builder.group(COLUMN_TIMESTAMP).dynamic(60, SECOND, true); builder.column(COLUMN_TIMESTAMP).format(AppConstants.INSTANCE.metrics_cluster_column_time()); } List metricIdxs = metricChartDef.get(group); for (Integer metricIdx : metricIdxs) { ClusterMetric metric = metricDefList.get(metricIdx); builder.column(metric.column, AVERAGE); builder.expression(metric.expression); builder.format(metric.title, metric.format); builder.yAxisTitle(metric.units); } DisplayerSettings settings = builder.buildSettings(); settings.setType(type); return displayerLocator.lookupDisplayer(settings); } @UiHandler("chartTypeSelector") public void onChartTypeSelected(ChangeEvent changeEvent) { onMetricSelected(changeEvent); } @UiHandler("metricSelector") public void onMetricSelected(ChangeEvent changeEvent) { // Dispose the current metric chart currentMetricChart.close(); displayerCoordinator.removeDisplayer(currentMetricChart); // Create the metric chart String title = metricSelector.getValue(metricSelector.getSelectedIndex()); currentMetricChart = createChartMetric(title); currentMetricChart.draw(); displayerCoordinator.addDisplayer(currentMetricChart); // Update the dashboard view metricChartPanel.clear(); metricChartPanel.add(currentMetricChart); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/metrics/ClusterMetricsDashboard.ui.xml ================================================ .panel { padding: 5px; } .listBox { width: 150px; } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/navbar/AppHeader.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/navbar/AppHeader.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import elemental2.dom.HTMLDivElement; import jsinterop.base.Js; import org.dashbuilder.client.navigation.NavBarHelper; import org.dashbuilder.client.navigation.NavTreeDefinitions; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.navigation.NavTree; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.views.pfly.menu.UserMenu; import org.uberfire.client.workbench.Header; import org.uberfire.client.workbench.Workbench; import org.uberfire.client.workbench.widgets.menu.megamenu.WorkbenchMegaMenuPresenter; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.Menus; @Templated @ApplicationScoped public class AppHeader implements Header { private AppConstants i18n = AppConstants.INSTANCE; @Inject @DataField HTMLDivElement header; @Inject private WorkbenchMegaMenuPresenter menuBarPresenter; @Inject UserMenu userMenu; @Inject private NavBarHelper navBarHelper; User user; Command onItemSelectedCommand; Command onLogoutCommand; NavTree navTree; String currentPerspectiveId; private Menus userMenus; public AppHeader() {} @Inject public AppHeader(User user) { this.user = user; } @PostConstruct private void init() { header.appendChild(Js.cast(menuBarPresenter.getView().getElement())); userMenu.clear(); userMenu.addMenus(MenuFactory.newTopLevelMenu(i18n.logOut()) .respondsWith(this::onLogoutClicked) .endMenu() .build()); userMenus = MenuFactory.newTopLevelCustomMenu(userMenu).endMenu().build(); } @Override public String getId() { return "AppHeader"; } @Override public int getOrder() { return 2; } public void setOnLogoutCommand(Command command) { this.onLogoutCommand = command; menuBarPresenter.addMenus(userMenus); } public void onLogoutClicked() { if (onLogoutCommand != null) { onLogoutCommand.execute(); } } public void setupMenu(NavTree navTree) { Menus menus = navBarHelper.buildMenusFromNavTree(navTree).build(); menuBarPresenter.clear(); menuBarPresenter.addMenus(menus); menuBarPresenter.addMenus(userMenus); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/navbar/DashbuilderNavBrand.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navbar; import javax.enterprise.context.ApplicationScoped; import org.uberfire.client.workbench.widgets.menu.megamenu.brand.MegaMenuBrand; @ApplicationScoped public class DashbuilderNavBrand implements MegaMenuBrand { @Override public String brandImageUrl() { return "./images/dashbuilder_brand.png"; } @Override public String brandImageLabel() { return "Dashbuilder"; } @Override public String menuAccessorLabel() { return "Menu"; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/navigation/NavTreeDefinitions.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.navigation; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.impl.NavTreeBuilder; import static org.dashbuilder.navigation.workbench.NavWorkbenchCtx.*; import static org.dashbuilder.perspectives.PerspectiveIds.*; /** * Navigation tree definitions such as the top menu bar */ public interface NavTreeDefinitions { String DASHBOARDS_GROUP = "dashboards_group"; String GROUP_APP = "app"; String ENTRY_HOME = "app_home"; String ENTRY_GALLERY = "app_gallery"; String GROUP_ADMIN = "app_admin"; String ENTRY_DATASETS = "app_datasets"; String ENTRY_SECURITY = "app_security"; String ENTRY_CONTENT_MGR = "app_contentMgr"; String GROUP_DASHBOARDS = "app_dashboards"; String ENTRY_SALES_DASHBOARD = "app_salesDashboard"; String ENTRY_SALES_REPORTS = "app_salesReports"; NavTree NAV_TREE_DEFAULT = new NavTreeBuilder() .group(GROUP_APP, "Dashbuilder", "The items displayed by the application's top menu bar", false) .item(ENTRY_HOME, "Home", "The home page", true, perspective(HOME)) .item(ENTRY_GALLERY, "Gallery", "The displayer gallery", true, perspective(GALLERY)) .endGroup() .group(GROUP_ADMIN, "Administration", "The administration tools", false) .item(ENTRY_DATASETS, "Datasets", "The dataset authoring tool", false, perspective(DATA_SETS)) .item(ENTRY_SECURITY, "Security", "The security configuration tool", false, perspective(SECURITY)) .item(ENTRY_CONTENT_MGR, "Content manager", "The content manager tool", false, perspective(CONTENT_MANAGER)) .item(ENTRY_CONTENT_MGR, "Data Transfer", "Allow content transference between installations", false, perspective(DATA_TRANSFER)) .endGroup() .build(); NavTree INITIAL_EMPTY = new NavTreeBuilder() .group(DASHBOARDS_GROUP, "Dashboards", "", true) .endGroup() .build(); } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/perspectives/DisplayerGalleryPerspective.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspectives; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.resources.i18n.AppConstants; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.MultiTabWorkbenchPanelPresenter; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.workbench.model.CompassPosition; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PanelDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; /** * The gallery perspective. */ @ApplicationScoped @WorkbenchPerspective(identifier = "DisplayerGalleryPerspective") public class DisplayerGalleryPerspective { @Perspective public PerspectiveDefinition buildPerspective() { PanelDefinition west = new PanelDefinitionImpl( StaticWorkbenchPanelPresenter.class.getName() ); west.setWidth(200); west.setMinWidth(150); west.addPart("GalleryTreeScreen"); PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(MultiTabWorkbenchPanelPresenter.class.getName()); perspective.setName(AppConstants.INSTANCE.menu_gallery()); perspective.getRoot().insertChild(CompassPosition.WEST, west); perspective.getRoot().addPart("GalleryHomeScreen"); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/perspectives/HomePerspective.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspectives; import org.dashbuilder.client.screens.HomeScreen; import org.dashbuilder.perspectives.PerspectiveIds; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.StaticWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; @WorkbenchPerspective(identifier = PerspectiveIds.HOME, isDefault = true) public class HomePerspective { @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(StaticWorkbenchPanelPresenter.class.getName()); final PlaceRequest place = new DefaultPlaceRequest(HomeScreen.ID); PartDefinitionImpl dashboardScreen = new PartDefinitionImpl(place); perspective.getRoot().addPart(dashboardScreen); perspective.setName("Dashbuilder Home"); return perspective; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/perspectives/SalesDashboardPerspective.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspectives; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.MultiTabWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import static org.dashbuilder.client.sales.SalesOppsDisplayers.*; /** * A sample dashboard perspective */ @ApplicationScoped @WorkbenchPerspective(identifier = "SalesDashboardPerspective") public class SalesDashboardPerspective { DisplayerSettingsJSONMarshaller jsonMarshaller = DisplayerSettingsJSONMarshaller.get(); @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(MultiTabWorkbenchPanelPresenter.class.getName()); perspective.setName(AppConstants.INSTANCE.salesdbpersp_salessummary()); perspective.getRoot().addPart(new PartDefinitionImpl(createPlaceRequest(OPPS_BY_STATUS))); perspective.getRoot().addPart(new PartDefinitionImpl(createPlaceRequest(OPPS_BY_SALESMAN))); perspective.getRoot().addPart(new PartDefinitionImpl(createPlaceRequest(OPPS_BY_PRODUCT))); perspective.getRoot().addPart(new PartDefinitionImpl(createPlaceRequest(OPPS_BY_COUNTRY))); perspective.getRoot().addPart(new PartDefinitionImpl(createPlaceRequest(OPPS_COUNTRY_SUMMARY))); return perspective; } private PlaceRequest createPlaceRequest(DisplayerSettings displayerSettings) { String json = jsonMarshaller.toJsonString(displayerSettings); Map params = new HashMap<>(); params.put("json", json); params.put("edit", "false"); return new DefaultPlaceRequest("DisplayerScreen", params); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/perspectives/SalesReportsPerspective.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.perspectives; import java.util.HashMap; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.json.DisplayerSettingsJSONMarshaller; import org.uberfire.client.annotations.Perspective; import org.uberfire.client.annotations.WorkbenchPerspective; import org.uberfire.client.workbench.panels.impl.MultiTabWorkbenchPanelPresenter; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import static org.dashbuilder.client.sales.SalesOppsDisplayers.*; /** * A sample dashboard perspective */ @ApplicationScoped @WorkbenchPerspective(identifier = "SalesReportsPerspective") public class SalesReportsPerspective { DisplayerSettingsJSONMarshaller jsonMarshaller = DisplayerSettingsJSONMarshaller.get(); @Perspective public PerspectiveDefinition buildPerspective() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl(MultiTabWorkbenchPanelPresenter.class.getName()); perspective.setName(AppConstants.INSTANCE.salesreportspersp_salesreports()); perspective.getRoot().addPart(new PartDefinitionImpl(createPlaceRequest(OPPS_ALLOPPS_LISTING))); perspective.getRoot().addPart(new PartDefinitionImpl(createPlaceRequest(OPPS_COUNTRY_SUMMARY))); return perspective; } private PlaceRequest createPlaceRequest(DisplayerSettings displayerSettings) { String json = jsonMarshaller.toJsonString(displayerSettings); Map params = new HashMap<>(); params.put("json", json); params.put("edit", "false"); return new DefaultPlaceRequest("DisplayerScreen", params); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/resources/AppImages.java ================================================ /* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.resources; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.ImageResource; /** * GWT managed images for Workbench */ public interface AppImages extends ClientBundle { @Source("images/dashbuilder_home_pie.png") ImageResource pieChartLogo(); @Source("images/dashbuilder_gallery_bar.png") ImageResource barChartLogo(); } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/resources/AppResource.java ================================================ package org.dashbuilder.client.resources; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; public interface AppResource extends ClientBundle { AppResource INSTANCE = GWT.create( AppResource.class ); AppImages images(); } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/resources/i18n/AppConstants.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.resources.i18n; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.Messages; public interface AppConstants extends Messages { public static final AppConstants INSTANCE = GWT.create(AppConstants.class); String logoBannerError(); String logOut(); String role(); String menu_home(); String menu_gallery(); String menu_administration(); String menu_security(); String menu_dataset_authoring(); String menu_dashboards(); String menu_dashboards_salesdb(); String menu_dashboards_salesreports(); String menu_dashboards_new(); String menu_content_manager(); String menu_extensions_apps(); String home_intro(); String home_upcoming(); String home_feature1(); String home_feature2(); String home_feature3(); String home_feature4(); String home_feature5(); String home_feature6(); String home_feature7(); String home_feature8(); String home_feature9(); String home_feature10(); String home_feature11(); String home_feature12(); String home_feature13(); String home_arch(); String home_arch1(); String home_arch2(); String home_arch3(); String home_arch4(); String home_arch5(); String home_arch6a(); String home_arch6b(); String home_furtherinfo(); String home_license(); String notification_dashboard_created(String id); String notification_dashboard_deleted(String id); String dashboard_new_displayer(); String dashboard_delete_dashboard(); String dashboard_delete_popup_title(); String dashboard_delete_popup_content(); String salesdbpersp_salessummary(); String salesreportspersp_salesreports(); String expensesdb_title(); String expensesdb_tab_exp_evolution(); String expensesdb_tab_by_employee(); String expensesdb_tab_all_exp(); String expensesdb_pie_title(); String expensesdb_pie_column1(); String expensesdb_pie_column2(); String expensesdb_pie_column3(); String expensesdb_bar_title(); String expensesdb_bar_column1(); String expensesdb_bubble_title(); String expensesdb_bubble_column1(); String expensesdb_bubble_column2(); String expensesdb_bubble_column3(); String expensesdb_bubble_column4(); String expensesdb_line_title(); String expensesdb_line_column1(); String expensesdb_table_title(); String expensesdb_table_column1(); String expensesdb_table_column2(); String expensesdb_table_column3(); String expensesdb_table_column4(); String expensesdb_table_column5(); String gallerytree_home(); String gallerytree_home_p1(); String gallerytree_home_s2a(); String gallerytree_home_s2b(); String gallerytree_home_ghublink(); String gallerytree_title(); String gallerytree_bar(); String gallerytree_bar_horiz(); String gallerytree_bar_horiz_title(); String gallerytree_bar_horiz_column1(); String gallerytree_bar_vert(); String gallerytree_bar_vert_title(); String gallerytree_bar_vert_column1(); String gallerytree_bar_vert_dd(); String gallerytree_bar_vert_dd_title(); String gallerytree_bar_vert_dd_column1(); String gallerytree_bar_vert_dd_column2(); String gallerytree_bar_vert_dd_column3(); String gallerytree_bar_multi(); String gallerytree_bar_stacked(); String gallerytree_bar_multi_title(); String gallerytree_bar_multi_column1(); String gallerytree_bar_multi_column2(); String gallerytree_bar_multi_column3(); String gallerytree_pie(); String gallerytree_pie_basic(); String gallerytree_pie_basic_title(); String gallerytree_pie_basic_column1(); String gallerytree_pie_3d(); String gallerytree_pie_3d_title(); String gallerytree_pie_3d_column1(); String gallerytree_pie_donut(); String gallerytree_pie_donut_title(); String gallerytree_pie_donut_column1(); String gallerytree_pie_dd(); String gallerytree_pie_dd_title(); String gallerytree_pie_dd_column1(); String gallerytree_pie_dd_column2(); String gallerytree_pie_dd_column3(); String gallerytree_line(); String gallerytree_line_basic(); String gallerytree_line_basic_title(); String gallerytree_line_basic_column1(); String gallerytree_line_basic_column2(); String gallerytree_line_multi(); String gallerytree_line_multi_title(); String gallerytree_line_multi_column1(); String gallerytree_line_multi_column2(); String gallerytree_line_multi_column3(); String gallerytree_line_multi_static(); String gallerytree_line_multi_static_title(); String gallerytree_line_multi_static_column1(); String gallerytree_line_multi_static_column2(); String gallerytree_line_multi_static_column3(); String gallerytree_area(); String gallerytree_area_basic(); String gallerytree_area_basic_title(); String gallerytree_area_basic_column1(); String gallerytree_area_fixed(); String gallerytree_area_fixed_title(); String gallerytree_area_fixed_column1(); String gallerytree_area_fixed_column2(); String gallerytree_area_dd(); String gallerytree_area_dd_title(); String gallerytree_area_dd_column1(); String gallerytree_area_dd_column2(); String gallerytree_bubble(); String gallerytree_bubble_basic(); String gallerytree_bubble_basic_title(); String gallerytree_bubble_basic_column1(); String gallerytree_bubble_basic_column2(); String gallerytree_bubble_basic_column3(); String gallerytree_bubble_basic_column4(); String gallerytree_meter(); String gallerytree_meter_basic(); String gallerytree_meter_basic_title(); String gallerytree_meter_basic_column1(); String gallerytree_meter_multi(); String gallerytree_meter_multi_title(); String gallerytree_meter_multi_column1(); String gallerytree_meter_multi_static(); String gallerytree_meter_multi_static_title(); String gallerytree_meter_multi_static_column1(); String gallerytree_meter_multi_static_column2(); String gallerytree_metrics(); String gallerytree_metrics_basic(); String gallerytree_metrics_basic_title(); String gallerytree_metrics_basic_column1(); String gallerytree_metrics_basic_static(); String gallerytree_metrics_basic_static_title(); String gallerytree_metrics_basic_static_column1(); String gallerytree_map(); String gallerytree_map_region(); String gallerytree_map_region_title(); String gallerytree_map_region_column1(); String gallerytree_map_marker(); String gallerytree_map_marker_title(); String gallerytree_map_marker_column1(); String gallerytree_table(); String gallerytree_table_basic(); String gallerytree_table_basic_title(); String gallerytree_table_basic_column1(); String gallerytree_table_basic_column2(); String gallerytree_table_basic_column3(); String gallerytree_table_basic_column4(); String gallerytree_table_basic_column5(); String gallerytree_table_basic_column6(); String gallerytree_table_basic_column7(); String gallerytree_table_basic_column8(); String gallerytree_table_basic_column9(); String gallerytree_table_basic_column10(); String gallerytree_table_filtered(); String gallerytree_table_filtered_title(); String gallerytree_table_filtered_column1(); String gallerytree_table_filtered_column2(); String gallerytree_table_filtered_column3(); String gallerytree_table_filtered_column4(); String gallerytree_table_filtered_column5(); String gallerytree_table_filtered_column6(); String gallerytree_table_filtered_column7(); String gallerytree_table_filtered_column8(); String gallerytree_table_grouped(); String gallerytree_table_grouped_title(); String gallerytree_table_grouped_column1(); String gallerytree_table_grouped_column2(); String gallerytree_table_grouped_column3(); String gallerytree_table_grouped_column4(); String gallerytree_table_grouped_column5(); String gallerytree_table_grouped_column6(); String gallerytree_table_default_dd(); String gallerytree_table_default_dd_title(); String gallerytree_table_default_dd_column1(); String gallerytree_table_default_dd_column2(); String gallerytree_table_default_dd_column3(); String gallerytree_table_default_dd_column4(); String gallerytree_table_default_dd_column5(); String gallerytree_table_default_dd_column6(); String gallerytree_table_default_dd_column7(); String gallerytree_table_default_dd_column8(); String gallerytree_table_default_dd_column9(); String gallerytree_table_default_dd_column10(); String gallerytree_selector(); String gallerytree_selector_dropdown(); String gallerytree_selector_labels(); String gallerytree_selector_slider(); String gallerytree_db(); String gallerytree_db_salesgoals(); String gallerytree_db_salespipe(); String gallerytree_db_salespcountry(); String gallerytree_db_salesreps(); String gallerytree_db_expreps(); String gallerytree_db_clustermetrics(); String gallerywidget_unknown(); String gallerywidget_dataset_modif(); String gallerywidget_dataset_loaded(String type, int size); String metrics_server_detail_title(); String metrics_server_detail_backbutton_tt(); String metrics_server_detail_modebutton_tt_viewtable(); String metrics_server_detail_modebutton_tt_viewcharts(); String metrics_server_detail_lasthour_summary(); String metrics_server_detail_cpu_usage(); String metrics_server_detail_mem_usage(); String metrics_server_detail_netw_usage(); String metrics_server_detail_disk_usage(); String metrics_server_detail_live_procs(); String metrics_server_detail_cpu1_title(); String metrics_server_detail_cpu2_title(); String metrics_server_detail_mem_title(); String metrics_server_detail_netw_title(); String metrics_server_detail_disk_title(); String metrics_server_detail_disk_column1(); String metrics_server_detail_disk_column2(); String metrics_server_detail_procs_running_title(); String metrics_server_detail_procs_running_column1(); String metrics_server_detail_procs_sleeping_title(); String metrics_server_detail_procs_sleeping_column1(); String metrics_server_detail_rt_table_title(String server); String metrics_server_detail_rt_table_column1(); String metrics_server_detail_rt_table_column2(); String metrics_server_detail_rt_table_column3(); String metrics_server_detail_rt_table_column4(); String metrics_server_detail_rt_table_column5(); String metrics_server_detail_rt_table_column6(); String metrics_server_detail_rt_table_column7(); String metrics_server_detail_rt_table_column8(); String metrics_server_detail_rt_table_column9(); String metrics_server_detail_rt_table_column10(); String metrics_server_detail_rt_table_column11(); String metrics_server_vert_title(); String metrics_server_vert_default_tt(); String metrics_server_vert_cpu_tt(); String metrics_server_vert_usedmem_tt(); String metrics_server_vert_netbw_tt(); String metrics_server_vert_procs_tt(); String metrics_server_vert_disk_tt(); String metrics_server_vert_cpu1_title(); String metrics_server_vert_cpu2_title(); String metrics_server_vert_memconsumption_title(); String metrics_server_vert_netbw_title(); String metrics_server_vert_procs_title(); String metrics_server_vert_du_title(); String metrics_server_vert_du_free(); String metrics_server_vert_du_used(); String metrics_server_vert_serverdown(String server); String metrics_cluster_title(); String metrics_cluster_messages_heading(); String metrics_cluster_metricselector_label(); String metrics_cluster_chartselector_label(); String metrics_cluster_metricselector_cpu(); String metrics_cluster_metricselector_mem(); String metrics_cluster_metricselector_disk(); String metrics_cluster_metricselector_netw(); String metrics_cluster_metricselector_proc(); String metrics_cluster_chartselector_bar(); String metrics_cluster_chartselector_line(); String metrics_cluster_chartselector_area(); String metrics_cluster_column_cpu(); String metrics_cluster_column_cpu_y(); String metrics_cluster_column_df(); String metrics_cluster_column_df_y(); String metrics_cluster_column_du(); String metrics_cluster_column_du_y(); String metrics_cluster_column_memf(); String metrics_cluster_column_memf_y(); String metrics_cluster_column_memu(); String metrics_cluster_column_memu_y(); String metrics_cluster_column_procsrn(); String metrics_cluster_column_procsrn_y(); String metrics_cluster_column_procssl(); String metrics_cluster_column_procssl_y(); String metrics_cluster_column_netrx(); String metrics_cluster_column_netrx_y(); String metrics_cluster_column_nettx(); String metrics_cluster_column_nettx_y(); String metrics_cluster_column_time(); String metrics_rt_title(); String metrics_rt_serverup(); String metrics_rt_serverdown(); String sales_bycountry_title(); String sales_bycountry_bubble_title(); String sales_bycountry_bubble_column1(); String sales_bycountry_bubble_column2(); String sales_bycountry_bubble_column3(); String sales_bycountry_map_title(); String sales_bycountry_map_column1(); String sales_bycountry_table_title(); String sales_bycountry_table_column1(); String sales_bycountry_table_column2(); String sales_bycountry_table_column3(); String sales_bycountry_table_column4(); String sales_bycountry_table_column5(); String sales_bycountry_table_column6(); String sales_bycountry_table_column7(); String sales_bycountry_table_column8(); String sales_bycountry_table_column9(); String sales_bydate_title(); String sales_bydate_area_title(); String sales_bydate_area_column1(); String sales_bydate_pie_years_title(); String sales_bydate_pie_years_column1(); String sales_bydate_pie_quarters_title(); String sales_bydate_pie_quarters_column1(); String sales_bydate_bar_weekday_title(); String sales_bydate_bar_weekday_column1(); String sales_bydate_pie_pipe_title(); String sales_bydate_pie_pipe_column1(); String sales_bydate_table_title(); String sales_bydate_table_column1(); String sales_bydate_table_column2(); String sales_bydate_table_column3(); String sales_bydate_table_column4(); String sales_bydate_table_column5(); String sales_bydate_table_column6(); String sales_bydate_table_column7(); String sales_bydate_table_column8(); String sales_bydate_table_column9(); String sales_bydate_selector_total(); String sales_goals_title(); String sales_goals_meter_title(); String sales_goals_meter_column1(); String sales_goals_line_title(); String sales_goals_line_column1(); String sales_goals_line_column2(); String sales_goals_line_column3(); String sales_goals_bar_byproduct_title(); String sales_goals_bar_byproduct_column1(); String sales_goals_bar_byproduct_column2(); String sales_goals_bar_byproduct_column3(); String sales_goals_bar_byempl_title(); String sales_goals_bar_byempl_column1(); String sales_goals_bar_byempl_column2(); String sales_goals_bubble_title(); String sales_goals_bubble_column1(); String sales_goals_bubble_column2(); String sales_goals_bubble_column3(); String sales_tablereports_title(); String sales_tablereports_tab_byyear(); String sales_tablereports_tab_bycountry(); String sales_tablereports_tab_byproduct(); String sales_tablereports_tab_bysalesman(); String sales_tablereports_all_title(); String sales_tablereports_all_column1(); String sales_tablereports_all_column2(); String sales_tablereports_all_column3(); String sales_tablereports_all_column4(); String sales_tablereports_all_column5(); String sales_tablereports_all_column6(); String sales_tablereports_all_column7(); String sales_tablereports_all_column8(); String sales_tablereports_all_column9(); String sales_tablereports_bycountry_title(); String sales_tablereports_bycountry_column1(); String sales_tablereports_bycountry_column2(); String sales_tablereports_bycountry_column3(); String sales_tablereports_bycountry_column4(); String sales_tablereports_bycountry_column5(); String sales_tablereports_bycountry_column6(); String sales_tablereports_byproduct_title(); String sales_tablereports_byproduct_column1(); String sales_tablereports_byproduct_column2(); String sales_tablereports_byproduct_column3(); String sales_tablereports_byproduct_column4(); String sales_tablereports_byproduct_column5(); String sales_tablereports_byproduct_column6(); String sales_tablereports_bysalesman_title(); String sales_tablereports_bysalesman_column1(); String sales_tablereports_bysalesman_column2(); String sales_tablereports_bysalesman_column3(); String sales_tablereports_bysalesman_column4(); String sales_tablereports_bysalesman_column5(); String sales_tablereports_bysalesman_column6(); String sales_tablereports_byyear_title(); String sales_tablereports_byyear_column1(); String sales_tablereports_byyear_column2(); String sales_tablereports_byyear_column3(); String sales_tablereports_byyear_column4(); String sales_tablereports_byyear_column5(); String sales_tablereports_byyear_column6(); String salesopps_displayers_by_pipeline_title(); String salesopps_displayers_by_status_title(); String salesopps_displayers_by_salesman_title(); String salesopps_displayers_by_exp_pipeline_title(); String salesopps_displayers_by_exp_pipeline_column1(); String salesopps_displayers_by_product_title(); String salesopps_displayers_by_product_column1(); String salesopps_displayers_by_country_title(); String salesopps_displayers_by_country_column1(); String salesopps_displayers_country_summary_title(); String salesopps_displayers_country_summary_column1(); String salesopps_displayers_country_summary_column2(); String salesopps_displayers_country_summary_column3(); String salesopps_displayers_country_summary_column4(); String salesopps_displayers_country_summary_column5(); String salesopps_displayers_country_summary_column6(); String salesopps_displayers_all_list_title(); String content_manager_dashboard(); String content_manager_dashboards(); String content_manager_noDashboards(); } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/SalesOppsDisplayers.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.sales; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.DisplayerSettingsFactory; import static org.dashbuilder.shared.sales.SalesConstants.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; /** * A set of displayer definitions for the Sales Dashboard */ public class SalesOppsDisplayers { public static final DisplayerSettings OPPS_BY_PIPELINE = DisplayerSettingsFactory.newPieChartSettings() .uuid("opps-by-pipeline") .dataset(SALES_OPPS) .group(PIPELINE) .column(PIPELINE, "Pipeline") .column(COUNT, "Number of opps") .title(AppConstants.INSTANCE.salesopps_displayers_by_pipeline_title()) .titleVisible(false) .width(500).height(300) .margins(10, 10, 10, 10) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_STATUS = DisplayerSettingsFactory.newPieChartSettings() .uuid("opps-by-status") .dataset(SALES_OPPS) .group(STATUS) .column(STATUS, "Status") .column(AMOUNT, SUM, "Total amount") .title(AppConstants.INSTANCE.salesopps_displayers_by_status_title()) .titleVisible(false) .margins(10, 10, 10, 10) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_SALESMAN = DisplayerSettingsFactory.newPieChartSettings() .uuid("opps-by-salesman") .dataset(SALES_OPPS) .group(SALES_PERSON) .column(SALES_PERSON, "Sales person") .column(AMOUNT, SUM, "Total amount") .title(AppConstants.INSTANCE.salesopps_displayers_by_salesman_title()) .titleVisible(false) .margins(10, 10, 10, 10) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_EXPECTED_PIPELINE = DisplayerSettingsFactory.newAreaChartSettings() .uuid("opps-expected-pipeline") .dataset(SALES_OPPS) .group(CLOSING_DATE).dynamic(24, DateIntervalType.MONTH, true) .column(CLOSING_DATE, "Closing date") .column(EXPECTED_AMOUNT, SUM, AppConstants.INSTANCE.salesopps_displayers_by_exp_pipeline_column1()) .title(AppConstants.INSTANCE.salesopps_displayers_by_exp_pipeline_title()) .titleVisible(false) .width(500).height(300) .margins(20, 50, 100, 100) .filterOn(true, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_PRODUCT = DisplayerSettingsFactory.newBarChartSettings() .subType_Bar() .uuid("opps-by-product") .dataset(SALES_OPPS) .group(PRODUCT) .column(PRODUCT, "Product") .column(AMOUNT, SUM, AppConstants.INSTANCE.salesopps_displayers_by_product_column1()) .title(AppConstants.INSTANCE.salesopps_displayers_by_product_title()) .titleVisible(false) .margins(10, 50, 100, 100) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_BY_COUNTRY = DisplayerSettingsFactory.newBarChartSettings() .subType_Bar() .uuid("opps-by-country") .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(AMOUNT, SUM, AppConstants.INSTANCE.salesopps_displayers_by_country_column1()) .title(AppConstants.INSTANCE.salesopps_displayers_by_country_title()) .titleVisible(false) .margins(10, 80, 100, 100) .filterOn(false, true, true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_COUNTRY_SUMMARY = DisplayerSettingsFactory.newTableSettings() .uuid("opps-country-summary") .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, AppConstants.INSTANCE.salesopps_displayers_country_summary_column1()) .column(AMOUNT, SUM, AppConstants.INSTANCE.salesopps_displayers_country_summary_column2()) .column(COUNT, AppConstants.INSTANCE.salesopps_displayers_country_summary_column3()) .column(AMOUNT, AVERAGE, AppConstants.INSTANCE.salesopps_displayers_country_summary_column4()) .column(AMOUNT, MIN, AppConstants.INSTANCE.salesopps_displayers_country_summary_column5()) .column(AMOUNT, MAX, AppConstants.INSTANCE.salesopps_displayers_country_summary_column6()) .title(AppConstants.INSTANCE.salesopps_displayers_country_summary_title()) .titleVisible(false) .tablePageSize(20) .tableColumnPickerEnabled(false) .filterOff(true) .refreshOn() .buildSettings(); public static final DisplayerSettings OPPS_ALLOPPS_LISTING = DisplayerSettingsFactory.newTableSettings() .uuid("opps-allopps-listing") .dataset(SALES_OPPS) .title(AppConstants.INSTANCE.salesopps_displayers_all_list_title()) .titleVisible(false) .tablePageSize(20) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .tableColumnPickerEnabled(false) .filterOn(true, true, true) .refreshOn() .buildSettings(); } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesDistributionByCountry.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.sales.widgets; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.gallery.GalleryWidget; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerCoordinator; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.renderer.client.DefaultRenderer; import static org.dashbuilder.shared.sales.SalesConstants.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; /** * A composite widget that represents an entire dashboard sample composed using an UI binder template. *

    The dashboard itself is composed by a set of Displayer instances.

    */ @Dependent public class SalesDistributionByCountry extends Composite implements GalleryWidget { interface SalesDashboardBinder extends UiBinder{} private static final SalesDashboardBinder uiBinder = GWT.create(SalesDashboardBinder.class); @UiField(provided = true) Displayer bubbleByCountry; @UiField(provided = true) Displayer mapByCountry; @UiField(provided = true) Displayer tableAll; DisplayerCoordinator displayerCoordinator; DisplayerLocator displayerLocator; @Inject public SalesDistributionByCountry(DisplayerCoordinator displayerCoordinator, DisplayerLocator displayerLocator) { this.displayerCoordinator = displayerCoordinator; this.displayerLocator = displayerLocator; } @Override public String getTitle() { return AppConstants.INSTANCE.sales_bycountry_title(); } @Override public void onClose() { displayerCoordinator.closeAll(); } @Override public boolean feedsFrom(String dataSetId) { return SALES_OPPS.equals(dataSetId); } @Override public void redrawAll() { displayerCoordinator.redrawAll(); } @PostConstruct public void init() { // Create the chart definitions bubbleByCountry = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newBubbleChartSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(COUNT, "count").format(AppConstants.INSTANCE.sales_bycountry_bubble_column1(), "#,##0") .column(PROBABILITY, AVERAGE).format(AppConstants.INSTANCE.sales_bycountry_bubble_column2(), "#,##0") .column(COUNTRY, "Country") .column(EXPECTED_AMOUNT, SUM).expression("value/1000").format(AppConstants.INSTANCE.sales_bycountry_bubble_column3(), "$ #,##0 K") .title(AppConstants.INSTANCE.sales_bycountry_bubble_title()) .width(450).height(300) .margins(20, 50, 50, 0) .filterOn(false, true, true) .buildSettings()); mapByCountry = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newMapChartSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(COUNT, "Number of opportunities") .column(EXPECTED_AMOUNT, SUM).expression("value/1000").format(AppConstants.INSTANCE.sales_bycountry_map_column1(), "$ #,##0 K") .title(AppConstants.INSTANCE.sales_bycountry_map_title()) .width(450).height(290) .margins(10, 10, 10, 10) .filterOn(false, true, true) .buildSettings()); tableAll = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .title(AppConstants.INSTANCE.sales_bycountry_table_title()) .titleVisible(true) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .tableColumnPickerEnabled(false) .column(COUNTRY, AppConstants.INSTANCE.sales_bycountry_table_column1()) .column(CUSTOMER, AppConstants.INSTANCE.sales_bycountry_table_column2()) .column(PRODUCT, AppConstants.INSTANCE.sales_bycountry_table_column3()) .column(SALES_PERSON, AppConstants.INSTANCE.sales_bycountry_table_column4()) .column(STATUS, AppConstants.INSTANCE.sales_bycountry_table_column5()) .column(CREATION_DATE, AppConstants.INSTANCE.sales_bycountry_table_column6()) .column(EXPECTED_AMOUNT, AppConstants.INSTANCE.sales_bycountry_table_column7()) .column(CLOSING_DATE, AppConstants.INSTANCE.sales_bycountry_table_column8()) .column(AMOUNT).expression("value/1000").format(AppConstants.INSTANCE.sales_bycountry_table_column9(), "$ #,##0 K") .filterOn(true, true, true) .tableWidth(900) .renderer(DefaultRenderer.UUID) .buildSettings()); // Make that charts interact among them displayerCoordinator.addDisplayer(bubbleByCountry); displayerCoordinator.addDisplayer(mapByCountry); displayerCoordinator.addDisplayer(tableAll); // Init the dashboard from the UI Binder template initWidget(uiBinder.createAndBindUi(this)); // Draw the charts displayerCoordinator.drawAll(); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesDistributionByCountry.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesExpectedByDate.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.sales.widgets; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.gallery.GalleryWidget; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerSubType; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerCoordinator; import org.dashbuilder.displayer.client.DisplayerLocator; import org.dashbuilder.renderer.client.DefaultRenderer; import static org.dashbuilder.dataset.group.DateIntervalType.*; import static org.dashbuilder.dataset.date.DayOfWeek.*; import static org.dashbuilder.shared.sales.SalesConstants.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; /** * A composite widget that represents an entire dashboard sample composed using an UI binder template. *

    The dashboard itself is composed by a set of Displayer instances.

    */ @Dependent public class SalesExpectedByDate extends Composite implements GalleryWidget { interface SalesDashboardBinder extends UiBinder{} private static final SalesDashboardBinder uiBinder = GWT.create(SalesDashboardBinder.class); @UiField(provided = true) Displayer areaChartByDate; @UiField(provided = true) Displayer pieChartYears; @UiField(provided = true) Displayer pieChartQuarters; @UiField(provided = true) Displayer barChartDayOfWeek; @UiField(provided = true) Displayer pieChartByPipeline; @UiField(provided = true) Displayer tableAll; @UiField(provided = true) Displayer countrySelector; @UiField(provided = true) Displayer customerSelector; @UiField(provided = true) Displayer salesmanSelector; DisplayerCoordinator displayerCoordinator; DisplayerLocator displayerLocator; @Inject public SalesExpectedByDate(DisplayerCoordinator displayerCoordinator, DisplayerLocator displayerLocator) { this.displayerCoordinator = displayerCoordinator; this.displayerLocator = displayerLocator; } @Override public String getTitle() { return AppConstants.INSTANCE.sales_bydate_title(); } @Override public void onClose() { displayerCoordinator.closeAll(); } @Override public boolean feedsFrom(String dataSetId) { return SALES_OPPS.equals(dataSetId); } @Override public void redrawAll() { displayerCoordinator.redrawAll(); } @PostConstruct public void init() { // Create the chart definitions areaChartByDate = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newAreaChartSettings() .dataset(SALES_OPPS) .group(CREATION_DATE).dynamic(30, QUARTER, true) .column(CREATION_DATE, "Creation date") .column(EXPECTED_AMOUNT, SUM).format(AppConstants.INSTANCE.sales_bydate_area_column1(), "$ #,###") .title(AppConstants.INSTANCE.sales_bydate_area_title()) .titleVisible(true) .width(700).height(200) .margins(10, 100, 80, 50) .xAxisAngle(45) .filterOn(true, true, true) .buildSettings()); pieChartYears = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newPieChartSettings() .dataset(SALES_OPPS) .group(CREATION_DATE).dynamic(YEAR, true) .column(CREATION_DATE, "Year") .column(COUNT, "#occs").format(AppConstants.INSTANCE.sales_bydate_pie_years_column1(), "#,###") .title(AppConstants.INSTANCE.sales_bydate_pie_years_title()) .titleVisible(true) .width(200).height(150) .margins(0, 0, 0, 0) .filterOn(false, true, false) .buildSettings()); pieChartQuarters = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newPieChartSettings() .dataset(SALES_OPPS) .group(CREATION_DATE).fixed(QUARTER, true) .column(CREATION_DATE, "Creation date") .column(COUNT, "#occs").format(AppConstants.INSTANCE.sales_bydate_pie_quarters_column1(), "#,###") .title(AppConstants.INSTANCE.sales_bydate_pie_quarters_title()) .titleVisible(true) .width(200).height(150) .margins(0, 0, 0, 0) .filterOn(false, true, false) .buildSettings()); barChartDayOfWeek = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newBarChartSettings() .subType_Bar() .dataset(SALES_OPPS) .group(CREATION_DATE).fixed(DAY_OF_WEEK, true).firstDay(SUNDAY) .column(CREATION_DATE, "Creation date") .column(COUNT, "#occs").format(AppConstants.INSTANCE.sales_bydate_bar_weekday_column1(), "#,###") .title(AppConstants.INSTANCE.sales_bydate_bar_weekday_title()) .titleVisible(true) .width(200).height(150) .margins(0, 20, 80, 10) .filterOn(false, true, true) .buildSettings()); pieChartByPipeline = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newPieChartSettings() .dataset(SALES_OPPS) .group(PIPELINE) .column(PIPELINE, "Pipeline") .column(COUNT, "#opps").format(AppConstants.INSTANCE.sales_bydate_pie_pipe_column1(), "#,###") .title(AppConstants.INSTANCE.sales_bydate_pie_pipe_title()) .titleVisible(true) .width(200).height(150) .margins(0, 0, 0, 0) .filterOn(false, true, true) .buildSettings()); tableAll = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .title(AppConstants.INSTANCE.sales_bydate_title()) .titleVisible(false) .tablePageSize(10) .tableWidth(800) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .tableColumnPickerEnabled(false) .renderer(DefaultRenderer.UUID) .column(COUNTRY, AppConstants.INSTANCE.sales_bydate_table_column1()) .column(CUSTOMER, AppConstants.INSTANCE.sales_bydate_table_column2()) .column(PRODUCT, AppConstants.INSTANCE.sales_bydate_table_column3()) .column(SALES_PERSON, AppConstants.INSTANCE.sales_bydate_table_column4()) .column(STATUS, AppConstants.INSTANCE.sales_bydate_table_column5()) .column(AMOUNT).format(AppConstants.INSTANCE.sales_bydate_table_column6(), "$ #,###") .column(EXPECTED_AMOUNT).format(AppConstants.INSTANCE.sales_bydate_table_column7(), "$ #,###") .column(CREATION_DATE).format(AppConstants.INSTANCE.sales_bydate_table_column8(), "MMM dd, yyyy") .column(CLOSING_DATE).format(AppConstants.INSTANCE.sales_bydate_table_column9(), "MMM dd, yyyy") .filterOn(false, true, true) .buildSettings()); // Create the selectors countrySelector = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newSelectorSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(COUNT, "#Opps").format("#Opps", "#,###") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_bydate_selector_total(), "$ #,##0.00") .sort(COUNTRY, ASCENDING) .subtype(DisplayerSubType.SELECTOR_DROPDOWN) .width(150) .multiple(true) .filterOn(false, true, true) .buildSettings()); salesmanSelector = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newSelectorSettings() .dataset(SALES_OPPS) .group(SALES_PERSON) .column(SALES_PERSON, "Employee") .column(COUNT, "#Opps").format("#Opps", "#,###") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_bydate_selector_total(), "$ #,##0.00") .sort(SALES_PERSON, ASCENDING) .subtype(DisplayerSubType.SELECTOR_DROPDOWN) .width(150) .multiple(true) .filterOn(false, true, true) .buildSettings()); customerSelector = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newSelectorSettings() .dataset(SALES_OPPS) .group(CUSTOMER) .column(CUSTOMER, "Customer") .column(COUNT, "#Opps").format("#Opps", "#,###") .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_bydate_selector_total(), "$ #,##0.00") .sort(CUSTOMER, ASCENDING) .subtype(DisplayerSubType.SELECTOR_DROPDOWN) .width(150) .multiple(true) .filterOn(false, true, true) .buildSettings()); // Make the displayers interact among them displayerCoordinator.addDisplayer(areaChartByDate); displayerCoordinator.addDisplayer(pieChartYears); displayerCoordinator.addDisplayer(pieChartQuarters); displayerCoordinator.addDisplayer(barChartDayOfWeek); displayerCoordinator.addDisplayer(pieChartByPipeline); displayerCoordinator.addDisplayer(tableAll); displayerCoordinator.addDisplayer(countrySelector); displayerCoordinator.addDisplayer(salesmanSelector); displayerCoordinator.addDisplayer(customerSelector); // Init the dashboard from the UI Binder template initWidget(uiBinder.createAndBindUi(this)); // Draw the charts displayerCoordinator.drawAll(); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesExpectedByDate.ui.xml ================================================ .margin { margin: 5px; } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesGoals.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.sales.widgets; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.gallery.GalleryWidget; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerCoordinator; import org.dashbuilder.displayer.client.DisplayerLocator; import static org.dashbuilder.shared.sales.SalesConstants.*; import static org.dashbuilder.dataset.group.DateIntervalType.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; /** * A composite widget that represents an entire dashboard sample composed using an UI binder template. *

    The dashboard itself is composed by a set of Displayer instances.

    */ @Dependent public class SalesGoals extends Composite implements GalleryWidget { interface SalesDashboardBinder extends UiBinder{} private static final SalesDashboardBinder uiBinder = GWT.create(SalesDashboardBinder.class); @UiField(provided = true) Displayer meterChartAmount; @UiField(provided = true) Displayer lineChartByDate; @UiField(provided = true) Displayer barChartByProduct; @UiField(provided = true) Displayer barChartByEmployee; @UiField(provided = true) Displayer bubbleByCountry; DisplayerCoordinator displayerCoordinator; DisplayerLocator displayerLocator; @Inject public SalesGoals(DisplayerCoordinator displayerCoordinator, DisplayerLocator displayerLocator) { this.displayerCoordinator = displayerCoordinator; this.displayerLocator = displayerLocator; // Create the chart definitions meterChartAmount = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newMeterChartSettings() .dataset(SALES_OPPS) .column(AMOUNT, SUM, AppConstants.INSTANCE.sales_goals_meter_column1()) .expression("value/1000") .format(AppConstants.INSTANCE.sales_goals_meter_column1(), "$ #,### K") .title(AppConstants.INSTANCE.sales_goals_meter_title()) .titleVisible(true) .width(200).height(200) .meter(0, 15000, 25000, 35000) .filterOn(false, true, true) .buildSettings()); lineChartByDate = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newLineChartSettings() .dataset(SALES_OPPS) .group(CLOSING_DATE).dynamic(60, MONTH, true) .column(CLOSING_DATE).format(AppConstants.INSTANCE.sales_goals_line_column1()) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_goals_line_column2(), "$ #,### K").expression("value/1000") .column(EXPECTED_AMOUNT, SUM).format(AppConstants.INSTANCE.sales_goals_line_column3(), "$ #,### K").expression("value/1000") .title(AppConstants.INSTANCE.sales_goals_line_title()) .titleVisible(true) .width(800).height(200) .margins(10, 80, 80, 100) .xAxisAngle(30) .filterOn(false, true, true) .buildSettings()); barChartByProduct = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newBarChartSettings() .subType_Column() .dataset(SALES_OPPS) .group(PRODUCT) .column(PRODUCT).format(AppConstants.INSTANCE.sales_goals_bar_byproduct_column1()) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_goals_bar_byproduct_column2(), "$ #,### K").expression("value/1000") .column(EXPECTED_AMOUNT, SUM).format(AppConstants.INSTANCE.sales_goals_bar_byproduct_column3(), "$ #,### K").expression("value/1000") .title(AppConstants.INSTANCE.sales_goals_bar_byproduct_title()) .titleVisible(true) .width(400).height(150) .margins(10, 80, 80, 10) .xAxisAngle(30) .filterOn(false, true, true) .buildSettings()); barChartByEmployee = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newBarChartSettings() .subType_Column() .dataset(SALES_OPPS) .group(SALES_PERSON) .column(SALES_PERSON).format(AppConstants.INSTANCE.sales_goals_bar_byempl_column1()) .column(AMOUNT, SUM).format(AppConstants.INSTANCE.sales_goals_bar_byempl_column2(), "$ #,### K").expression("value/1000") .sort(AMOUNT, DESCENDING) .title(AppConstants.INSTANCE.sales_goals_bar_byempl_title()) .titleVisible(true) .width(400).height(150) .margins(10, 80, 80, 10) .xAxisAngle(30) .filterOn(false, true, true) .buildSettings()); bubbleByCountry = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newBubbleChartSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, "Country") .column(COUNT, "#opps").format(AppConstants.INSTANCE.sales_goals_bubble_column1(), "#,###") .column(PROBABILITY, AVERAGE).format(AppConstants.INSTANCE.sales_goals_bubble_column2(), "#,###") .column(COUNTRY, "Country") .column(EXPECTED_AMOUNT, SUM).expression("value/1000").format(AppConstants.INSTANCE.sales_goals_bubble_column3(), "$ #,##0.00 K") .title(AppConstants.INSTANCE.sales_goals_bubble_title()) .width(550).height(250) .margins(10, 30, 50, 0) .filterOn(false, true, true) .buildSettings()); // Make the charts interact among them displayerCoordinator.addDisplayer(meterChartAmount); displayerCoordinator.addDisplayer(lineChartByDate); displayerCoordinator.addDisplayer(barChartByProduct); displayerCoordinator.addDisplayer(barChartByEmployee); displayerCoordinator.addDisplayer(bubbleByCountry); // Init the dashboard from the UI Binder template initWidget(uiBinder.createAndBindUi(this)); // Draw the charts displayerCoordinator.drawAll(); } @Override public String getTitle() { return AppConstants.INSTANCE.sales_goals_title(); } @Override public void onClose() { displayerCoordinator.closeAll(); } @Override public boolean feedsFrom(String dataSetId) { return SALES_OPPS.equals(dataSetId); } @Override public void redrawAll() { displayerCoordinator.redrawAll(); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesGoals.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesTableReports.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.sales.widgets; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.client.gallery.GalleryWidget; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.client.Displayer; import org.dashbuilder.displayer.client.DisplayerCoordinator; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.displayer.client.DisplayerLocator; import static org.dashbuilder.shared.sales.SalesConstants.*; import static org.dashbuilder.dataset.sort.SortOrder.*; import static org.dashbuilder.dataset.group.AggregateFunctionType.*; /** * A composite widget that represents an entire dashboard sample composed using an UI binder template. *

    The dashboard itself is composed by a set of Displayer instances.

    */ @Dependent public class SalesTableReports extends Composite implements GalleryWidget { interface SalesDashboardBinder extends UiBinder{} private static final SalesDashboardBinder uiBinder = GWT.create(SalesDashboardBinder.class); @UiField(provided = true) Displayer tableByProduct; @UiField(provided = true) Displayer tableBySalesman; @UiField(provided = true) Displayer tableByCountry; @UiField(provided = true) Displayer tableByYear; @UiField(provided = true) Displayer tableAll; DisplayerCoordinator displayerCoordinator; DisplayerLocator displayerLocator; @Inject public SalesTableReports(DisplayerCoordinator displayerCoordinator, DisplayerLocator displayerLocator) { this.displayerCoordinator = displayerCoordinator; this.displayerLocator = displayerLocator; } @Override public String getTitle() { return AppConstants.INSTANCE.sales_tablereports_title(); } @Override public void onClose() { displayerCoordinator.closeAll(); } @Override public boolean feedsFrom(String dataSetId) { return SALES_OPPS.equals(dataSetId); } @Override public void redrawAll() { displayerCoordinator.redrawAll(); } @PostConstruct public void init() { // Create the chart definitions tableAll = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .title(AppConstants.INSTANCE.sales_tablereports_all_title()) .titleVisible(true) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault(AMOUNT, DESCENDING) .tableColumnPickerEnabled(false) .column(COUNTRY, AppConstants.INSTANCE.sales_tablereports_all_column1()) .column(CUSTOMER, AppConstants.INSTANCE.sales_tablereports_all_column2()) .column(PRODUCT, AppConstants.INSTANCE.sales_tablereports_all_column3()) .column(SALES_PERSON, AppConstants.INSTANCE.sales_tablereports_all_column4()) .column(STATUS, AppConstants.INSTANCE.sales_tablereports_all_column5()) .column(CREATION_DATE, AppConstants.INSTANCE.sales_tablereports_all_column6()) .column(EXPECTED_AMOUNT, AppConstants.INSTANCE.sales_tablereports_all_column7()) .column(CLOSING_DATE, AppConstants.INSTANCE.sales_tablereports_all_column8()) .column(AMOUNT, AppConstants.INSTANCE.sales_tablereports_all_column9()) .filterOn(false, true, true) .buildSettings()); tableByCountry = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .group(COUNTRY) .column(COUNTRY, AppConstants.INSTANCE.sales_tablereports_bycountry_column1()) .column(COUNT, AppConstants.INSTANCE.sales_tablereports_bycountry_column2()) .column(AMOUNT, MIN, AppConstants.INSTANCE.sales_tablereports_bycountry_column3()) .column(AMOUNT, MAX, AppConstants.INSTANCE.sales_tablereports_bycountry_column4()) .column(AMOUNT, AVERAGE, AppConstants.INSTANCE.sales_tablereports_bycountry_column5()) .column(AMOUNT, SUM, AppConstants.INSTANCE.sales_tablereports_bycountry_column6()) .title(AppConstants.INSTANCE.sales_tablereports_bycountry_title()) .titleVisible(false) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault("Total", DESCENDING) .tableColumnPickerEnabled(false) .filterOn(false, true, true) .buildSettings()); tableByProduct = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .group(PRODUCT) .column(PRODUCT, AppConstants.INSTANCE.sales_tablereports_byproduct_column1()) .column(COUNT, AppConstants.INSTANCE.sales_tablereports_byproduct_column2()) .column(AMOUNT, MIN, AppConstants.INSTANCE.sales_tablereports_byproduct_column3()) .column(AMOUNT, MAX, AppConstants.INSTANCE.sales_tablereports_byproduct_column4()) .column(AMOUNT, AVERAGE, AppConstants.INSTANCE.sales_tablereports_byproduct_column5()) .column(AMOUNT, SUM, AppConstants.INSTANCE.sales_tablereports_byproduct_column6()) .title(AppConstants.INSTANCE.sales_tablereports_byproduct_title()) .titleVisible(false) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault("Total", DESCENDING) .tableColumnPickerEnabled(false) .filterOn(false, true, true) .buildSettings()); tableBySalesman = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .group(SALES_PERSON) .column(SALES_PERSON, AppConstants.INSTANCE.sales_tablereports_bysalesman_column1()) .column(COUNT, AppConstants.INSTANCE.sales_tablereports_bysalesman_column2()) .column(AMOUNT, MIN, AppConstants.INSTANCE.sales_tablereports_bysalesman_column3()) .column(AMOUNT, MAX, AppConstants.INSTANCE.sales_tablereports_bysalesman_column4()) .column(AMOUNT, AVERAGE, AppConstants.INSTANCE.sales_tablereports_bysalesman_column5()) .column(AMOUNT, SUM, AppConstants.INSTANCE.sales_tablereports_bysalesman_column6()) .title(AppConstants.INSTANCE.sales_tablereports_bysalesman_title()) .titleVisible(false) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault("Total", DESCENDING) .tableColumnPickerEnabled(false) .filterOn(false, true, true) .buildSettings()); tableByYear = displayerLocator.lookupDisplayer( DisplayerSettingsFactory.newTableSettings() .dataset(SALES_OPPS) .group(CREATION_DATE).dynamic(DateIntervalType.YEAR, true) .column(CREATION_DATE, AppConstants.INSTANCE.sales_tablereports_byyear_column1()) .column(COUNT, AppConstants.INSTANCE.sales_tablereports_byyear_column2()) .column(AMOUNT, MIN, AppConstants.INSTANCE.sales_tablereports_byyear_column3()) .column(AMOUNT, MAX, AppConstants.INSTANCE.sales_tablereports_byyear_column4()) .column(AMOUNT, AVERAGE, AppConstants.INSTANCE.sales_tablereports_byyear_column5()) .column(AMOUNT, SUM, AppConstants.INSTANCE.sales_tablereports_byyear_column6()) .title(AppConstants.INSTANCE.sales_tablereports_byyear_title()) .titleVisible(false) .tablePageSize(10) .tableOrderEnabled(true) .tableOrderDefault("Total", DESCENDING) .tableColumnPickerEnabled(false) .filterOn(false, true, true) .buildSettings()); // Make that charts interact among them displayerCoordinator.addDisplayer(tableByCountry); displayerCoordinator.addDisplayer(tableByProduct); displayerCoordinator.addDisplayer(tableBySalesman); displayerCoordinator.addDisplayer(tableByYear); displayerCoordinator.addDisplayer(tableAll); // Init the dashboard from the UI Binder template initWidget(uiBinder.createAndBindUi(this)); // Draw the charts displayerCoordinator.drawAll(); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/sales/widgets/SalesTableReports.ui.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/screens/GalleryHomeScreen.html ================================================

    The gallery contains live examples of all the different displayer types supported in Dashbuilder. The node "Dashboards" contains also a set of examples of how to combine several displayers into full featured end user dashboards.

    All the examples are built using the Dashbuilder's GWT Displayer API. If you are interested in the internals or just want to see how the source code looks then take a look at the following file at GitHub.

    ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/screens/GalleryHomeScreen.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.dom.client.AnchorElement; import com.google.gwt.dom.client.ParagraphElement; import com.google.gwt.dom.client.SpanElement; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Image; import org.dashbuilder.client.resources.AppResource; import org.dashbuilder.client.resources.i18n.AppConstants; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchScreen; @Dependent @Templated @WorkbenchScreen(identifier="GalleryHomeScreen") public class GalleryHomeScreen extends Composite { @Inject @DataField private FlowPanel galleryImagePanel; @Inject @DataField private ParagraphElement paragraph1; @Inject @DataField private SpanElement span2a; @Inject @DataField private SpanElement span2b; @Inject @DataField private AnchorElement gitHubLink; @WorkbenchPartTitle public String getScreenTitle() { return AppConstants.INSTANCE.gallerytree_home(); } @PostConstruct void doLayout() { Image image = new Image(AppResource.INSTANCE.images().barChartLogo()); galleryImagePanel.add(image); paragraph1.setInnerText(AppConstants.INSTANCE.gallerytree_home_p1()); span2a.setInnerText(AppConstants.INSTANCE.gallerytree_home_s2a()); span2b.setInnerText(AppConstants.INSTANCE.gallerytree_home_s2b()); gitHubLink.setInnerText(AppConstants.INSTANCE.gallerytree_home_ghublink()); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/screens/HomeScreen.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import javax.annotation.PostConstruct; import javax.inject.Inject; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.client.mvp.PlaceManager; import org.uberfire.client.mvp.UberElemental; import static org.dashbuilder.perspectives.PerspectiveIds.CONTENT_MANAGER; import static org.dashbuilder.perspectives.PerspectiveIds.DATA_SETS; import static org.dashbuilder.perspectives.PerspectiveIds.DATA_TRANSFER; import static org.dashbuilder.perspectives.PerspectiveIds.GALLERY; @WorkbenchScreen(identifier = HomeScreen.ID) public class HomeScreen { public static final String ID = "HomeScreen"; @Inject View view; @Inject PlaceManager placeManager; public interface View extends UberElemental { } @PostConstruct public void init() { view.init(this); } @WorkbenchPartTitle public String title() { return "Home Screen"; } @WorkbenchPartView public View root() { return view; } public void goToSample() { go(GALLERY); } public void goToDataset() { go(DATA_SETS); } public void goToDesign() { go(CONTENT_MANAGER); } public void goToTransfer() { go(DATA_TRANSFER); } public void go(String perspectiveId) { placeManager.goTo(perspectiveId); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/screens/StaticChartScreen.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import org.dashbuilder.dataset.DataSetFactory; import org.dashbuilder.displayer.DisplayerSettingsFactory; import org.dashbuilder.displayer.DisplayerSettings; import org.dashbuilder.displayer.client.widgets.DisplayerViewer; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.lifecycle.OnStartup; import static org.dashbuilder.dataset.date.Month.*; @WorkbenchScreen(identifier = "StaticChartScreen") public class StaticChartScreen { public static final DisplayerSettings displayerSettings = DisplayerSettingsFactory.newLineChartSettings() .title("Sales Evolution Per Year") .column("month", "Month") .column("2013", "Sales in 2013") .column("2014", "Sales in 2014") .column("2015", "Sales in 2015") .dataset(DataSetFactory.newDataSetBuilder() .label("month") .number("2013") .number("2014") .number("2015") .row(JANUARY, 1000d, 2000d, 3000d) .row(FEBRUARY, 1400d, 2300d, 2000d) .row(MARCH, 1300d, 2000d, 1400d) .row(APRIL, 900d, 2100d, 1500d) .row(MAY, 1300d, 2300d, 1600d) .row(JUNE, 1010d, 2000d, 1500d) .row(JULY, 1050d, 2400d, 3000d) .row(AUGUST, 2300d, 2000d, 3200d) .row(SEPTEMBER, 1900d, 2700d, 3000d) .row(OCTOBER, 1200d, 2200d, 3100d) .row(NOVEMBER, 1400d, 2100d, 3100d) .row(DECEMBER, 1100d, 2100d, 4200d) .buildDataSet()) .buildSettings(); DisplayerViewer displayerViewer; @Inject public StaticChartScreen(DisplayerViewer displayerViewer) { this.displayerViewer = displayerViewer; } @OnStartup public void init() { displayerViewer.init(displayerSettings); displayerViewer.draw(); } @WorkbenchPartTitle public String getTitle() { return "Static Chart"; } @WorkbenchPartView public IsWidget getView() { return displayerViewer; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/screens/view/HomeScreenView.html ================================================

    Welcome to Dashbuilder

    Dashbuilder offers tools to create Business Dashboards. Select a tool below to get started

    Samples

    Explore Dashbuilder Gallery to learn more about data displayers.

    Datasets

    Create and edit source of data that can be used to build dashboards.

    Design

    Build pages with charts and metrics components.

    Data Transfer

    Transfer content between installations.
    ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/screens/view/HomeScreenView.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.screens.view; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.event.dom.client.ClickEvent; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; import org.dashbuilder.client.navigation.resources.i18n.NavigationConstants; import org.dashbuilder.client.resources.i18n.AppConstants; import org.dashbuilder.client.screens.HomeScreen; import org.jboss.errai.ui.shared.api.annotations.DataField; import org.jboss.errai.ui.shared.api.annotations.EventHandler; import org.jboss.errai.ui.shared.api.annotations.Templated; import org.uberfire.client.mvp.PlaceManager; @Dependent @Templated public class HomeScreenView implements HomeScreen.View { private static final AppConstants i18n = AppConstants.INSTANCE; @Inject @DataField HTMLDivElement sampleAction; @Inject @DataField HTMLDivElement datasetsAction; @Inject @DataField HTMLDivElement designAction; @Inject @DataField HTMLDivElement transferAction; @Inject @DataField HTMLDivElement homePage; private HomeScreen presenter; @Override public void init(HomeScreen presenter) { this.presenter = presenter; } @Override public HTMLElement getElement() { return homePage; } @EventHandler("sampleAction") public void onSampleAction(ClickEvent e) { presenter.goToSample(); } @EventHandler("datasetsAction") public void onDatasetsAction(ClickEvent e) { presenter.goToDataset(); } @EventHandler("designAction") public void onDesignAction(ClickEvent e) { presenter.goToDesign(); } @EventHandler("transferAction") public void onTransferAction(ClickEvent e) { presenter.goToTransfer(); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/screens/view/HomeScreenView.less ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @import "/org/uberfire/client/views/static/uberfire-variables.less"; #homePage { height: 100%; .kie-circle-icon--md { font-size: 3em; } .kie-circle-icon--lg { font-size: 4em; } .kie-page { align-items: stretch; display: flex; justify-content: space-between; flex-flow: column nowrap; height: 100%; max-height: 100vh; } .kie-page__content { flex: 1 1 auto; } .kie-page__masthead, .kie-page__footer { flex: 0 0 auto; } .kie-content--bg-image { background-image: url('./images/dashbuilder_home_bg.jpg'); background-color: @color-pf-black-700; background-position: top center; background-size: cover; .blank-slate-pf { background-color: transparent; color: @color-pf-black-300; border: 0; } .kie-circle-icon { background-color: transparent; } } .kie-container-fluid--blank-slate { @media (min-width: @screen-md-min) { width: 100%; background-color: rgba(0, 0, 0, .2); } } .kie-blank-slate { display: flex; @media (min-width: @screen-md-min) { align-items: center; } } .blank-slate-pf-secondary-action { display: flex; flex-direction: column; flex-wrap: wrap; > *:not(:last-child) { margin-bottom: @pf-spacer-lg; } @media (min-width: @screen-md-min) { flex-direction: row; flex-grow: 1; justify-content: center; align-items: stretch; flex-wrap: nowrap; > *:not(:last-child) { margin-bottom: 0; border-right: 1px solid @color-pf-white; } } } .kie-hero-card { height: 210px; display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; padding-top: @pf-spacer-md; & + .kie-hero-card { border-left: 0; } @media (min-width: @screen-md-min) { flex: 0 0 24em; flex-direction: column; flex-wrap: nowrap; justify-content: space-between; align-items: center; padding-left: @pf-spacer-xxxl; padding-right: @pf-spacer-xxxl; } &:hover, &:focus, &:active { .kie-hero-card__icon { background-color: @brand-primary; color: @color-pf-white; } } } .kie-hero-card__icon { margin-right: @pf-spacer-md; .kie-circle-icon--md; @media (min-width: @screen-md-min) { margin-right: 0; .kie-circle-icon--lg; } } .kie-hero-card__text { flex: 3 0; text-align: left; width: 230px; @media (min-width: @screen-md-min) { flex: 1 1 ; text-align: center; } } .kie-hero-card__action { display: flex; flex: 1 1 100%; align-items: center; margin-bottom: @grid-gutter-width; @media (min-width: @screen-xs-min) { flex: 1 1; align-items: flex-end; width: auto; margin-bottom: 0; } @media (min-width: @screen-sm-min) { margin-top: @grid-gutter-width; } } .kie-circle-icon { background-color: @alert-info-bg; display: flex; justify-content: center; align-items: center; font-size: 1.5rem; height: 1.75em; width: 1.75em; border-radius: 50%; &:hover { background-color: @color-pf-black-600; color: @color-pf-white; } } .kie-circle-icon--md { font-size: 3em; } .kie-circle-icon--lg { font-size: 4em; } .kie-hero-card__link { font-weight: bold; } .kie-hero-card__link.disabled { pointer-events: none; font-weight: normal; color: #d1d1d1; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/client/security/PermissionTreeSetup.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.client.security; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.dashbuilder.client.cms.resources.i18n.ContentManagerI18n; import org.dashbuilder.client.resources.i18n.AppConstants; import org.uberfire.client.authz.PerspectiveTreeProvider; import org.uberfire.ext.preferences.client.admin.AdminPagePerspective; import org.uberfire.ext.preferences.client.central.PreferencesCentralPerspective; import static org.dashbuilder.perspectives.PerspectiveIds.*; /** * This is an example of how to customize some of the permission tree nodes. */ @ApplicationScoped public class PermissionTreeSetup { private PerspectiveTreeProvider perspectiveTreeProvider; private AppConstants i18n = AppConstants.INSTANCE; private ContentManagerI18n cmsI18n; public PermissionTreeSetup() { } @Inject public PermissionTreeSetup(PerspectiveTreeProvider perspectiveTreeProvider, ContentManagerI18n cmsI18n) { this.perspectiveTreeProvider = perspectiveTreeProvider; this.cmsI18n = cmsI18n; } public void configureTree() { perspectiveTreeProvider.setPerspectiveName(HOME, i18n.menu_home()); perspectiveTreeProvider.setPerspectiveName(DATA_SETS, i18n.menu_dataset_authoring()); perspectiveTreeProvider.setPerspectiveName(GALLERY, i18n.menu_gallery()); perspectiveTreeProvider.setPerspectiveName(CONTENT_MANAGER, i18n.menu_content_manager()); perspectiveTreeProvider.setPerspectiveName(SECURITY, i18n.menu_security()); perspectiveTreeProvider.setPerspectiveName(SALES_DASHBOARD, i18n.menu_dashboards_salesdb()); perspectiveTreeProvider.setPerspectiveName(SALES_REPORTS, i18n.menu_dashboards_salesreports()); // Exclude some perspectives perspectiveTreeProvider.excludePerspectiveId("StandaloneEditorPerspective"); /* uberfire */ perspectiveTreeProvider.excludePerspectiveId(APPS); /* uberfire */ perspectiveTreeProvider.excludePerspectiveId(PLUGINS); /* uberfire */ perspectiveTreeProvider.excludePerspectiveId(AdminPagePerspective.IDENTIFIER); /* uberfire */ perspectiveTreeProvider.excludePerspectiveId(PreferencesCentralPerspective.IDENTIFIER); /* uberfire */ // Rename perspective to dashboard in CMS //perspectiveTreeProvider.setResourceName(cmsI18n.capitalizeFirst(cmsI18n.getPerspectiveResourceName())); } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/shared/dashboard/events/DashboardDeletedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.dashboard.events; import org.jboss.errai.common.client.api.annotations.Portable; /** * @deprecated Since version 0.7, dashboards are created from the Content Manager perspective. This class is * still needed in order to deal with old dashboards created from existing installations. */ @Portable public class DashboardDeletedEvent { private String dashboardId; private String dashboardName; public DashboardDeletedEvent() { } public DashboardDeletedEvent(String dashboardId, String dashboardName) { this.dashboardId = dashboardId; this.dashboardName = dashboardName; } public String getDashboardId() { return dashboardId; } public String getDashboardName() { return dashboardName; } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/java/org/dashbuilder/shared/sales/SalesConstants.java ================================================ /* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.shared.sales; public interface SalesConstants { String SALES_OPPS = "salesOpportunities"; String AMOUNT = "amount"; String CREATION_DATE = "creationDate"; String CLOSING_DATE = "closingDate"; String PIPELINE = "pipeline"; String STATUS = "status"; String CUSTOMER = "customer"; String COUNTRY = "country"; String PRODUCT = "product"; String SALES_PERSON = "salesPerson"; String PROBABILITY = "probability"; String SOURCE = "source"; String EXPECTED_AMOUNT = "expectedAmount"; String COLOR = "color"; } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/META-INF/ErraiApp.properties ================================================ # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. errai.security.user_on_hostpage_enabled=true errai.marshalling.serializableTypes=org.dashbuilder.dataprovider.StaticProviderType \ org.dashbuilder.dataprovider.BeanProviderType \ org.dashbuilder.dataprovider.CSVProviderType \ org.dashbuilder.dataprovider.SQLProviderType \ org.dashbuilder.dataprovider.PrometheusProviderType \ org.dashbuilder.dataset.ColumnType \ org.dashbuilder.dataset.ColumnType \ org.dashbuilder.dataset.DataSetLookup \ org.dashbuilder.dataset.backend.EditDataSetDef \ org.dashbuilder.dataset.date.DayOfWeek \ org.dashbuilder.dataset.date.Month \ org.dashbuilder.dataset.date.Quarter \ org.dashbuilder.dataset.date.TimeAmount \ org.dashbuilder.dataset.date.TimeFrame \ org.dashbuilder.dataset.date.TimeInstant \ org.dashbuilder.dataset.def.DataSetDef \ org.dashbuilder.dataset.def.BeanDataSetDef \ org.dashbuilder.dataset.def.CSVDataSetDef \ org.dashbuilder.dataset.def.SQLDataSetDef \ org.dashbuilder.dataset.def.SQLDataSourceDef \ org.dashbuilder.dataset.def.StaticDataSetDef \ org.dashbuilder.dataset.def.PrometheusDataSetDef \ org.dashbuilder.dataset.def.DataColumnDef \ org.dashbuilder.dataset.events.DataSetDefModifiedEvent \ org.dashbuilder.dataset.events.DataSetDefRegisteredEvent \ org.dashbuilder.dataset.events.DataSetDefRemovedEvent \ org.dashbuilder.dataset.events.DataSetModifiedEvent \ org.dashbuilder.dataset.events.DataSetPushingEvent \ org.dashbuilder.dataset.events.DataSetPushOkEvent \ org.dashbuilder.dataset.events.DataSetStaleEvent \ org.dashbuilder.dataset.exception.DataSetLookupException \ org.dashbuilder.dataset.filter.CoreFunctionFilter \ org.dashbuilder.dataset.filter.CoreFunctionType \ org.dashbuilder.dataset.filter.DataSetFilter \ org.dashbuilder.dataset.filter.LogicalExprFilter \ org.dashbuilder.dataset.filter.LogicalExprType \ org.dashbuilder.dataset.group.AggregateFunctionType \ org.dashbuilder.dataset.group.ColumnGroup \ org.dashbuilder.dataset.group.DataSetGroup \ org.dashbuilder.dataset.group.DateIntervalType \ org.dashbuilder.dataset.group.GroupFunction \ org.dashbuilder.dataset.group.GroupStrategy \ org.dashbuilder.dataset.group.Interval \ org.dashbuilder.dataset.impl.DataColumnImpl \ org.dashbuilder.dataset.impl.DataSetBuilderImpl \ org.dashbuilder.dataset.impl.DataSetImpl \ org.dashbuilder.dataset.impl.DataSetLookupBuilderImpl \ org.dashbuilder.dataset.impl.DataSetMetadataImpl \ org.dashbuilder.dataset.sort.ColumnSort \ org.dashbuilder.dataset.sort.DataSetSort \ org.dashbuilder.dataset.sort.SortedList ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/META-INF/services/org.uberfire.java.nio.file.spi.FileSystemProvider ================================================ org.uberfire.java.nio.fs.jgit.JGitFileSystemProvider org.uberfire.java.nio.fs.file.SimpleFileSystemProvider ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/app.html.template ================================================ Dashbuilder Showcase
    Please wait
    Loading application...
    ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/application-roles.properties ================================================ admin=admin ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/application-users.properties ================================================ admin=207b6e0cc556d7084b5e2db7d822555c ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/logback.xml ================================================ %d [%t] %-5p %m%n ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/DashbuilderShowcase.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/FastCompiledDashbuilderShowcase.gwt.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # logoBannerError=Failed to load banner. logOut=Log Out role=Role menu_home=Home menu_gallery=Gallery menu_administration=Administration menu_security=Security menu_dataset_authoring=Data Sets menu_content_manager=Content Manager menu_extensions_apps=Apps menu_dashboards=Dashboards menu_dashboards_salesdb=Sales Dashboard menu_dashboards_salesreports=Sales Reports menu_dashboards_new=- New - home_intro=Dashbuilder is a general purpose dashboard and reporting web app which allows for: home_upcoming=Upcoming features home_feature1=Visual configuration and personalization of dashboards home_feature2=Support for different types of visualizations using several charting libraries home_feature3=UI editor for the creation of data sets definitions home_feature4=Full featured editor for the definition of chart visualizations home_feature5=Definition of interactive report tables home_feature6=Data extraction from external systems, through different protocols home_feature7=Support for both analytics and real-time dashboards home_feature8=New renderers based on D3 JS & Lienzo GWT home_feature9=Hierarchical (nested group) displayer types: Tree & Pie home_feature10=Support for multiple data series home_feature11=Rich mobility support home_feature12=Alerts and SLA configuration home_feature13=RESTful API home_arch=Architecture home_arch1=Not tied to any chart rendering technology. Pluggable renderers. home_arch2=No tied to any data storage. home_arch3=Ability to read data from: CSV files, Databases or Java generators. home_arch4=Decoupled client & server layers. Ability to build pure lightweight client dashboards. home_arch5=Ability to push & handle data sets on client for better performance. home_arch6a=Based on home_arch6b=, a framework for building rich workbench styled apps on the web. home_furtherinfo=For further information, please visit the project web site home_license=Licensed under the Apache License, Version 2.0 notification_dashboard_created={0} dashboard created notification_dashboard_deleted={0} dashboard deleted dashboard_new_displayer=New displayer dashboard_delete_popup_title=Delete dashboard dashboard_delete_popup_content=Are you sure you want to delete this dashboard? dashboard_delete_dashboard=Delete dashboard salesdbpersp_salessummary=Sales summary salesreportspersp_salesreports=Sales reports expensesdb_title=Expense reports expensesdb_tab_exp_evolution=Expenses evolution expensesdb_tab_by_employee=By employee expensesdb_tab_all_exp=All expenses expensesdb_pie_title=Expenses by Office expensesdb_pie_column1=Office expensesdb_pie_column2=Department expensesdb_pie_column3=Employee expensesdb_bar_title=Expenses by Department expensesdb_bar_column1=Total Amount expensesdb_bubble_title=Expenses by Employee" expensesdb_bubble_column1=Total expensesdb_bubble_column2=Average expensesdb_bubble_column3=Employee expensesdb_bubble_column4=Number of expense reports expensesdb_line_title=Expenses evolution expensesdb_line_column1=Total Amount expensesdb_table_title=List of expense reports expensesdb_table_column1=Office expensesdb_table_column2=Department expensesdb_table_column3=Employee expensesdb_table_column4=Amount expensesdb_table_column5=Date gallerytree_home=Gallery gallerytree_home_p1=The gallery contains live examples of all the different displayer types supported in Dashbuilder. The node "Dashboards" contains also a set of examples of how to combine several displayers into full featured end user dashboards. gallerytree_home_s2a=All the examples are built using the Dashbuilder's GWT Displayer API. If you're interested in the internals or just want to see how the source code looks then take a look at the following gallerytree_home_s2b=at GitHub. gallerytree_home_ghublink=file gallerytree_title=Gallery Tree gallerytree_bar=Bar Chart gallerytree_bar_horiz=Horizontal gallerytree_bar_horiz_title=By Product gallerytree_bar_horiz_column1=Total amount gallerytree_bar_vert=Vertical gallerytree_bar_vert_title=By Product gallerytree_bar_vert_column1=Total amount gallerytree_bar_vert_dd=Drill-down gallerytree_bar_vert_dd_title=By Pipeline/Status/Sales person gallerytree_bar_vert_dd_column1=Total amount gallerytree_bar_vert_dd_column2=Total amount gallerytree_bar_vert_dd_column3=Total amount gallerytree_bar_multi=Multiple gallerytree_bar_stacked=Stacked gallerytree_bar_multi_title=By Country (min/max/avg) gallerytree_bar_multi_column1=Min gallerytree_bar_multi_column2=Max gallerytree_bar_multi_column3=Avg gallerytree_pie=Pie Chart gallerytree_pie_basic=Basic gallerytree_pie_basic_title=By Status gallerytree_pie_basic_column1=Total amount gallerytree_pie_3d=3d gallerytree_pie_3d_title=By Status gallerytree_pie_3d_column1=Total amount gallerytree_pie_donut=Donut gallerytree_pie_donut_title=By Status gallerytree_pie_donut_column1=Total amount gallerytree_pie_dd=Drill-down gallerytree_pie_dd_title=By Pipeline/Status/Sales person gallerytree_pie_dd_column1=Total amount gallerytree_pie_dd_column2=Total amount gallerytree_pie_dd_column3=Total amount gallerytree_line=Line Chart gallerytree_line_basic=Basic gallerytree_line_basic_title=Sales opportunities evolution gallerytree_line_basic_column1=Closing date gallerytree_line_basic_column2=Total amount gallerytree_line_multi=Multiple gallerytree_line_multi_title=By Country (min/max/avg) gallerytree_line_multi_column1=Min gallerytree_line_multi_column2=Max gallerytree_line_multi_column3=Avg gallerytree_line_multi_static=Multiple (static) gallerytree_line_multi_static_title=Sales Evolution Per Year gallerytree_line_multi_static_column1=Sales in 2014 gallerytree_line_multi_static_column2=Sales in 2015 gallerytree_line_multi_static_column3=Sales in 2016 gallerytree_area=Area Chart gallerytree_area_basic=Basic gallerytree_area_basic_title=Expected Pipeline gallerytree_area_basic_column1=Expected amount gallerytree_area_fixed=Fixed (per month) gallerytree_area_fixed_title=Pipeline (best month) gallerytree_area_fixed_column1=Closing date gallerytree_area_fixed_column2=Expected amount per month gallerytree_area_dd=Drill-down gallerytree_area_dd_title=Expected Pipeline gallerytree_area_dd_column1=Closing date gallerytree_area_dd_column2=Expected amount gallerytree_bubble=Bubble Chart gallerytree_bubble_basic=Basic gallerytree_bubble_basic_title=Opportunities distribution by Country gallerytree_bubble_basic_column1=Number of opportunities gallerytree_bubble_basic_column2=Average probability gallerytree_bubble_basic_column3=Expected amount gallerytree_bubble_basic_column4=Country gallerytree_meter=Meter Chart gallerytree_meter_basic=Basic gallerytree_meter_basic_title=Sales goal gallerytree_meter_basic_column1=Total amount gallerytree_meter_multi=Multiple gallerytree_meter_multi_title=Expected amount per year gallerytree_meter_multi_column1=Total amount gallerytree_meter_multi_static=Multiple (static) gallerytree_meter_multi_static_title=Heart rate gallerytree_meter_multi_static_column1=Person gallerytree_meter_multi_static_column2=Heart rate gallerytree_metrics=Metrics gallerytree_metrics_basic=Basic gallerytree_metrics_basic_title=Sales (current quarter) gallerytree_metrics_basic_column1=Sales (current quarter) gallerytree_metrics_basic_static=Basic (static) gallerytree_metrics_basic_static_title=Tweets! gallerytree_metrics_basic_static_column1=Tweets gallerytree_map=Map gallerytree_map_region=Markers gallerytree_map_region_title=By Country gallerytree_map_region_column1=Total amount gallerytree_map_marker=Regions gallerytree_map_marker_title=By Country gallerytree_map_marker_column1=Total amount gallerytree_table=Table report gallerytree_table_basic=Basic gallerytree_table_basic_title=List of Opportunities gallerytree_table_basic_column1=Country gallerytree_table_basic_column2=Customer gallerytree_table_basic_column3=Product gallerytree_table_basic_column4=Salesman gallerytree_table_basic_column5=Status gallerytree_table_basic_column6=Source gallerytree_table_basic_column7=Creation gallerytree_table_basic_column8=Expected gallerytree_table_basic_column9=Closing gallerytree_table_basic_column10=Amount gallerytree_table_filtered=Filtered gallerytree_table_filtered_title=Opportunities in USA & Brazil gallerytree_table_filtered_column1=Customer gallerytree_table_filtered_column2=Product gallerytree_table_filtered_column3=Status gallerytree_table_filtered_column4=Source gallerytree_table_filtered_column5=Creation gallerytree_table_filtered_column6=Expected gallerytree_table_filtered_column7=Closing gallerytree_table_filtered_column8=Amount gallerytree_table_grouped=Grouped gallerytree_table_grouped_title=Country Summary gallerytree_table_grouped_column1=Country gallerytree_table_grouped_column2=#Opps gallerytree_table_grouped_column3=Min gallerytree_table_grouped_column4=Max gallerytree_table_grouped_column5=Average gallerytree_table_grouped_column6=Total gallerytree_table_default_dd=Default (drill-down) gallerytree_table_default_dd_title=List of Opportunities gallerytree_table_default_dd_column1=Country gallerytree_table_default_dd_column2=Customer gallerytree_table_default_dd_column3=Product gallerytree_table_default_dd_column4=Salesman gallerytree_table_default_dd_column5=Status gallerytree_table_default_dd_column6=Source gallerytree_table_default_dd_column7=Creation gallerytree_table_default_dd_column8=Expected gallerytree_table_default_dd_column9=Closing gallerytree_table_default_dd_column10=Amount gallerytree_selector=Selector gallerytree_selector_dropdown=Drop down gallerytree_selector_labels=Labels gallerytree_selector_slider=Slider gallerytree_db=Dashboards gallerytree_db_salesgoals=Sales goals gallerytree_db_salespipe=Sales pipeline gallerytree_db_salespcountry=Sales per country gallerytree_db_salesreps=Sales reports gallerytree_db_expreps=Expense reports gallerytree_db_clustermetrics=Cluster metrics gallerywidget_unknown=Unknown gallery widget: gallerywidget_dataset_modif=The data set has been modified. Refreshing the view ... gallerywidget_dataset_loaded=Data set loaded from server [{0}, {1} Kb] metrics_server_detail_title=Server metrics (Vertical) metrics_server_detail_backbutton_tt=Go back metrics_server_detail_modebutton_tt_viewtable=View as table metrics_server_detail_modebutton_tt_viewcharts=View as charts metrics_server_detail_lasthour_summary=Last hour summary metrics_server_detail_cpu_usage=CPU usage (%) metrics_server_detail_mem_usage=Memory usage (Gb) metrics_server_detail_netw_usage=Network usage (kbps) metrics_server_detail_disk_usage=Disk usage (Mb) metrics_server_detail_live_procs=Live processes metrics_server_detail_cpu1_title=CPU 1 % metrics_server_detail_cpu2_title=CPU 2 % metrics_server_detail_mem_title=Memory consumption metrics_server_detail_netw_title=Network bandwidth metrics_server_detail_disk_title=Disk usage metrics_server_detail_disk_column1=Free disk space metrics_server_detail_disk_column2=Used disk space metrics_server_detail_procs_running_title=Running processes metrics_server_detail_procs_running_column1=Running metrics_server_detail_procs_sleeping_title=Sleeping processes metrics_server_detail_procs_sleeping_column1=Sleeping metrics_server_detail_rt_table_title=Real-time {0} metrics metrics_server_detail_rt_table_column1=Minute metrics_server_detail_rt_table_column2=CPU0 metrics_server_detail_rt_table_column3=CPU1 metrics_server_detail_rt_table_column4=Used memory (Gb) metrics_server_detail_rt_table_column5=Free memory (Gb) metrics_server_detail_rt_table_column6=Upstream (kbps) metrics_server_detail_rt_table_column7=Downstream (kbps) metrics_server_detail_rt_table_column8=Running processes metrics_server_detail_rt_table_column9=Sleeping processes metrics_server_detail_rt_table_column10=Used disk (Mb) metrics_server_detail_rt_table_column11=Free disk (Mb) metrics_server_vert_title=Server metrics (Vertical) metrics_server_vert_default_tt=Click to show server details metrics_server_vert_cpu_tt=CPU usage (%) metrics_server_vert_usedmem_tt=Used memory (Gb) metrics_server_vert_netbw_tt=Network BW (kbps) metrics_server_vert_procs_tt=Running/Sleeping processes metrics_server_vert_disk_tt=Disk usage (Mb) metrics_server_vert_cpu1_title=CPU 1 % metrics_server_vert_cpu2_title=CPU 2 % metrics_server_vert_memconsumption_title=Memory consumption metrics_server_vert_netbw_title=Network bandwidth metrics_server_vert_procs_title=Running/Sleeping processes metrics_server_vert_du_title=Disk usage metrics_server_vert_du_free=Free disk (Mb) metrics_server_vert_du_used=Used disk (Mb) metrics_server_vert_serverdown={0} is down metrics_cluster_title=Cluster metrics metrics_cluster_messages_heading=Initializing dashboard... metrics_cluster_metricselector_label=Metric metrics_cluster_chartselector_label=Chart type metrics_cluster_metricselector_cpu=CPU % metrics_cluster_metricselector_mem=Memory metrics_cluster_metricselector_disk=Disk metrics_cluster_metricselector_netw=Network metrics_cluster_metricselector_proc=Processes metrics_cluster_chartselector_bar=Bar metrics_cluster_chartselector_line=Line metrics_cluster_chartselector_area=Area metrics_cluster_column_cpu=CPU % metrics_cluster_column_cpu_y=CPU % metrics_cluster_column_df=Disk free metrics_cluster_column_df_y=Gigabytes metrics_cluster_column_du=Disk used metrics_cluster_column_du_y=Gigabytes metrics_cluster_column_memf=Mem. free metrics_cluster_column_memf_y=Gigabytes metrics_cluster_column_memu=Mem. used metrics_cluster_column_memu_y=Gigabytes metrics_cluster_column_procsrn=Proc. running metrics_cluster_column_procsrn_y=Processes metrics_cluster_column_procssl=Proc. sleeping metrics_cluster_column_procssl_y=Processes metrics_cluster_column_netrx=Net. Rx metrics_cluster_column_netrx_y=Kb/s metrics_cluster_column_nettx=Net. Tx metrics_cluster_column_nettx_y=Kb/s metrics_cluster_column_time=Time metrics_rt_title=System Metrics (Real-time) metrics_rt_serverup= is up metrics_rt_serverdown= is down sales_bycountry_title=Sales by country sales_bycountry_bubble_title=Opportunities distribution by Country sales_bycountry_bubble_column1=Number of opportunities sales_bycountry_bubble_column2=Average probability sales_bycountry_bubble_column3=Expected amount sales_bycountry_map_title=By Country sales_bycountry_map_column1=Total amount sales_bycountry_table_title=List of Opportunities sales_bycountry_table_column1=Country sales_bycountry_table_column2=Customer sales_bycountry_table_column3=Product sales_bycountry_table_column4=Salesman sales_bycountry_table_column5=Status sales_bycountry_table_column6=Creation sales_bycountry_table_column7=Expected sales_bycountry_table_column8=Closing sales_bycountry_table_column9=Amount sales_bydate_title=Sales pipeline sales_bydate_area_title=Expected pipeline sales_bydate_area_column1=Amount sales_bydate_pie_years_title=Year sales_bydate_pie_years_column1=Occurrences sales_bydate_pie_quarters_title=Quarter sales_bydate_pie_quarters_column1=Occurrences sales_bydate_bar_weekday_title=Day of week sales_bydate_bar_weekday_column1=Occurrences sales_bydate_pie_pipe_title=Pipeline sales_bydate_pie_pipe_column1=Number of opps sales_bydate_table_title=List of Opportunities sales_bydate_table_column1=Country sales_bydate_table_column2=Customer sales_bydate_table_column3=Product sales_bydate_table_column4=Salesman sales_bydate_table_column5=Status sales_bydate_table_column6=Amount sales_bydate_table_column7=Expected sales_bydate_table_column8=Creation sales_bydate_table_column9=Closing sales_bydate_selector_total=Total sales_goals_title=Sales goals sales_goals_meter_title=Sales goal sales_goals_meter_column1=Total amount sales_goals_line_title=Expected pipeline sales_goals_line_column1=Closing date sales_goals_line_column2=Total amount sales_goals_line_column3=Expected amount sales_goals_bar_byproduct_title=By product sales_goals_bar_byproduct_column1=Product sales_goals_bar_byproduct_column2=Total sales_goals_bar_byproduct_column3=Expected sales_goals_bar_byempl_title=By employee sales_goals_bar_byempl_column1=Employee sales_goals_bar_byempl_column2=Amount sales_goals_bubble_title=Opportunities distribution by Country sales_goals_bubble_column1=Number of opportunities sales_goals_bubble_column2=Average probability sales_goals_bubble_column3=Expected amount sales_tablereports_title=Sales reports sales_tablereports_tab_byyear=By year sales_tablereports_tab_bycountry=By country sales_tablereports_tab_byproduct=By product sales_tablereports_tab_bysalesman=By sales person sales_tablereports_all_title=List of Opportunities sales_tablereports_all_column1=Country sales_tablereports_all_column2=Customer sales_tablereports_all_column3=Product sales_tablereports_all_column4=Salesman sales_tablereports_all_column5=Status sales_tablereports_all_column6=Creation sales_tablereports_all_column7=Expected sales_tablereports_all_column8=Closing sales_tablereports_all_column9=Amount sales_tablereports_bycountry_title=Country summary sales_tablereports_bycountry_column1=Country sales_tablereports_bycountry_column2=#Opps sales_tablereports_bycountry_column3=Min sales_tablereports_bycountry_column4=Max sales_tablereports_bycountry_column5=Average sales_tablereports_bycountry_column6=Total sales_tablereports_byproduct_title=Product summary sales_tablereports_byproduct_column1=Product sales_tablereports_byproduct_column2=#Opps sales_tablereports_byproduct_column3=Min sales_tablereports_byproduct_column4=Max sales_tablereports_byproduct_column5=Average sales_tablereports_byproduct_column6=Total sales_tablereports_bysalesman_title=Sales by person sales_tablereports_bysalesman_column1=Sales person sales_tablereports_bysalesman_column2=#Opps sales_tablereports_bysalesman_column3=Min sales_tablereports_bysalesman_column4=Max sales_tablereports_bysalesman_column5=Average sales_tablereports_bysalesman_column6=Total sales_tablereports_byyear_title=Year summary sales_tablereports_byyear_column1=Creation date sales_tablereports_byyear_column2=#Opps sales_tablereports_byyear_column3=Min sales_tablereports_byyear_column4=Max sales_tablereports_byyear_column5=Average sales_tablereports_byyear_column6=Total salesopps_displayers_by_pipeline_title=Pipeline status salesopps_displayers_by_status_title=By Status salesopps_displayers_by_salesman_title=By Sales Person salesopps_displayers_by_exp_pipeline_title=Expected Amount salesopps_displayers_by_exp_pipeline_column1=Expected amount salesopps_displayers_by_product_title=By Product salesopps_displayers_by_product_column1=Total amount salesopps_displayers_by_country_title=By Country salesopps_displayers_by_country_column1=Total amount salesopps_displayers_country_summary_title=Country Summary salesopps_displayers_country_summary_column1=COUNTRY salesopps_displayers_country_summary_column2=TOTAL salesopps_displayers_country_summary_column3=NUMBER salesopps_displayers_country_summary_column4=AVERAGE salesopps_displayers_country_summary_column5=MIN salesopps_displayers_country_summary_column6=MAX salesopps_displayers_all_list_title=List of Opportunities content_manager_dashboard=dashboard content_manager_dashboards=dashboards content_manager_noDashboards=No dashboards HomeScreenView.title=Welcome to Dashbuilder HomeScreenView.subTitle=Dashbuilder offers tools to create Business Dashboards. Select a tool below to get started ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_de.properties ================================================ logoBannerError=Banner konnte nicht geladen werden logOut=Abmelden role=Rolle menu_home=Home menu_gallery=Galerie menu_extensions_apps=Apps menu_dashboards=Dashboards menu_dashboards_salesdb=Verkaufs-Dashboard menu_dashboards_salesreports=Verkaufsberichte menu_dashboards_new=- Neu - home_intro=Der Dashbuilder ist ein Dashboard für allgemeine Zwecke und gleichzeitig eine Web-App für Berichterstattung, die Folgendes ermöglicht\: home_upcoming=Anstehende Features home_feature1=Visuelle Konfiguration und persönliche Anpassung von Dashboards home_feature2=Support für verschiedene Visualisierungstypen unter Verwendung verschiedener Bibliotheken zur Diagrammerstellung home_feature3=UI Editor zur Erstellung von Datensatz-Definitionen home_feature4=Vollfunktionaler Editor zur Definition von Diagramm-Visualisierungen home_feature5=Definition interaktiver Bericht-Tabellen home_feature6=Datengewinnung aus externen Systemen über verschiedene Protokolle home_feature7=Support für analytische und Echtzeit-Dashboards home_feature8=Neue Renderers basierend auf D3 JS & Lienzo GWT home_feature9=Hierarchische (verschachtelte Gruppen) Displayer-Typen\: Baum & Kreis home_feature10=Support für mehrere Datenserien home_feature11=Umfassender Mobility Support home_feature12=Warnungen und SLA-Konfiguration home_feature13=RESTful API home_arch=Architektur home_arch1=An keine Technologie zur Diagramm-Erstellung gebunden. Austauschbare Renderer. home_arch2=Nicht an Datenspeicher gebunden. home_arch3=Kann Daten lesen von\: CSV-Dateien, Datenbanken oder Java-Generatoren. home_arch4=Entkoppelte Client & Server Schichten. Fähig, reine Leichtgewicht-Client Dashboards zu erzeugen. home_arch5=Fähigkeit Data Sets für bessere Leistung auf den Client zu pushen & zu bearbeiten. home_arch6a=Basierend auf home_arch6b=, ein Framework zur Erstellung umfassender Apps im Workbench-Stil im Netz. home_furtherinfo=Weitere Informationen finden Sie auf der Webseite des Projekts home_license=Lizensiert unter Apache License, Version 2.0 notification_dashboard_created={0} Dashboard erstellt notification_dashboard_deleted={0} Dashboard gelöscht dashboard_new_displayer=Neuer Displayer dashboard_delete_popup_title=Dashboard löschen dashboard_delete_popup_content=Sind Sie sicher, dass Sie dieses Dashboard löschen möchten? dashboard_delete_dashboard=Dashboard löschen salesdbpersp_salessummary=Verkaufsübersicht salesreportspersp_salesreports=Verkaufsberichte expensesdb_title=Ausgabenberichte expensesdb_tab_exp_evolution=Ausgabenentwicklung expensesdb_tab_by_employee=Nach Mitarbeiter expensesdb_tab_all_exp=Alle Ausgaben expensesdb_pie_title=Ausgaben nach Büro expensesdb_pie_column1=Büro expensesdb_pie_column2=Abteilung expensesdb_pie_column3=Mitarbeiter expensesdb_bar_title=Ausgaben nach Abteilung expensesdb_bar_column1=Gesamtsumme expensesdb_bubble_title=Ausgaben nach Mitarbeiter expensesdb_bubble_column1=Gesamt expensesdb_bubble_column2=Durchschnitt expensesdb_bubble_column3=Mitarbeiter expensesdb_bubble_column4=Anzahl an Ausgabenberichten expensesdb_line_title=Ausgabenentwicklung expensesdb_line_column1=Gesamtsumme expensesdb_table_title=Liste der Ausgabenberichte expensesdb_table_column1=Büro expensesdb_table_column2=Abteilung expensesdb_table_column3=Mitarbeiter expensesdb_table_column4=Betrag expensesdb_table_column5=Datum gallerytree_home=Galerie gallerytree_home_p1=Die Galerie enthält echte Beispiele für alle unterschiedlichen Displayer-Typen, die in Dashbuilder unterstützt werden. Der Knoten "Dashboards" enthält auch eine Reihe von Beispielen darüber, wie mehrere Displayer zu einem voll funktionstüchtigen Endbenutzer-Dashboard kombiniert werden können. gallerytree_home_s2a=Alle Beispiele werden mithilfe des Dashbuilder GWT Displayer API erstellt. Wenn Sie sich für die Hintergründe interessieren oder einfach wissen wollen, wie der Quellcode aussieht, dann werfen Sie einen Blick auf Folgendes gallerytree_home_s2b=bei GitHub. gallerytree_home_ghublink=Datei gallerytree_title=Galerie-Baum gallerytree_bar=Balkendiagramm gallerytree_bar_horiz=Horizontal gallerytree_bar_horiz_title=Nach Produkt gallerytree_bar_horiz_column1=Gesamtsumme gallerytree_bar_vert=Vertikal gallerytree_bar_vert_title=Nach Produkt gallerytree_bar_vert_column1=Gesamtsumme gallerytree_bar_vert_dd=In die Tiefe gehen gallerytree_bar_vert_dd_title=Nach Pipeline/Status/Vertriebsperson gallerytree_bar_vert_dd_column1=Gesamtsumme gallerytree_bar_vert_dd_column2=Gesamtsumme gallerytree_bar_vert_dd_column3=Gesamtsumme gallerytree_bar_multi=Mehrere gallerytree_bar_stacked=Gestapelt gallerytree_bar_multi_title=Nach Land (min/max/durchschn.) gallerytree_bar_multi_column1=Min. gallerytree_bar_multi_column2=Max. gallerytree_bar_multi_column3=Durchschn. gallerytree_pie=Kreisdiagramm gallerytree_pie_basic=Einfach gallerytree_pie_basic_title=Nach Status gallerytree_pie_basic_column1=Gesamtsumme gallerytree_pie_3d=3d gallerytree_pie_3d_title=Nach Status gallerytree_pie_3d_column1=Gesamtsumme gallerytree_pie_donut=Donut gallerytree_pie_donut_title=Nach Status gallerytree_pie_donut_column1=Gesamtsumme gallerytree_pie_dd=In die Tiefe gehen gallerytree_pie_dd_title=Nach Pipeline/Status/Vertriebsperson gallerytree_pie_dd_column1=Gesamtsumme gallerytree_pie_dd_column2=Gesamtsumme gallerytree_pie_dd_column3=Gesamtsumme gallerytree_line=Liniendiagramm gallerytree_line_basic=Einfach gallerytree_line_basic_title=Entwicklung der Vertriebsmöglichkeiten gallerytree_line_basic_column1=Abschlussdatum gallerytree_line_basic_column2=Gesamtsumme gallerytree_line_multi=Mehrere gallerytree_line_multi_title=Nach Land (min/max/durchschn.) gallerytree_line_multi_column1=Min. gallerytree_line_multi_column2=Max. gallerytree_line_multi_column3=Durchschn. gallerytree_line_multi_static=Mehrere (statisch) gallerytree_line_multi_static_title=Vertriebsentwicklung pro Jahr gallerytree_line_multi_static_column1=Verkauf 2014 gallerytree_line_multi_static_column2=Verkauf 2015 gallerytree_line_multi_static_column3=Verkauf 2016 gallerytree_area=Flächendiagramm gallerytree_area_basic=Einfach gallerytree_area_basic_title=Erwartete Pipeline gallerytree_area_basic_column1=Erwartete Summe gallerytree_area_fixed=Fest (pro Monat) gallerytree_area_fixed_title=Pipeline (bester Monat) gallerytree_area_fixed_column1=Abschlussdatum gallerytree_area_fixed_column2=Erwartete Summe pro Monat gallerytree_area_dd=In die Tiefe gehen gallerytree_area_dd_title=Erwartete Pipeline gallerytree_area_dd_column1=Abschlussdatum gallerytree_area_dd_column2=Erwartete Summe gallerytree_bubble=Blasendiagramm gallerytree_bubble_basic=Einfach gallerytree_bubble_basic_title=Möglichkeitenverteilung nach Land gallerytree_bubble_basic_column1=Anzahl von Möglichkeiten gallerytree_bubble_basic_column2=Durchschnittliche Wahrscheinlichkeit gallerytree_bubble_basic_column3=Erwartete Summe gallerytree_bubble_basic_column4=Land gallerytree_meter=Meter-Diagramm gallerytree_meter_basic=Einfach gallerytree_meter_basic_title=Vertriebsziel gallerytree_meter_basic_column1=Gesamtsumme gallerytree_meter_multi=Mehrfach gallerytree_meter_multi_title=Erwartete Summe pro Jahr gallerytree_meter_multi_column1=Gesamtsumme gallerytree_meter_multi_static=Mehrere (statisch) gallerytree_meter_multi_static_title=Heart Rate gallerytree_meter_multi_static_column1=Person gallerytree_meter_multi_static_column2=Heart Rate gallerytree_metrics=Metriken gallerytree_metrics_basic=Einfach gallerytree_metrics_basic_title=Verkäufe (aktuelles Quartal) gallerytree_metrics_basic_column1=Verkäufe (aktuelles Quartal) gallerytree_metrics_basic_static=Einfach (statisch) gallerytree_metrics_basic_static_title=Tweets\! gallerytree_metrics_basic_static_column1=Tweets gallerytree_map=Map gallerytree_map_region=Marker gallerytree_map_region_title=Nach Land gallerytree_map_region_column1=Gesamtsumme gallerytree_map_marker=Regionen gallerytree_map_marker_title=Nach Land gallerytree_map_marker_column1=Gesamtsumme gallerytree_table=Tabellenbericht gallerytree_table_basic=Einfach gallerytree_table_basic_title=Liste von Möglichkeiten gallerytree_table_basic_column1=Land gallerytree_table_basic_column2=Kunde gallerytree_table_basic_column3=Produkt gallerytree_table_basic_column4=Vertriebsperson gallerytree_table_basic_column5=Status gallerytree_table_basic_column6=Quelle gallerytree_table_basic_column7=Erstellung gallerytree_table_basic_column8=Erwartet gallerytree_table_basic_column9=Abschluss gallerytree_table_basic_column10=Summe gallerytree_table_filtered=Gefiltert gallerytree_table_filtered_title=Möglichkeiten in den USA & Brasilien gallerytree_table_filtered_column1=Kunde gallerytree_table_filtered_column2=Produkt gallerytree_table_filtered_column3=Status gallerytree_table_filtered_column4=Quelle gallerytree_table_filtered_column5=Erstellung gallerytree_table_filtered_column6=Erwartet gallerytree_table_filtered_column7=Abschluss gallerytree_table_filtered_column8=Summe gallerytree_table_grouped=Gruppiert gallerytree_table_grouped_title=Übersicht Land gallerytree_table_grouped_column1=Land gallerytree_table_grouped_column2=\#Opps gallerytree_table_grouped_column3=Min. gallerytree_table_grouped_column4=Max. gallerytree_table_grouped_column5=Durchschnitt gallerytree_table_grouped_column6=Gesamt gallerytree_table_default_dd=Standard (in die Tiefe gehen) gallerytree_table_default_dd_title=Liste von Möglichkeiten gallerytree_table_default_dd_column1=Land gallerytree_table_default_dd_column2=Kunde gallerytree_table_default_dd_column3=Produkt gallerytree_table_default_dd_column4=Vertriebsperson gallerytree_table_default_dd_column5=Status gallerytree_table_default_dd_column6=Quelle gallerytree_table_default_dd_column7=Erstellung gallerytree_table_default_dd_column8=Erwartet gallerytree_table_default_dd_column9=Abschluss gallerytree_table_default_dd_column10=Summe gallerytree_db=Dashboards gallerytree_db_salesgoals=Vertriebsziele gallerytree_db_salespipe=Pipeline Vertrieb gallerytree_db_salespcountry=Vertrieb pro Land gallerytree_db_salesreps=Verkaufsberichte gallerytree_db_expreps=Ausgabenberichte gallerytree_db_clustermetrics=Cluster-Metriken gallerywidget_unknown=Unbekanntes Galerie-Widget gallerywidget_dataset_modif=Der Datensatz von Mitwirkenden wurde bearbeitet. Lade Ansicht neu ... gallerywidget_dataset_loaded=Datensatz geladen von Server [{0}, {1} Kb] metrics_server_detail_title=Server-Metriken (Vertikal) metrics_server_detail_backbutton_tt=Zurück metrics_server_detail_modebutton_tt_viewtable=Als Tabelle anzeigen metrics_server_detail_modebutton_tt_viewcharts=Als Diagramme anzeigen metrics_server_detail_lasthour_summary=Übersicht letzte Stunde metrics_server_detail_cpu_usage=CPU-Auslastung (%) metrics_server_detail_mem_usage=Arbeitsspeicher-Auslastung (Gb) metrics_server_detail_netw_usage=Netzwerk-Auslastung (kbps) metrics_server_detail_disk_usage=Disk-Auslastung (Mb) metrics_server_detail_live_procs=Live-Prozesse metrics_server_detail_cpu1_title=CPU 1 % metrics_server_detail_cpu2_title=CPU 2 % metrics_server_detail_mem_title=Arbeitsspeicherverbrauch metrics_server_detail_netw_title=Netzwerk-Bandbreite metrics_server_detail_disk_title=Disk-Auslastung metrics_server_detail_disk_column1=Freier Disk-Platz metrics_server_detail_disk_column2=Verwendeter Disk-Platz metrics_server_detail_procs_running_title=Prozesse in Betrieb metrics_server_detail_procs_running_column1=Läuft metrics_server_detail_procs_sleeping_title=Prozesse im Ruhezustand metrics_server_detail_procs_sleeping_column1=Im Ruhezustand metrics_server_detail_rt_table_title=Echtzeit {0} Metriken metrics_server_detail_rt_table_column1=Minute metrics_server_detail_rt_table_column2=CPU0 metrics_server_detail_rt_table_column3=CPU1 metrics_server_detail_rt_table_column4=Verbrauchter Arbeitsspeicher (Gb) metrics_server_detail_rt_table_column5=Freier Arbeitsspeicher (Gb) metrics_server_detail_rt_table_column6=Upstream (kbps) metrics_server_detail_rt_table_column7=Downstream (kbps) metrics_server_detail_rt_table_column8=Prozesse in Betrieb metrics_server_detail_rt_table_column9=Prozesse im Ruhezustand metrics_server_detail_rt_table_column10=Verwendete Disk (Mb) metrics_server_detail_rt_table_column11=Freie Disk (Mb) metrics_server_vert_title=Server-Metriken (Vertikal) metrics_server_vert_default_tt=Klicken, um Server-Details anzuzeigen metrics_server_vert_cpu_tt=CPU-Auslastung (%) metrics_server_vert_usedmem_tt=Verbrauchter Arbeitsspeicher (Gb) metrics_server_vert_netbw_tt=Netzwerk BW (kbps) metrics_server_vert_procs_tt=Prozesse in Betrieb/Ruhezustand metrics_server_vert_disk_tt=Disk-Auslastung (Mb) metrics_server_vert_cpu1_title=CPU 1 % metrics_server_vert_cpu2_title=CPU 2 % metrics_server_vert_memconsumption_title=Arbeitsspeicherverbrauch metrics_server_vert_netbw_title=Netzwerk-Bandbreite metrics_server_vert_procs_title=Prozesse in Betrieb/Ruhezustand metrics_server_vert_du_title=Disk-Auslastung metrics_server_vert_du_free=Freie Disk (Mb) metrics_server_vert_du_used=Verwendete Disk (Mb) metrics_server_vert_serverdown={0} ist außer Betrieb metrics_cluster_title=Cluster-Metriken metrics_cluster_messages_heading=Initialisiere Dashboard ... metrics_cluster_metricselector_label=Metrik metrics_cluster_chartselector_label=Diagrammtyp metrics_cluster_metricselector_cpu=CPU % metrics_cluster_metricselector_mem=Arbeitsspeicher metrics_cluster_metricselector_disk=Disk metrics_cluster_metricselector_netw=Netzwerk metrics_cluster_metricselector_proc=Prozesse metrics_cluster_chartselector_bar=Balken metrics_cluster_chartselector_line=Linien metrics_cluster_chartselector_area=Flächen metrics_cluster_column_cpu=CPU % metrics_cluster_column_cpu_y=CPU % metrics_cluster_column_df=Disk frei metrics_cluster_column_df_y=Gigabyte metrics_cluster_column_du=Disk verwendet metrics_cluster_column_du_y=Gigabyte metrics_cluster_column_memf=Arbeitssp. frei metrics_cluster_column_memf_y=Gigabyte metrics_cluster_column_memu=Arbeitsspeicher verwendet metrics_cluster_column_memu_y=Gigabyte metrics_cluster_column_procsrn=Proz. in Betrieb metrics_cluster_column_procsrn_y=Prozesse metrics_cluster_column_procssl=Proz. in Ruhezustand metrics_cluster_column_procssl_y=Prozesse metrics_cluster_column_netrx=Net. Rx metrics_cluster_column_netrx_y=Kb/s metrics_cluster_column_nettx=Net. St. metrics_cluster_column_nettx_y=Kb/s metrics_cluster_column_time=Zeit metrics_rt_title=Systemmetriken (Echtzeit) metrics_rt_serverup=in Betrieb metrics_rt_serverdown=außer Betrieb sales_bycountry_title=Vertrieb nach Land sales_bycountry_bubble_title=Möglichkeitenverteilung nach Land sales_bycountry_bubble_column1=Anzahl von Möglichkeiten sales_bycountry_bubble_column2=Durchschnittliche Wahrscheinlichkeit sales_bycountry_bubble_column3=Erwartete Summe sales_bycountry_map_title=Nach Land sales_bycountry_map_column1=Gesamtsumme sales_bycountry_table_title=Liste von Möglichkeiten sales_bycountry_table_column1=Land sales_bycountry_table_column2=Kunde sales_bycountry_table_column3=Produkt sales_bycountry_table_column4=Vertriebsperson sales_bycountry_table_column5=Status sales_bycountry_table_column6=Erstellung sales_bycountry_table_column7=Erwartet sales_bycountry_table_column8=Abschluss sales_bycountry_table_column9=Summe sales_bydate_title=Pipeline Vertrieb sales_bydate_area_title=Erwartete Pipeline sales_bydate_area_column1=Betrag sales_bydate_pie_years_title=Jahr sales_bydate_pie_years_column1=Vorkommen sales_bydate_pie_quarters_title=Quartal sales_bydate_pie_quarters_column1=Vorkommen sales_bydate_bar_weekday_title=Wochentag sales_bydate_bar_weekday_column1=Vorkommen sales_bydate_pie_pipe_title=Pipeline sales_bydate_pie_pipe_column1=Anzahl von Opps sales_bydate_table_title=Liste von Möglichkeiten sales_bydate_table_column1=Land sales_bydate_table_column2=Kunde sales_bydate_table_column3=Produkt sales_bydate_table_column4=Vertriebsperson sales_bydate_table_column5=Status sales_bydate_table_column6=Betrag sales_bydate_table_column7=Erwartet sales_bydate_table_column8=Erstellung sales_bydate_table_column9=Abschluss sales_bydate_selector_total=Gesamt sales_goals_title=Vertriebsziele sales_goals_meter_title=Vertriebsziel sales_goals_meter_column1=Gesamtsumme sales_goals_line_title=Erwartete Pipeline sales_goals_line_column1=Abschlussdatum sales_goals_line_column2=Gesamtsumme sales_goals_line_column3=Erwartete Summe sales_goals_bar_byproduct_title=Nach Produkt sales_goals_bar_byproduct_column1=Produkt sales_goals_bar_byproduct_column2=Gesamt sales_goals_bar_byproduct_column3=Erwartet sales_goals_bar_byempl_title=Nach Mitarbeiter sales_goals_bar_byempl_column1=Mitarbeiter sales_goals_bar_byempl_column2=Betrag sales_goals_bubble_title=Möglichkeitenverteilung nach Land sales_goals_bubble_column1=Anzahl von Möglichkeiten sales_goals_bubble_column2=Durchschnittliche Wahrscheinlichkeit sales_goals_bubble_column3=Erwartete Summe sales_tablereports_title=Verkaufsberichte sales_tablereports_tab_byyear=Nach Jahr sales_tablereports_tab_bycountry=Nach Land sales_tablereports_tab_byproduct=Nach Produkt sales_tablereports_tab_bysalesman=Nach Vertriebsperson sales_tablereports_all_title=Liste von Möglichkeiten sales_tablereports_all_column1=Land sales_tablereports_all_column2=Kunde sales_tablereports_all_column3=Produkt sales_tablereports_all_column4=Vertriebsperson sales_tablereports_all_column5=Status sales_tablereports_all_column6=Erstellung sales_tablereports_all_column7=Erwartet sales_tablereports_all_column8=Abschluss sales_tablereports_all_column9=Betrag sales_tablereports_bycountry_title=Übersicht Land sales_tablereports_bycountry_column1=Land sales_tablereports_bycountry_column2=\#Opps sales_tablereports_bycountry_column3=Min. sales_tablereports_bycountry_column4=Max. sales_tablereports_bycountry_column5=Durchschnitt sales_tablereports_bycountry_column6=Gesamt sales_tablereports_byproduct_title=Produktübersicht sales_tablereports_byproduct_column1=Produkt sales_tablereports_byproduct_column2=\#Opps sales_tablereports_byproduct_column3=Min. sales_tablereports_byproduct_column4=Max. sales_tablereports_byproduct_column5=Durchschnitt sales_tablereports_byproduct_column6=Gesamt sales_tablereports_bysalesman_title=Vertrieb nach Person sales_tablereports_bysalesman_column1=Vertriebsperson sales_tablereports_bysalesman_column2=\#Opps sales_tablereports_bysalesman_column3=Min. sales_tablereports_bysalesman_column4=Max. sales_tablereports_bysalesman_column5=Durchschnitt sales_tablereports_bysalesman_column6=Gesamt sales_tablereports_byyear_title=Übersicht Jahr sales_tablereports_byyear_column1=Erstellungsdatum sales_tablereports_byyear_column2=\#Opps sales_tablereports_byyear_column3=Min. sales_tablereports_byyear_column4=Max. sales_tablereports_byyear_column5=Durchschnitt sales_tablereports_byyear_column6=Gesamt salesopps_displayers_by_pipeline_title=Pipeline-Status salesopps_displayers_by_status_title=Nach Status salesopps_displayers_by_salesman_title=Nach Vertriebsperson salesopps_displayers_by_exp_pipeline_title=Erwarteter Betrag salesopps_displayers_by_exp_pipeline_column1=Erwarteter Betrag salesopps_displayers_by_product_title=Nach Produkt salesopps_displayers_by_product_column1=Gesamtsumme salesopps_displayers_by_country_title=Nach Land salesopps_displayers_by_country_column1=Gesamtsumme salesopps_displayers_country_summary_title=Übersicht Land salesopps_displayers_country_summary_column1=LAND salesopps_displayers_country_summary_column2=GESAMT salesopps_displayers_country_summary_column3=NUMMER salesopps_displayers_country_summary_column4=DURCHSCHNITT salesopps_displayers_country_summary_column5=MIN salesopps_displayers_country_summary_column6=MAX salesopps_displayers_all_list_title=Liste von Möglichkeiten ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_es.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # logoBannerError=Error al cargar el cartel. logOut=Cerrar sesión role=Función menu_home=Inicio menu_gallery=Galería menu_administration=Administración menu_security=Seguridad menu_dataset_authoring=Conjuntos de datos menu_content_manager=Administrador de contenido menu_extensions_apps=Aplicaciones menu_dashboards=Cuadros de mando menu_dashboards_salesdb=Cuadro de mando de ventas menu_dashboards_salesreports=Informes de ventas menu_dashboards_new=- Nuevo - home_intro=Dashbuilder es una aplicación web de informes y un cuadro de mando de propósito general que permite lo siguiente: home_upcoming=Próximas funcionalidades home_feature1=Configuración visual y personalización de los cuadros de mando home_feature2=Soporte para distintos tipos de visualizaciones mediante el uso de varias bibliotecas de gráficos home_feature3=Editor de la interfaz de usuario para la creación de definiciones de conjuntos de datos home_feature4=Editor completo para la definición de visualizaciones de gráficos home_feature5=Definición de tablas de informes interactivas home_feature6=Extracción de datos de sistemas externos, a través de diferentes protocolos home_feature7=Soporte tanto para análisis como para cuadros de mando en tiempo real home_feature8=Nuevos renderizadores basados en D3 JS y Lienzo GWT home_feature9=Tipos de visualizadores jerárquicos (grupos anidados): home_feature10=Soporte para múltiples series de datos home_feature11=Amplio soporte de movilidad home_feature12=Alertas y configuración de SLA home_feature13=API RESTful home_arch=Arquitectura home_arch1=No está atado a ninguna tecnología de representación gráfica. Renderizadores conectables. home_arch2=No está vinculado a ningún almacenamiento de datos. home_arch3=Archivos CSV, bases de datos o generadores Java. home_arch4=Capas de cliente y servidor desacopladas. Capacidad de compilar cuadros de mando de clientes puramente ligeros. home_arch5=Capacidad de enviar y manejar conjuntos de datos en el cliente para un mejor rendimiento. home_arch6a=Basado en home_arch6b=, un marco para compilar aplicaciones sofisticadas con estilo de mesa de trabajo en la Web. home_furtherinfo=Para obtener más información, visite el sitio web del proyecto home_license=Licenciado bajo la licencia de Apache, versión 2.0 notification_dashboard_created=Se creó el cuadro de mando {0} notification_dashboard_deleted=Se eliminó el cuadro de mando {0} dashboard_new_displayer=Nuevo visualizador dashboard_delete_popup_title=Eliminar el cuadro de mando dashboard_delete_popup_content=¿Está seguro de que desea eliminar este cuadro de mando? dashboard_delete_dashboard=Eliminar el cuadro de mando salesdbpersp_salessummary=Resumen de ventas salesreportspersp_salesreports=Informes de ventas expensesdb_title=Informes de gastos expensesdb_tab_exp_evolution=Evolución de gastos expensesdb_tab_by_employee=Por empleado expensesdb_tab_all_exp=Todos los gastos expensesdb_pie_title=Gastos por oficina expensesdb_pie_column1=Oficina expensesdb_pie_column2=Departamento expensesdb_pie_column3=Empleado expensesdb_bar_title=Gastos por departamento expensesdb_bar_column1=Cantidad total expensesdb_bubble_title=Gastos por empleado” expensesdb_bubble_column1=Total expensesdb_bubble_column2=Promedio expensesdb_bubble_column3=Empleado expensesdb_bubble_column4=Número de informes de gastos expensesdb_line_title=Evolución de gastos expensesdb_line_column1=Cantidad total expensesdb_table_title=Lista de informes de gastos expensesdb_table_column1=Oficina expensesdb_table_column2=Departamento expensesdb_table_column3=Empleado expensesdb_table_column4=Cantidad expensesdb_table_column5=Fecha gallerytree_home=Galería gallerytree_home_p1=La galería contiene ejemplos en vivo de todos los diferentes tipos de visualizadores admitidos en Dashbuilder. El nodo “Cuadros de mando” también contiene un conjunto de ejemplos de cómo combinar varios visualizadores en cuadros de mando para el usuario final con todas las funcionalidades. gallerytree_home_s2a=Todos los ejemplos se crearon mediante el uso de la API GWT Displayer de Dashbuilder. Si está interesado en los internos o solo desea ver cómo luce el código fuente, observe lo siguiente gallerytree_home_s2b=en GitHub. gallerytree_home_ghublink=archivo gallerytree_title=Árbol de la galería gallerytree_bar=Gráfico de barras gallerytree_bar_horiz=Horizontal gallerytree_bar_horiz_title=Por producto gallerytree_bar_horiz_column1=Cantidad total gallerytree_bar_vert=Vertical gallerytree_bar_vert_title=Por producto gallerytree_bar_vert_column1=Cantidad total gallerytree_bar_vert_dd=Ver detalles gallerytree_bar_vert_dd_title=Por tubería/estado/vendedor gallerytree_bar_vert_dd_column1=Cantidad total gallerytree_bar_vert_dd_column2=Cantidad total gallerytree_bar_vert_dd_column3=Cantidad total gallerytree_bar_multi=Múltiple gallerytree_bar_stacked=Apilado gallerytree_bar_multi_title=Por país (mín./máx./prom.) gallerytree_bar_multi_column1=Mín. gallerytree_bar_multi_column2=Máx. gallerytree_bar_multi_column3=Prom. gallerytree_pie=Gráfico circular gallerytree_pie_basic=Básico gallerytree_pie_basic_title=Por estado gallerytree_pie_basic_column1=Cantidad total gallerytree_pie_3d=3d gallerytree_pie_3d_title=Por estado gallerytree_pie_3d_column1=Cantidad total gallerytree_pie_donut=Dona gallerytree_pie_donut_title=Por estado gallerytree_pie_donut_column1=Cantidad total gallerytree_pie_dd=Ver detalles gallerytree_pie_dd_title=Por tubería/estado/vendedor gallerytree_pie_dd_column1=Cantidad total gallerytree_pie_dd_column2=Cantidad total gallerytree_pie_dd_column3=Cantidad total gallerytree_line=Gráfico de líneas gallerytree_line_basic=Básico gallerytree_line_basic_title=Evolución de las oportunidades de venta gallerytree_line_basic_column1=Fecha de cierre gallerytree_line_basic_column2=Cantidad total gallerytree_line_multi=Múltiple gallerytree_line_multi_title=Por país (mín./máx./prom.) gallerytree_line_multi_column1=Mín. gallerytree_line_multi_column2=Máx. gallerytree_line_multi_column3=Prom. gallerytree_line_multi_static=Múltiple (estático) gallerytree_line_multi_static_title=Evolución de las ventas por año gallerytree_line_multi_static_column1=Ventas en 2014 gallerytree_line_multi_static_column2=Ventas en 2015 gallerytree_line_multi_static_column3=Ventas en 2016 gallerytree_area=Gráfico de área gallerytree_area_basic=Básico gallerytree_area_basic_title=Tubería prevista gallerytree_area_basic_column1=Cantidad prevista gallerytree_area_fixed=Fijo (por mes) gallerytree_area_fixed_title=Tubería (mejor mes) gallerytree_area_fixed_column1=Fecha de cierre gallerytree_area_fixed_column2=Cantidad prevista por mes gallerytree_area_dd=Ver detalles gallerytree_area_dd_title=Tubería prevista gallerytree_area_dd_column1=Fecha de cierre gallerytree_area_dd_column2=Cantidad prevista gallerytree_bubble=Gráfico de burbujas gallerytree_bubble_basic=Básico gallerytree_bubble_basic_title=Distribución de oportunidades por país gallerytree_bubble_basic_column1=Cantidad de oportunidades gallerytree_bubble_basic_column2=Probabilidad media gallerytree_bubble_basic_column3=Cantidad prevista gallerytree_bubble_basic_column4=País gallerytree_meter=Gráfico de medidor gallerytree_meter_basic=Básico gallerytree_meter_basic_title=Objetivo de ventas gallerytree_meter_basic_column1=Cantidad total gallerytree_meter_multi=Múltiple gallerytree_meter_multi_title=Cantidad prevista por año gallerytree_meter_multi_column1=Cantidad total gallerytree_meter_multi_static=Múltiple (estático) gallerytree_meter_multi_static_title=Ritmo cardíaco gallerytree_meter_multi_static_column1=Persona gallerytree_meter_multi_static_column2=Ritmo cardíaco gallerytree_metrics=Métrica gallerytree_metrics_basic=Básico gallerytree_metrics_basic_title=Ventas (trimestre en curso) gallerytree_metrics_basic_column1=Ventas (trimestre en curso) gallerytree_metrics_basic_static=Básico (estático) gallerytree_metrics_basic_static_title=¡Tweets! gallerytree_metrics_basic_static_column1=Tweets gallerytree_map=Mapa gallerytree_map_region=Marcadores gallerytree_map_region_title=Por país gallerytree_map_region_column1=Cantidad total gallerytree_map_marker=Regiones gallerytree_map_marker_title=Por país gallerytree_map_marker_column1=Cantidad total gallerytree_table=Informe de tabla gallerytree_table_basic=Básico gallerytree_table_basic_title=Lista de oportunidades gallerytree_table_basic_column1=País gallerytree_table_basic_column2=Cliente gallerytree_table_basic_column3=Producto gallerytree_table_basic_column4=Vendedor gallerytree_table_basic_column5=Estado gallerytree_table_basic_column6=Fuente gallerytree_table_basic_column7=Creación gallerytree_table_basic_column8=Previsto gallerytree_table_basic_column9=Cerrando gallerytree_table_basic_column10=Cantidad gallerytree_table_filtered=Filtrado gallerytree_table_filtered_title=Oportunidades en EE.UU. y Brasil gallerytree_table_filtered_column1=Cliente gallerytree_table_filtered_column2=Producto gallerytree_table_filtered_column3=Estado gallerytree_table_filtered_column4=Fuente gallerytree_table_filtered_column5=Creación gallerytree_table_filtered_column6=Previsto gallerytree_table_filtered_column7=Cerrando gallerytree_table_filtered_column8=Cantidad gallerytree_table_grouped=Agrupados gallerytree_table_grouped_title=Resumen de país gallerytree_table_grouped_column1=País gallerytree_table_grouped_column2=Cant. de oportunidades gallerytree_table_grouped_column3=Mín. gallerytree_table_grouped_column4=Máx. gallerytree_table_grouped_column5=Promedio gallerytree_table_grouped_column6=Total gallerytree_table_default_dd=Predeterminado (desglosar) gallerytree_table_default_dd_title=Lista de oportunidades gallerytree_table_default_dd_column1=País gallerytree_table_default_dd_column2=Cliente gallerytree_table_default_dd_column3=Producto gallerytree_table_default_dd_column4=Vendedor gallerytree_table_default_dd_column5=Estado gallerytree_table_default_dd_column6=Fuente gallerytree_table_default_dd_column7=Creación gallerytree_table_default_dd_column8=Previsto gallerytree_table_default_dd_column9=Cerrando gallerytree_table_default_dd_column10=Cantidad gallerytree_selector=Selector gallerytree_selector_dropdown=Desplegar gallerytree_selector_labels=Etiquetas gallerytree_selector_slider=Control deslizante gallerytree_db=Cuadros de mando gallerytree_db_salesgoals=Objetivos de ventas gallerytree_db_salespipe=Tubería de ventas gallerytree_db_salespcountry=Ventas por país gallerytree_db_salesreps=Informes de ventas gallerytree_db_expreps=Informes de gastos gallerytree_db_clustermetrics=Métricas de clúster gallerywidget_unknown=Asistente de galería desconocido: gallerywidget_dataset_modif=Se ha modificado el conjunto de datos. Actualizando la vista… gallerywidget_dataset_loaded=Conjunto de datos cargado desde el servidor [{0}, {1} Kb] metrics_server_detail_title=Métricas de servidor (vertical) metrics_server_detail_backbutton_tt=Volver atrás metrics_server_detail_modebutton_tt_viewtable=Ver como tabla metrics_server_detail_modebutton_tt_viewcharts=Ver como gráficos metrics_server_detail_lasthour_summary=Resumen de la última hora metrics_server_detail_cpu_usage=Uso de CPU (%) metrics_server_detail_mem_usage=Uso de la memoria (Gb) metrics_server_detail_netw_usage=Uso de red (kbps) metrics_server_detail_disk_usage=Uso del disco (Mb) metrics_server_detail_live_procs=Procesos en vivo metrics_server_detail_cpu1_title=CPU 1 % metrics_server_detail_cpu2_title=CPU 2 % metrics_server_detail_mem_title=Consumo de memoria metrics_server_detail_netw_title=Ancho de banda de red metrics_server_detail_disk_title=Uso del disco metrics_server_detail_disk_column1=Espacio libre en el disco metrics_server_detail_disk_column2=Espacio de disco usado metrics_server_detail_procs_running_title=Procesos en ejecución metrics_server_detail_procs_running_column1=En ejecución metrics_server_detail_procs_sleeping_title=Procesos suspendidos metrics_server_detail_procs_sleeping_column1=Suspendido metrics_server_detail_rt_table_title=Métricas de {0} en tiempo real metrics_server_detail_rt_table_column1=Minuto metrics_server_detail_rt_table_column2=CPU0 metrics_server_detail_rt_table_column3=CPU1 metrics_server_detail_rt_table_column4=Memoria usada (Gb) metrics_server_detail_rt_table_column5=Memoria libre (Gb) metrics_server_detail_rt_table_column6=Ascendente (kbps) metrics_server_detail_rt_table_column7=Descendente (kbps) metrics_server_detail_rt_table_column8=Procesos en ejecución metrics_server_detail_rt_table_column9=Procesos suspendidos metrics_server_detail_rt_table_column10=Disco usado (Mb) metrics_server_detail_rt_table_column11=Disco libre (Mb) metrics_server_vert_title=Métricas de servidor (vertical) metrics_server_vert_default_tt=Haga clic para mostrar los detalles del servidor metrics_server_vert_cpu_tt=Uso de CPU (%) metrics_server_vert_usedmem_tt=Memoria usada (Gb) metrics_server_vert_netbw_tt=Ancho de banda de red (kbps) metrics_server_vert_procs_tt=Procesos en ejecución/suspendidos metrics_server_vert_disk_tt=Uso del disco (Mb) metrics_server_vert_cpu1_title=CPU 1 % metrics_server_vert_cpu2_title=CPU 2 % metrics_server_vert_memconsumption_title=Consumo de memoria metrics_server_vert_netbw_title=Ancho de banda de red metrics_server_vert_procs_title=Procesos en ejecución/suspendidos metrics_server_vert_du_title=Uso del disco metrics_server_vert_du_free=Disco libre (Mb) metrics_server_vert_du_used=Disco usado (Mb) metrics_server_vert_serverdown={0} está apagado metrics_cluster_title=Métricas de clúster metrics_cluster_messages_heading=Iniciando el cuadro de mando… metrics_cluster_metricselector_label=Métrica metrics_cluster_chartselector_label=Tipo de gráfico metrics_cluster_metricselector_cpu=% de CPU % metrics_cluster_metricselector_mem=Memoria metrics_cluster_metricselector_disk=Disco metrics_cluster_metricselector_netw=Red metrics_cluster_metricselector_proc=Procesos metrics_cluster_chartselector_bar=Barra metrics_cluster_chartselector_line=Línea metrics_cluster_chartselector_area=Área metrics_cluster_column_cpu=% de CPU % metrics_cluster_column_cpu_y=% de CPU % metrics_cluster_column_df=Disco libre metrics_cluster_column_df_y=Gigabytes metrics_cluster_column_du=Disco en uso metrics_cluster_column_du_y=Gigabytes metrics_cluster_column_memf=Mem. libre metrics_cluster_column_memf_y=Gigabytes metrics_cluster_column_memu=Mem. usada metrics_cluster_column_memu_y=Gigabytes metrics_cluster_column_procsrn=Proc. en ejecución metrics_cluster_column_procsrn_y=Procesos metrics_cluster_column_procssl=Proc. suspendido metrics_cluster_column_procssl_y=Procesos metrics_cluster_column_netrx=Red. Rx metrics_cluster_column_netrx_y=Kb/s metrics_cluster_column_nettx=Red. Tx metrics_cluster_column_nettx_y=Kb/s metrics_cluster_column_time=Tiempo metrics_rt_title=Métricas del sistema (tiempo real) metrics_rt_serverup= está encendido metrics_rt_serverdown= está apagado sales_bycountry_title=Ventas por país sales_bycountry_bubble_title=Distribución de oportunidades por país sales_bycountry_bubble_column1=Cantidad de oportunidades sales_bycountry_bubble_column2=Probabilidad media sales_bycountry_bubble_column3=Cantidad prevista sales_bycountry_map_title=Por país sales_bycountry_map_column1=Cantidad total sales_bycountry_table_title=Lista de oportunidades sales_bycountry_table_column1=País sales_bycountry_table_column2=Cliente sales_bycountry_table_column3=Producto sales_bycountry_table_column4=Vendedor sales_bycountry_table_column5=Estado sales_bycountry_table_column6=Creación sales_bycountry_table_column7=Previsto sales_bycountry_table_column8=Cerrando sales_bycountry_table_column9=Cantidad sales_bydate_title=Tubería de ventas sales_bydate_area_title=Tubería prevista sales_bydate_area_column1=Cantidad sales_bydate_pie_years_title=Año sales_bydate_pie_years_column1=Ocurrencias sales_bydate_pie_quarters_title=Trimestre sales_bydate_pie_quarters_column1=Ocurrencias sales_bydate_bar_weekday_title=Día de la semana sales_bydate_bar_weekday_column1=Ocurrencias sales_bydate_pie_pipe_title=Tubería sales_bydate_pie_pipe_column1=Cantidad de oportunidades sales_bydate_table_title=Lista de oportunidades sales_bydate_table_column1=País sales_bydate_table_column2=Cliente sales_bydate_table_column3=Producto sales_bydate_table_column4=Vendedor sales_bydate_table_column5=Estado sales_bydate_table_column6=Cantidad sales_bydate_table_column7=Previsto sales_bydate_table_column8=Creación sales_bydate_table_column9=Cerrando sales_bydate_selector_total=Total sales_goals_title=Objetivos de ventas sales_goals_meter_title=Objetivo de ventas sales_goals_meter_column1=Cantidad total sales_goals_line_title=Tubería prevista sales_goals_line_column1=Fecha de cierre sales_goals_line_column2=Cantidad total sales_goals_line_column3=Cantidad prevista sales_goals_bar_byproduct_title=Por producto sales_goals_bar_byproduct_column1=Producto sales_goals_bar_byproduct_column2=Total sales_goals_bar_byproduct_column3=Previsto sales_goals_bar_byempl_title=Por empleado sales_goals_bar_byempl_column1=Empleado sales_goals_bar_byempl_column2=Cantidad sales_goals_bubble_title=Distribución de oportunidades por país sales_goals_bubble_column1=Cantidad de oportunidades sales_goals_bubble_column2=Probabilidad media sales_goals_bubble_column3=Cantidad prevista sales_tablereports_title=Informes de ventas sales_tablereports_tab_byyear=Por año sales_tablereports_tab_bycountry=Por país sales_tablereports_tab_byproduct=Por producto sales_tablereports_tab_bysalesman=Por vendedor sales_tablereports_all_title=Lista de oportunidades sales_tablereports_all_column1=País sales_tablereports_all_column2=Cliente sales_tablereports_all_column3=Producto sales_tablereports_all_column4=Vendedor sales_tablereports_all_column5=Estado sales_tablereports_all_column6=Creación sales_tablereports_all_column7=Previsto sales_tablereports_all_column8=Cerrando sales_tablereports_all_column9=Cantidad sales_tablereports_bycountry_title=Resumen de país sales_tablereports_bycountry_column1=País sales_tablereports_bycountry_column2=Cant. de oportunidades sales_tablereports_bycountry_column3=Mín. sales_tablereports_bycountry_column4=Máx. sales_tablereports_bycountry_column5=Promedio sales_tablereports_bycountry_column6=Total sales_tablereports_byproduct_title=Resumen del producto sales_tablereports_byproduct_column1=Producto sales_tablereports_byproduct_column2=Cant. de oportunidades sales_tablereports_byproduct_column3=Mín. sales_tablereports_byproduct_column4=Máx. sales_tablereports_byproduct_column5=Promedio sales_tablereports_byproduct_column6=Total sales_tablereports_bysalesman_title=Ventas por persona sales_tablereports_bysalesman_column1=Vendedor sales_tablereports_bysalesman_column2=Cant. de oportunidades sales_tablereports_bysalesman_column3=Mín. sales_tablereports_bysalesman_column4=Máx. sales_tablereports_bysalesman_column5=Promedio sales_tablereports_bysalesman_column6=Total sales_tablereports_byyear_title=Resumen del año sales_tablereports_byyear_column1=Fecha de creación sales_tablereports_byyear_column2=Cant. de oportunidades sales_tablereports_byyear_column3=Mín. sales_tablereports_byyear_column4=Máx. sales_tablereports_byyear_column5=Promedio sales_tablereports_byyear_column6=Total salesopps_displayers_by_pipeline_title=Estado de la tubería salesopps_displayers_by_status_title=Por estado salesopps_displayers_by_salesman_title=Por vendedor salesopps_displayers_by_exp_pipeline_title=Cantidad prevista salesopps_displayers_by_exp_pipeline_column1=Cantidad prevista salesopps_displayers_by_product_title=Por producto salesopps_displayers_by_product_column1=Cantidad total salesopps_displayers_by_country_title=Por país salesopps_displayers_by_country_column1=Cantidad total salesopps_displayers_country_summary_title=Resumen de país salesopps_displayers_country_summary_column1=PAÍS salesopps_displayers_country_summary_column2=TOTAL salesopps_displayers_country_summary_column3=NÚMERO salesopps_displayers_country_summary_column4=PROMEDIO salesopps_displayers_country_summary_column5=MÍN salesopps_displayers_country_summary_column6=MÁX salesopps_displayers_all_list_title=Lista de oportunidades content_manager_dashboard=cuadro de mando content_manager_dashboards=cuadros de mando content_manager_noDashboards=No hay cuadros de mando HomeScreenView.title=¡Bienvenido a Dashbuilder! HomeScreenView.subTitle=Dashbuilder ofrece herramientas para crear cuadros de mando empresariales. Seleccione una herramienta a continuación para empezar. ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_fr.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # logoBannerError=Échec de chargement de la bannière. logOut=Se déconnecter role=Rôle menu_home=Accueil menu_gallery=Galerie menu_administration=Administration menu_security=Sécurité menu_dataset_authoring=Ensembles de données menu_content_manager=Gestionnaire de contenu menu_extensions_apps=Applications menu_dashboards=Tableaux de bord menu_dashboards_salesdb=Tableau de bord des ventes menu_dashboards_salesreports=Rapports sur les ventes menu_dashboards_new=- Nouveau - home_intro=Dashbuilder est une application Web de tableau de bord et de création de rapports polyvalente qui offre les fonctionnalités suivantes : home_upcoming=Fonctionnalités à venir home_feature1=Configuration visuelle et personnalisation des tableaux de bord home_feature2=Prise en charge de différents types de visualisations à l''aide de plusieurs bibliothèques de graphiques home_feature3=Éditeur d''IU pour la création de définitions d''ensembles de données home_feature4=Éditeur complet permettant de définir des visualisations de graphiques home_feature5=Définition de tables de rapports interactives home_feature6=Extraction de données à partir de systèmes externes, par le biais de différents protocoles home_feature7=Pris en charge de tableaux de bord en temps réel et analytiques home_feature8=Nouveaux moteurs de rendu basés sur D3 JS et Lienzo GWT home_feature9=Types d''afficheurs hiérarchiques (groupes imbriqués) : Tree & Pie home_feature10=Prise en charge de plusieurs séries de données home_feature11=Prise en charge étendue de la mobilité home_feature12=Alertes et configuration de contrats SLA home_feature13=API RESTful home_arch=Architecture home_arch1=Lié à aucune technologie de rendu de graphiques. Moteurs de rendu enfichables. home_arch2=Lié à aucun stockage de données. home_arch3=Capacité de lire des données à partir de : fichiers CSV, bases de données, recherche élastique ou générateurs Java. home_arch4=Couches client et serveur découplées. Capacité de création de tableaux de bord client légers. home_arch5=Capacité d''envoi et de traitement d''ensembles de données sur le client pour de meilleures performances. home_arch6a=Basé sur home_arch6b=, une structure destinée à la création d''applications enrichies de type "Tableau de référence" sur le Web. home_furtherinfo=Pour plus d''informations, veuillez consulter le site Web du projet home_license=Sous licence Apache, version 2.0 notification_dashboard_created={0} tableau de bord créé notification_dashboard_deleted={0} tableau de bord supprimé dashboard_new_displayer=Nouvel afficheur dashboard_delete_popup_title=Supprimer le tableau de bord dashboard_delete_popup_content=Voulez-vous vraiment supprimer ce tableau de bord ? dashboard_delete_dashboard=Supprimer le tableau de bord salesdbpersp_salessummary=Résumé des ventes salesreportspersp_salesreports=Rapports sur les ventes expensesdb_title=Rapports sur les dépenses expensesdb_tab_exp_evolution=Évolution des dépenses expensesdb_tab_by_employee=Par employé expensesdb_tab_all_exp=Toutes les dépenses expensesdb_pie_title=Dépenses par bureau expensesdb_pie_column1=Bureau expensesdb_pie_column2=Service expensesdb_pie_column3=Employé expensesdb_bar_title=Dépenses par service expensesdb_bar_column1=Montant total expensesdb_bubble_title=Dépenses par employé" expensesdb_bubble_column1=Total expensesdb_bubble_column2=Moyenne expensesdb_bubble_column3=Employé expensesdb_bubble_column4=Nombre de rapports sur les dépenses expensesdb_line_title=Évolution des dépenses expensesdb_line_column1=Montant total expensesdb_table_title=Liste des rapports sur les dépenses expensesdb_table_column1=Bureau expensesdb_table_column2=Service expensesdb_table_column3=Employé expensesdb_table_column4=Montant expensesdb_table_column5=Date gallerytree_home=Galerie gallerytree_home_p1=La galerie contient des exemples dynamiques de tous les différents types d''afficheur pris en charge dans Dashbuilder. Le nœud "Tableaux de bord" contient également des exemples sur la manière de combiner plusieurs afficheurs afin de disposer de tableaux de bord complets pour l''utilisateur final. gallerytree_home_s2a=Tous les exemples sont compilés à l''aide de l''API GWT Displayer de Dashbuilder. Si vous êtes intéressé par leur fonctionnement interne ou si vous voulez simplement voir à quoi ressemble le code source, consultez gallerytree_home_s2b=sur GitHub. gallerytree_home_ghublink=fichier gallerytree_title=Arborescence de la galerie gallerytree_bar=Graphique à barres gallerytree_bar_horiz=Horizontal gallerytree_bar_horiz_title=Par produit gallerytree_bar_horiz_column1=Montant total gallerytree_bar_vert=Vertical gallerytree_bar_vert_title=Par produit gallerytree_bar_vert_column1=Montant total gallerytree_bar_vert_dd=Descendre dans la hiérarchie gallerytree_bar_vert_dd_title=Par pipeline/état/vendeur gallerytree_bar_vert_dd_column1=Montant total gallerytree_bar_vert_dd_column2=Montant total gallerytree_bar_vert_dd_column3=Montant total gallerytree_bar_multi=Multiple gallerytree_bar_stacked=Empilé gallerytree_bar_multi_title=Par pays (min/max/moy) gallerytree_bar_multi_column1=Min gallerytree_bar_multi_column2=Max gallerytree_bar_multi_column3=Moy gallerytree_pie=Graphique en secteurs gallerytree_pie_basic=De base gallerytree_pie_basic_title=Par état gallerytree_pie_basic_column1=Montant total gallerytree_pie_3d=3d gallerytree_pie_3d_title=Par état gallerytree_pie_3d_column1=Montant total gallerytree_pie_donut=Anneau gallerytree_pie_donut_title=Par état gallerytree_pie_donut_column1=Montant total gallerytree_pie_dd=Descendre dans la hiérarchie gallerytree_pie_dd_title=Par pipeline/état/vendeur gallerytree_pie_dd_column1=Montant total gallerytree_pie_dd_column2=Montant total gallerytree_pie_dd_column3=Montant total gallerytree_line=Graphique en courbes gallerytree_line_basic=De base gallerytree_line_basic_title=Évolution des opportunités de vente gallerytree_line_basic_column1=Date de clôture gallerytree_line_basic_column2=Montant total gallerytree_line_multi=Multiple gallerytree_line_multi_title=Par pays (min/max/moy) gallerytree_line_multi_column1=Min gallerytree_line_multi_column2=Max gallerytree_line_multi_column3=Moy gallerytree_line_multi_static=Multiple (statique) gallerytree_line_multi_static_title=Évolution des ventes par année gallerytree_line_multi_static_column1=Ventes en 2014 gallerytree_line_multi_static_column2=Ventes en 2015 gallerytree_line_multi_static_column3=Ventes en 2016 gallerytree_area=Graphique en aires gallerytree_area_basic=De base gallerytree_area_basic_title=Pipeline prévu gallerytree_area_basic_column1=Montant prévu gallerytree_area_fixed=Fixe (par mois) gallerytree_area_fixed_title=Pipeline (meilleur mois) gallerytree_area_fixed_column1=Date de clôture gallerytree_area_fixed_column2=Montant prévu par mois gallerytree_area_dd=Descendre dans la hiérarchie gallerytree_area_dd_title=Pipeline prévu gallerytree_area_dd_column1=Date de clôture gallerytree_area_dd_column2=Montant prévu gallerytree_bubble=Graphique en bulles gallerytree_bubble_basic=De base gallerytree_bubble_basic_title=Répartition des opportunités par pays gallerytree_bubble_basic_column1=Nombre d''opportunités gallerytree_bubble_basic_column2=Probabilité moyenne gallerytree_bubble_basic_column3=Montant prévu gallerytree_bubble_basic_column4=Pays gallerytree_meter=Graphique de mesure gallerytree_meter_basic=De base gallerytree_meter_basic_title=Objectif de vente gallerytree_meter_basic_column1=Montant total gallerytree_meter_multi=Multiple gallerytree_meter_multi_title=Montant prévu par an gallerytree_meter_multi_column1=Montant total gallerytree_meter_multi_static=Multiple (statique) gallerytree_meter_multi_static_title=Fréquence cardiaque gallerytree_meter_multi_static_column1=Personne gallerytree_meter_multi_static_column2=Fréquence cardiaque gallerytree_metrics=Métriques gallerytree_metrics_basic=De base gallerytree_metrics_basic_title=Ventes (trimestre en cours) gallerytree_metrics_basic_column1=Ventes (trimestre en cours) gallerytree_metrics_basic_static=De base (statique) gallerytree_metrics_basic_static_title=Tweets ! gallerytree_metrics_basic_static_column1=Tweets gallerytree_map=Carte gallerytree_map_region=Marqueurs gallerytree_map_region_title=Par pays gallerytree_map_region_column1=Montant total gallerytree_map_marker=Régions gallerytree_map_marker_title=Par pays gallerytree_map_marker_column1=Montant total gallerytree_table=Rapport de tableau gallerytree_table_basic=De base gallerytree_table_basic_title=Liste des opportunités gallerytree_table_basic_column1=Pays gallerytree_table_basic_column2=Client gallerytree_table_basic_column3=Produit gallerytree_table_basic_column4=Vendeur gallerytree_table_basic_column5=État gallerytree_table_basic_column6=Source gallerytree_table_basic_column7=Création gallerytree_table_basic_column8=Prévu gallerytree_table_basic_column9=Clôture gallerytree_table_basic_column10=Montant gallerytree_table_filtered=Filtré gallerytree_table_filtered_title=Opportunités aux États-Unis et au Brésil gallerytree_table_filtered_column1=Client gallerytree_table_filtered_column2=Produit gallerytree_table_filtered_column3=État gallerytree_table_filtered_column4=Source gallerytree_table_filtered_column5=Création gallerytree_table_filtered_column6=Prévu gallerytree_table_filtered_column7=Clôture gallerytree_table_filtered_column8=Montant gallerytree_table_grouped=Groupé gallerytree_table_grouped_title=Résumé par pays gallerytree_table_grouped_column1=Pays gallerytree_table_grouped_column2=#Opps gallerytree_table_grouped_column3=Min gallerytree_table_grouped_column4=Max gallerytree_table_grouped_column5=Moyenne gallerytree_table_grouped_column6=Total gallerytree_table_default_dd=Par défaut (descendre dans la hiérarchie) gallerytree_table_default_dd_title=Liste des opportunités gallerytree_table_default_dd_column1=Pays gallerytree_table_default_dd_column2=Client gallerytree_table_default_dd_column3=Produit gallerytree_table_default_dd_column4=Vendeur gallerytree_table_default_dd_column5=État gallerytree_table_default_dd_column6=Source gallerytree_table_default_dd_column7=Création gallerytree_table_default_dd_column8=Prévu gallerytree_table_default_dd_column9=Clôture gallerytree_table_default_dd_column10=Montant gallerytree_selector=Sélecteur gallerytree_selector_dropdown=Liste déroulante gallerytree_selector_labels=Étiquettes gallerytree_selector_slider=Curseur gallerytree_db=Tableaux de bord gallerytree_db_salesgoals=Objectifs de vente gallerytree_db_salespipe=Pipeline de ventes gallerytree_db_salespcountry=Ventes par pays gallerytree_db_salesreps=Rapports sur les ventes gallerytree_db_expreps=Rapports sur les dépenses gallerytree_db_clustermetrics=Métriques de cluster gallerywidget_unknown=Widget de galerie inconnu : gallerywidget_dataset_modif=L''ensemble de données a été modifié. Rafraîchissement de la vue… gallerywidget_dataset_loaded=Ensemble de données chargé à partir du serveur [{0}, {1} Ko] metrics_server_detail_title=Métriques du serveur (vertical) metrics_server_detail_backbutton_tt=Revenir en arrière metrics_server_detail_modebutton_tt_viewtable=Afficher sous la forme d''un tableau metrics_server_detail_modebutton_tt_viewcharts=Afficher sous forme de graphiques metrics_server_detail_lasthour_summary=Résumé de la dernière heure metrics_server_detail_cpu_usage=Utilisation du processeur (%) metrics_server_detail_mem_usage=Utilisation de la mémoire (Go) metrics_server_detail_netw_usage=Utilisation du réseau (kbit/s) metrics_server_detail_disk_usage=Utilisation du disque (Mo) metrics_server_detail_live_procs=Processus en direct metrics_server_detail_cpu1_title=% processeur 1 metrics_server_detail_cpu2_title=% processeur 2 metrics_server_detail_mem_title=Consommation de mémoire metrics_server_detail_netw_title=Bande passante du réseau metrics_server_detail_disk_title=Utilisation du disque metrics_server_detail_disk_column1=Espace disque libre metrics_server_detail_disk_column2=Espace disque utilisé metrics_server_detail_procs_running_title=Processus en cours d''exécution metrics_server_detail_procs_running_column1=En cours d''exécution metrics_server_detail_procs_sleeping_title=Processus en veille metrics_server_detail_procs_sleeping_column1=En veille metrics_server_detail_rt_table_title=Métriques {0} en temps réel metrics_server_detail_rt_table_column1=Minute metrics_server_detail_rt_table_column2=Processeur 0 metrics_server_detail_rt_table_column3=Processeur 1 metrics_server_detail_rt_table_column4=Mémoire utilisée (Go) metrics_server_detail_rt_table_column5=Mémoire libre (Go) metrics_server_detail_rt_table_column6=Montant (kbit/s) metrics_server_detail_rt_table_column7=Descendant (kbit/s) metrics_server_detail_rt_table_column8=Processus en cours d''exécution metrics_server_detail_rt_table_column9=Processus en veille metrics_server_detail_rt_table_column10=Disque utilisé (Mo) metrics_server_detail_rt_table_column11=Espace disque libre (Mo) metrics_server_vert_title=Métriques du serveur (vertical) metrics_server_vert_default_tt=Cliquez pour afficher les détails du serveur metrics_server_vert_cpu_tt=Utilisation du processeur (%) metrics_server_vert_usedmem_tt=Mémoire utilisée (Go) metrics_server_vert_netbw_tt=Bande passante du réseau (kbit/s) metrics_server_vert_procs_tt=Processus en cours d''exécution/en veille metrics_server_vert_disk_tt=Utilisation du disque (Mo) metrics_server_vert_cpu1_title=% processeur 1 metrics_server_vert_cpu2_title=% processeur 2 metrics_server_vert_memconsumption_title=Consommation de mémoire metrics_server_vert_netbw_title=Bande passante du réseau metrics_server_vert_procs_title=Processus en cours d''exécution/en veille metrics_server_vert_du_title=Utilisation du disque metrics_server_vert_du_free=Espace disque libre (Mo) metrics_server_vert_du_used=Disque utilisé (Mo) metrics_server_vert_serverdown={0} hors service metrics_cluster_title=Métriques de cluster metrics_cluster_messages_heading=Initialisation du tableau de bord… metrics_cluster_metricselector_label=Métrique metrics_cluster_chartselector_label=Type de graphique metrics_cluster_metricselector_cpu=% de processeur metrics_cluster_metricselector_mem=Mémoire metrics_cluster_metricselector_disk=Disque metrics_cluster_metricselector_netw=Réseau metrics_cluster_metricselector_proc=Processus metrics_cluster_chartselector_bar=Barres metrics_cluster_chartselector_line=Ligne metrics_cluster_chartselector_area=Aires metrics_cluster_column_cpu=% de processeur metrics_cluster_column_cpu_y=% de processeur metrics_cluster_column_df=Disque libre metrics_cluster_column_df_y=Giga-octets metrics_cluster_column_du=Disque utilisé metrics_cluster_column_du_y=Giga-octets metrics_cluster_column_memf=Mém. libre metrics_cluster_column_memf_y=Giga-octets metrics_cluster_column_memu=Mém. utilisée metrics_cluster_column_memu_y=Giga-octets metrics_cluster_column_procsrn=Proc. en cours metrics_cluster_column_procsrn_y=Processus metrics_cluster_column_procssl=Proc. en veille metrics_cluster_column_procssl_y=Processus metrics_cluster_column_netrx=Réseau Rx metrics_cluster_column_netrx_y=Kbit/s metrics_cluster_column_nettx=Réseau Tx metrics_cluster_column_nettx_y=Kbit/s metrics_cluster_column_time=Temps metrics_rt_title=Métriques du système (en temps réel) metrics_rt_serverup= est actif metrics_rt_serverdown= est inactif sales_bycountry_title=Ventes par pays sales_bycountry_bubble_title=Répartition des opportunités par pays sales_bycountry_bubble_column1=Nombre d''opportunités sales_bycountry_bubble_column2=Probabilité moyenne sales_bycountry_bubble_column3=Montant prévu sales_bycountry_map_title=Par pays sales_bycountry_map_column1=Montant total sales_bycountry_table_title=Liste des opportunités sales_bycountry_table_column1=Pays sales_bycountry_table_column2=Client sales_bycountry_table_column3=Produit sales_bycountry_table_column4=Vendeur sales_bycountry_table_column5=État sales_bycountry_table_column6=Création sales_bycountry_table_column7=Prévu sales_bycountry_table_column8=Clôture sales_bycountry_table_column9=Montant sales_bydate_title=Pipeline de ventes sales_bydate_area_title=Pipeline prévue sales_bydate_area_column1=Montant sales_bydate_pie_years_title=Année sales_bydate_pie_years_column1=Occurrences sales_bydate_pie_quarters_title=Trimestre sales_bydate_pie_quarters_column1=Occurrences sales_bydate_bar_weekday_title=Jour de la semaine sales_bydate_bar_weekday_column1=Occurrences sales_bydate_pie_pipe_title=Pipeline sales_bydate_pie_pipe_column1=Nombre d''opportunités sales_bydate_table_title=Liste des opportunités sales_bydate_table_column1=Pays sales_bydate_table_column2=Client sales_bydate_table_column3=Produit sales_bydate_table_column4=Vendeur sales_bydate_table_column5=État sales_bydate_table_column6=Montant sales_bydate_table_column7=Prévu sales_bydate_table_column8=Création sales_bydate_table_column9=Clôture sales_bydate_selector_total=Total sales_goals_title=Objectifs de vente sales_goals_meter_title=Objectif de vente sales_goals_meter_column1=Montant total sales_goals_line_title=Pipeline prévue sales_goals_line_column1=Date de clôture sales_goals_line_column2=Montant total sales_goals_line_column3=Montant prévu sales_goals_bar_byproduct_title=Par produit sales_goals_bar_byproduct_column1=Produit sales_goals_bar_byproduct_column2=Total sales_goals_bar_byproduct_column3=Prévu sales_goals_bar_byempl_title=Par employé sales_goals_bar_byempl_column1=Employé sales_goals_bar_byempl_column2=Montant sales_goals_bubble_title=Répartition des opportunités par pays sales_goals_bubble_column1=Nombre d''opportunités sales_goals_bubble_column2=Probabilité moyenne sales_goals_bubble_column3=Montant prévu sales_tablereports_title=Rapports sur les ventes sales_tablereports_tab_byyear=Par année sales_tablereports_tab_bycountry=Par pays sales_tablereports_tab_byproduct=Par produit sales_tablereports_tab_bysalesman=Par vendeur sales_tablereports_all_title=Liste des opportunités sales_tablereports_all_column1=Pays sales_tablereports_all_column2=Client sales_tablereports_all_column3=Produit sales_tablereports_all_column4=Vendeur sales_tablereports_all_column5=État sales_tablereports_all_column6=Création sales_tablereports_all_column7=Prévu sales_tablereports_all_column8=Clôture sales_tablereports_all_column9=Montant sales_tablereports_bycountry_title=Résumé par pays sales_tablereports_bycountry_column1=Pays sales_tablereports_bycountry_column2=#Opps sales_tablereports_bycountry_column3=Min sales_tablereports_bycountry_column4=Max sales_tablereports_bycountry_column5=Moyenne sales_tablereports_bycountry_column6=Total sales_tablereports_byproduct_title=Résumé du produit sales_tablereports_byproduct_column1=Produit sales_tablereports_byproduct_column2=#Opps sales_tablereports_byproduct_column3=Min sales_tablereports_byproduct_column4=Max sales_tablereports_byproduct_column5=Moyenne sales_tablereports_byproduct_column6=Total sales_tablereports_bysalesman_title=Ventes par personne sales_tablereports_bysalesman_column1=Vendeur sales_tablereports_bysalesman_column2=#Opps sales_tablereports_bysalesman_column3=Min sales_tablereports_bysalesman_column4=Max sales_tablereports_bysalesman_column5=Moyenne sales_tablereports_bysalesman_column6=Total sales_tablereports_byyear_title=Résumé de l''année sales_tablereports_byyear_column1=Date de création sales_tablereports_byyear_column2=#Opps sales_tablereports_byyear_column3=Min sales_tablereports_byyear_column4=Max sales_tablereports_byyear_column5=Moyenne sales_tablereports_byyear_column6=Total salesopps_displayers_by_pipeline_title=État des pipelines salesopps_displayers_by_status_title=Par état salesopps_displayers_by_salesman_title=Par vendeur salesopps_displayers_by_exp_pipeline_title=Montant prévu salesopps_displayers_by_exp_pipeline_column1=Montant prévu salesopps_displayers_by_product_title=Par produit salesopps_displayers_by_product_column1=Montant total salesopps_displayers_by_country_title=Par pays salesopps_displayers_by_country_column1=Montant total salesopps_displayers_country_summary_title=Résumé par pays salesopps_displayers_country_summary_column1=PAYS salesopps_displayers_country_summary_column2=TOTAL salesopps_displayers_country_summary_column3=NUMÉRO salesopps_displayers_country_summary_column4=MOYENNE salesopps_displayers_country_summary_column5=MIN salesopps_displayers_country_summary_column6=MAX salesopps_displayers_all_list_title=Liste des opportunités content_manager_dashboard=tableau de bord content_manager_dashboards=tableaux de bord content_manager_noDashboards=Aucun tableau de bord HomeScreenView.title=Bienvenue dans Dashbuilder ! HomeScreenView.subTitle=Dashbuilder offre des outils pour créer des tableaux de bord d''entreprise. Sélectionnez un outil ci-dessous pour commencer. ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_it.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # logoBannerError=Impossibile caricare il banner. logOut=Esci role=Ruolo menu_home=Home menu_gallery=Galleria menu_administration=Amministrazione menu_security=Sicurezza menu_dataset_authoring=Set di dati menu_content_manager=Gestore dei contenuti menu_extensions_apps=App menu_dashboards=Dashboard menu_dashboards_salesdb=Dashboard delle vendite menu_dashboards_salesreports=Report delle vendite menu_dashboards_new=- Nuovo - home_intro=Dashbuilder è un''applicazione web di dashboard e reporting generale che consente di: home_upcoming=Prossime funzionalità home_feature1=Configurazione visuale e personalizzazione delle dashboard home_feature2=Supporto per diversi tipi di visualizzazioni utilizzando diverse librerie di grafici home_feature3=Editor UI per la creazione di definizioni di set di dati home_feature4=Editor completo per la definizione di visualizzazioni grafiche home_feature5=Definizione di tabelle di report interattive home_feature6=Estrazione di dati da sistemi esterni, attraverso diversi protocolli home_feature7=Supporto sia per dashboard di analisi che in tempo reale home_feature8=Nuovi render basati su D3 JS & Lienzo GWT home_feature9=Tipi di visualizzatori gerarchici (gruppi nidificati): Albero e Torta home_feature10=Supporto per più serie di dati home_feature11=Supporto completo per la mobilità home_feature12=Configurazione di avvisi e SLA home_feature13=API RESTful home_arch=Architettura home_arch1=Non legato a una particolare tecnologia di rendering dei grafici. Renderizzatori plug-in. home_arch2=Non legato a un particolare archivio dati. home_arch3=Capacità di leggere dati da: file CSV, database o generatori Java. home_arch4=Strati client e server disaccoppiati. Capacità di creare dashboard client leggere. home_arch5=Capacità di spingere e gestire set di dati sul client per una migliore performance. home_arch6a=Basato su home_arch6b=, un framework per la creazione di app ricche di stile workbench sul web. home_furtherinfo=Per ulteriori informazioni, visita il sito web del progetto home_license=Licenza Apache, Versione 2.0 notification_dashboard_created=Dashboard {0} creata notification_dashboard_deleted=Dashboard {0} eliminata dashboard_new_displayer=Nuovo visualizzatore dashboard_delete_popup_title=Elimina dashboard dashboard_delete_popup_content=Sei sicuro di voler eliminare questa dashboard? dashboard_delete_dashboard=Elimina dashboard salesdbpersp_salessummary=Sommario vendite salesreportspersp_salesreports=Report vendite expensesdb_title=Report spese expensesdb_tab_exp_evolution=Andamento spese expensesdb_tab_by_employee=Per dipendente expensesdb_tab_all_exp=Tutte le spese expensesdb_pie_title=Spese per Ufficio expensesdb_pie_column1=Ufficio expensesdb_pie_column2=Dipartimento expensesdb_pie_column3=Dipendente expensesdb_bar_title=Spese per Dipartimento expensesdb_bar_column1=Importo totale expensesdb_bubble_title=Spese per Dipendente expensesdb_bubble_column1=Totale expensesdb_bubble_column2=Media expensesdb_bubble_column3=Dipendente expensesdb_bubble_column4=Numero di report spese expensesdb_line_title=Andamento spese expensesdb_line_column1=Importo totale expensesdb_table_title=Elenco report spese expensesdb_table_column1=Ufficio expensesdb_table_column2=Dipartimento expensesdb_table_column3=Dipendente expensesdb_table_column4=Importo expensesdb_table_column5=Data gallerytree_home=Galleria gallerytree_home_p1=La galleria contiene esempi dal vivo di tutti i diversi tipi di visualizzatori supportati in Dashbuilder. Il nodo "Dashboard" contiene anche una serie di esempi su come combinare diversi visualizzatori in dashboard complete per gli utenti finali. gallerytree_home_s2a=Tutti gli esempi sono realizzati utilizzando l''API GWT Displayer di Dashbuilder. Se sei interessato agli interni o vuoi solo vedere come appare il codice sorgente, dai un''occhiata al seguente gallerytree_home_s2b= su GitHub. gallerytree_home_ghublink=file gallerytree_title=Albero della galleria gallerytree_bar=Grafico a barre gallerytree_bar_horiz=Orizzontale gallerytree_bar_horiz_title=Per prodotto gallerytree_bar_horiz_column1=Importo totale gallerytree_bar_vert=Verticale gallerytree_bar_vert_title=Per prodotto gallerytree_bar_vert_column1=Importo totale gallerytree_bar_vert_dd=Drill-down gallerytree_bar_vert_dd_title=Per pipeline/Stato/Venditore gallerytree_bar_vert_dd_column1=Importo totale gallerytree_bar_vert_dd_column2=Importo totale gallerytree_bar_vert_dd_column3=Importo totale gallerytree_bar_multi=Multiplo gallerytree_bar_stacked=Impilato gallerytree_bar_multi_title=Per paese (min/max/avg) gallerytree_bar_multi_column1=Min gallerytree_bar_multi_column2=Max gallerytree_bar_multi_column3=Media gallerytree_pie=Grafico a torta gallerytree_pie_basic=Base gallerytree_pie_basic_title=Per stato gallerytree_pie_basic_column1=Importo totale gallerytree_pie_3d=3D gallerytree_pie_3d_title=Per stato gallerytree_pie_3d_column1=Importo totale gallerytree_pie_donut=Anello gallerytree_pie_donut_title=Per stato gallerytree_pie_donut_column1=Importo totale gallerytree_pie_dd=Drill-down gallerytree_pie_dd_title=Per pipeline/Stato/Venditore gallerytree_pie_dd_column1=Importo totale gallerytree_pie_dd_column2=Importo totale gallerytree_pie_dd_column3=Importo totale gallerytree_line=Grafico a linee gallerytree_line_basic=Base gallerytree_line_basic_title=Evoluzione delle opportunità di vendita gallerytree_line_basic_column1=Data di chiusura gallerytree_line_basic_column2=Importo totale gallerytree_line_multi=Multiplo gallerytree_line_multi_title=Per paese (min/max/avg) gallerytree_line_multi_column1=Min gallerytree_line_multi_column2=Max gallerytree_line_multi_column3=Media gallerytree_line_multi_static=Multiplo (statico) gallerytree_line_multi_static_title=Evoluzione delle vendite per anno gallerytree_line_multi_static_column1=Vendite nel 2014 gallerytree_line_multi_static_column2=Vendite nel 2015 gallerytree_line_multi_static_column3=Vendite nel 2016 gallerytree_area=Grafico ad area gallerytree_area_basic=Base gallerytree_area_basic_title=Pipeline prevista gallerytree_area_basic_column1=Importo previsto gallerytree_area_fixed=Fisso (al mese) gallerytree_area_fixed_title=Pipeline (miglior mese) gallerytree_area_fixed_column1=Data di chiusura gallerytree_area_fixed_column2=Importo previsto al mese gallerytree_area_dd=Drill-down gallerytree_area_dd_title=Pipeline prevista gallerytree_area_dd_column1=Data di chiusura gallerytree_area_dd_column2=Importo previsto gallerytree_bubble=Grafico a bolle gallerytree_bubble_basic=Base gallerytree_bubble_basic_title=Distribuzione delle opportunità per paese gallerytree_bubble_basic_column1=Numero di opportunità gallerytree_bubble_basic_column2=Probabilità media gallerytree_bubble_basic_column3=Importo previsto gallerytree_bubble_basic_column4=Paese gallerytree_meter=Grafico a misuratore gallerytree_meter_basic=Base gallerytree_meter_basic_title=Obiettivo di vendita gallerytree_meter_basic_column1=Importo totale gallerytree_meter_multi=Multiplo gallerytree_meter_multi_title=Importo previsto per anno gallerytree_meter_multi_column1=Importo totale gallerytree_meter_multi_static=Multiplo (statico) gallerytree_meter_multi_static_title=Battito cardiaco gallerytree_meter_multi_static_column1=Persona gallerytree_meter_multi_static_column2=Battito cardiaco gallerytree_metrics=Metriche gallerytree_metrics_basic=Base gallerytree_metrics_basic_title=Vendite (trimestre corrente) gallerytree_metrics_basic_column1=Vendite (trimestre corrente) gallerytree_metrics_basic_static=Base (statico) gallerytree_metrics_basic_static_title=Tweets! gallerytree_metrics_basic_static_column1=Tweets gallerytree_map=Mappa gallerytree_map_region=Marcatori gallerytree_map_region_title=Per paese gallerytree_map_region_column1=Importo totale gallerytree_map_marker=Regioni gallerytree_map_marker_title=Per paese gallerytree_map_marker_column1=Importo totale gallerytree_table=Report tabella gallerytree_table_basic=Base gallerytree_table_basic_title=Elenco delle opportunità gallerytree_table_basic_column1=Paese gallerytree_table_basic_column2=Cliente gallerytree_table_basic_column3=Prodotto gallerytree_table_basic_column4=Venditore gallerytree_table_basic_column5=Stato gallerytree_table_basic_column6=Origine gallerytree_table_basic_column7=Creazione gallerytree_table_basic_column8=Previsto gallerytree_table_basic_column9=Chiusura gallerytree_table_basic_column10=Importo gallerytree_table_filtered=Filtrato gallerytree_table_filtered_title=Opportunità negli USA e in Brasile gallerytree_table_filtered_column1=Cliente gallerytree_table_filtered_column2=Prodotto gallerytree_table_filtered_column3=Stato gallerytree_table_filtered_column4=Origine gallerytree_table_filtered_column5=Creazione gallerytree_table_filtered_column6=Previsto gallerytree_table_filtered_column7=Chiusura gallerytree_table_filtered_column8=Importo gallerytree_table_grouped=Raggruppato gallerytree_table_grouped_title=Sommario per paese gallerytree_table_grouped_column1=Paese gallerytree_table_grouped_column2=#Opps gallerytree_table_grouped_column3=Min gallerytree_table_grouped_column4=Max gallerytree_table_grouped_column5=Media gallerytree_table_grouped_column6=Totale gallerytree_table_default_dd=Predefinito (drill-down) gallerytree_table_default_dd_title=Elenco delle opportunità gallerytree_table_default_dd_column1=Paese gallerytree_table_default_dd_column2=Cliente gallerytree_table_default_dd_column3=Prodotto gallerytree_table_default_dd_column4=Venditore gallerytree_table_default_dd_column5=Stato gallerytree_table_default_dd_column6=Origine gallerytree_table_default_dd_column7=Creazione gallerytree_table_default_dd_column8=Previsto gallerytree_table_default_dd_column9=Chiusura gallerytree_table_default_dd_column10=Importo gallerytree_selector=Selettore gallerytree_selector_dropdown=A tendina gallerytree_selector_labels=Etichette gallerytree_selector_slider=Slider gallerytree_db=Dashboard gallerytree_db_salesgoals=Obiettivi di vendita gallerytree_db_salespipe=Pipeline di vendita gallerytree_db_salespcountry=Vendite per paese gallerytree_db_salesreps=Report di vendita gallerytree_db_expreps=Report spese gallerytree_db_clustermetrics=Metriche del cluster gallerywidget_unknown=Widget di galleria sconosciuto: gallerywidget_dataset_modif=Il set di dati è stato modificato. Aggiornamento della visualizzazione... gallerywidget_dataset_loaded=Set di dati caricato dal server [{0}, {1} Kb] metrics_server_detail_title=Metriche del server (Verticale) metrics_server_detail_backbutton_tt=Torna indietro metrics_server_detail_modebutton_tt_viewtable=Visualizza come tabella metrics_server_detail_modebutton_tt_viewcharts=Visualizza come grafici metrics_server_detail_lasthour_summary=Sommario dell''ultima ora metrics_server_detail_cpu_usage=Utilizzo CPU (%) metrics_server_detail_mem_usage=Utilizzo memoria (Gb) metrics_server_detail_netw_usage=Utilizzo rete (kbps) metrics_server_detail_disk_usage=Utilizzo disco (Mb) metrics_server_detail_live_procs=Processi attivi metrics_server_detail_cpu1_title=CPU 1 % metrics_server_detail_cpu2_title=CPU 2 % metrics_server_detail_mem_title=Consumo memoria metrics_server_detail_netw_title=Larghezza di banda di rete metrics_server_detail_disk_title=Utilizzo disco metrics_server_detail_disk_column1=Spazio disco libero metrics_server_detail_disk_column2=Spazio disco utilizzato metrics_server_detail_procs_running_title=Processi in esecuzione metrics_server_detail_procs_running_column1=In esecuzione metrics_server_detail_procs_sleeping_title=Processi in attesa metrics_server_detail_procs_sleeping_column1=In attesa metrics_server_detail_rt_table_title=Metriche {0} in tempo reale metrics_server_detail_rt_table_column1=Minuto metrics_server_detail_rt_table_column2=CPU0 metrics_server_detail_rt_table_column3=CPU1 metrics_server_detail_rt_table_column4=Memoria utilizzata (Gb) metrics_server_detail_rt_table_column5=Memoria libera (Gb) metrics_server_detail_rt_table_column6=Upstream (kbps) metrics_server_detail_rt_table_column7=Downstream (kbps) metrics_server_detail_rt_table_column8=Processi in esecuzione metrics_server_detail_rt_table_column9=Processi in attesa metrics_server_detail_rt_table_column10=Disco utilizzato (Mb) metrics_server_detail_rt_table_column11=Disco libero (Mb) metrics_server_vert_title=Metriche del server (Verticale) metrics_server_vert_default_tt=Fai clic per mostrare i dettagli del server metrics_server_vert_cpu_tt=Utilizzo CPU (%) metrics_server_vert_usedmem_tt=Memoria utilizzata (Gb) metrics_server_vert_netbw_tt=Larghezza di banda di rete (kbps) metrics_server_vert_procs_tt=Processi in esecuzione/in attesa metrics_server_vert_disk_tt=Utilizzo disco (Mb) metrics_server_vert_cpu1_title=CPU 1 % metrics_server_vert_cpu2_title=CPU 2 % metrics_server_vert_memconsumption_title=Consumo memoria metrics_server_vert_netbw_title=Larghezza di banda di rete metrics_server_vert_procs_title=Processi in esecuzione/in attesa metrics_server_vert_du_title=Utilizzo disco metrics_server_vert_du_free=Disco libero (Mb) metrics_server_vert_du_used=Disco utilizzato (Mb) metrics_server_vert_serverdown={0} è inattivo metrics_cluster_title=Metriche del cluster metrics_cluster_messages_heading=Inizializzazione dashboard... metrics_cluster_metricselector_label=Metrica metrics_cluster_chartselector_label=Tipo di grafico metrics_cluster_metricselector_cpu=Utilizzo CPU (%) metrics_cluster_metricselector_mem=Memoria metrics_cluster_metricselector_disk=Disco metrics_cluster_metricselector_netw=Rete metrics_cluster_metricselector_proc=Processi metrics_cluster_chartselector_bar=Barra metrics_cluster_chartselector_line=Linea metrics_cluster_chartselector_area=Area metrics_cluster_column_cpu=Utilizzo CPU (%) metrics_cluster_column_cpu_y=Utilizzo CPU (%) metrics_cluster_column_df=Spazio disco libero metrics_cluster_column_df_y=Gigabyte metrics_cluster_column_du=Spazio disco utilizzato metrics_cluster_column_du_y=Gigabyte metrics_cluster_column_memf=Memoria libera metrics_cluster_column_memf_y=Gigabyte metrics_cluster_column_memu=Memoria utilizzata metrics_cluster_column_memu_y=Gigabyte metrics_cluster_column_procsrn=Processi in esecuzione metrics_cluster_column_procsrn_y=Processi metrics_cluster_column_procssl=Processi in attesa metrics_cluster_column_procssl_y=Processi metrics_cluster_column_netrx=Ricezione rete metrics_cluster_column_netrx_y=Kb/s metrics_cluster_column_nettx=Trasmissione rete metrics_cluster_column_nettx_y=Kb/s metrics_cluster_column_time=Tempo metrics_rt_title=Metriche di sistema (Tempo reale) metrics_rt_serverup= è attivo metrics_rt_serverdown= è inattivo sales_bycountry_title=Vendite per paese sales_bycountry_bubble_title=Distribuzione delle opportunità per paese sales_bycountry_bubble_column1=Numero di opportunità sales_bycountry_bubble_column2=Probabilità media sales_bycountry_bubble_column3=Importo previsto sales_bycountry_map_title=Per paese sales_bycountry_map_column1=Importo totale sales_bycountry_table_title=Elenco delle opportunità sales_bycountry_table_column1=Paese sales_bycountry_table_column2=Cliente sales_bycountry_table_column3=Prodotto sales_bycountry_table_column4=Venditore sales_bycountry_table_column5=Stato sales_bycountry_table_column6=Creazione sales_bycountry_table_column7=Previsto sales_bycountry_table_column8=Chiusura sales_bycountry_table_column9=Importo sales_bydate_title=Pipeline di vendita sales_bydate_area_title=Pipeline prevista sales_bydate_area_column1=Importo sales_bydate_pie_years_title=Anno sales_bydate_pie_years_column1=Occorrenze sales_bydate_pie_quarters_title=Trimestre sales_bydate_pie_quarters_column1=Occorrenze sales_bydate_bar_weekday_title=Giorno della settimana sales_bydate_bar_weekday_column1=Occorrenze sales_bydate_pie_pipe_title=Pipeline sales_bydate_pie_pipe_column1=Numero di opportunità sales_bydate_table_title=Elenco delle opportunità sales_bydate_table_column1=Paese sales_bydate_table_column2=Cliente sales_bydate_table_column3=Prodotto sales_bydate_table_column4=Venditore sales_bydate_table_column5=Stato sales_bydate_table_column6=Importo sales_bydate_table_column7=Previsto sales_bydate_table_column8=Creazione sales_bydate_table_column9=Chiusura sales_bydate_selector_total=Totale sales_goals_title=Obiettivi di vendita sales_goals_meter_title=Obiettivo di vendita sales_goals_meter_column1=Importo totale sales_goals_line_title=Pipeline prevista sales_goals_line_column1=Data di chiusura sales_goals_line_column2=Importo totale sales_goals_line_column3=Importo previsto sales_goals_bar_byproduct_title=Per prodotto sales_goals_bar_byproduct_column1=Prodotto sales_goals_bar_byproduct_column2=Importo totale sales_goals_bar_byproduct_column3=Importo previsto sales_goals_bar_byempl_title=Per dipendente sales_goals_bar_byempl_column1=Dipendente sales_goals_bar_byempl_column2=Importo sales_goals_bubble_title=Distribuzione delle opportunità per paese sales_goals_bubble_column1=Numero di opportunità sales_goals_bubble_column2=Probabilità media sales_goals_bubble_column3=Importo previsto sales_tablereports_title=Report di vendita sales_tablereports_tab_byyear=Per anno sales_tablereports_tab_bycountry=Per paese sales_tablereports_tab_byproduct=Per prodotto sales_tablereports_tab_bysalesman=Per venditore sales_tablereports_all_title=Elenco delle opportunità sales_tablereports_all_column1=Paese sales_tablereports_all_column2=Cliente sales_tablereports_all_column3=Prodotto sales_tablereports_all_column4=Venditore sales_tablereports_all_column5=Stato sales_tablereports_all_column6=Creazione sales_tablereports_all_column7=Previsto sales_tablereports_all_column8=Chiusura sales_tablereports_all_column9=Importo sales_tablereports_bycountry_title=Sommario per paese sales_tablereports_bycountry_column1=Paese sales_tablereports_bycountry_column2=#Opportunità sales_tablereports_bycountry_column3=Minimo sales_tablereports_bycountry_column4=Massimo sales_tablereports_bycountry_column5=Media sales_tablereports_bycountry_column6=Totale sales_tablereports_byproduct_title=Sommario per prodotto sales_tablereports_byproduct_column1=Prodotto sales_tablereports_byproduct_column2=#Opportunità sales_tablereports_byproduct_column3=Minimo sales_tablereports_byproduct_column4=Massimo sales_tablereports_byproduct_column5=Media sales_tablereports_byproduct_column6=Totale sales_tablereports_bysalesman_title=Vendite per venditore sales_tablereports_bysalesman_column1=Venditore sales_tablereports_bysalesman_column2=#Opportunità sales_tablereports_bysalesman_column3=Minimo sales_tablereports_bysalesman_column4=Massimo sales_tablereports_bysalesman_column5=Media sales_tablereports_bysalesman_column6=Totale sales_tablereports_byyear_title=Sommario per anno sales_tablereports_byyear_column1=Data di creazione sales_tablereports_byyear_column2=#Opportunità sales_tablereports_byyear_column3=Minimo sales_tablereports_byyear_column4=Massimo sales_tablereports_byyear_column5=Media sales_tablereports_byyear_column6=Totale salesopps_displayers_by_pipeline_title=Stato della pipeline salesopps_displayers_by_status_title=Per stato salesopps_displayers_by_salesman_title=Per venditore salesopps_displayers_by_exp_pipeline_title=Importo previsto salesopps_displayers_by_exp_pipeline_column1=Importo previsto salesopps_displayers_by_product_title=Per prodotto salesopps_displayers_by_product_column1=Importo totale salesopps_displayers_by_country_title=Per paese salesopps_displayers_by_country_column1=Importo totale salesopps_displayers_country_summary_title=Sommario per paese salesopps_displayers_country_summary_column1=PAESE salesopps_displayers_country_summary_column2=TOTALE salesopps_displayers_country_summary_column3=NUMERO salesopps_displayers_country_summary_column4=MEDIA salesopps_displayers_country_summary_column5=MINIMO salesopps_displayers_country_summary_column6=MASSIMO salesopps_displayers_all_list_title=Elenco delle opportunità content_manager_dashboard=dashboard content_manager_dashboards=dashboards content_manager_noDashboards=Nessuna dashboard HomeScreenView.title=Benvenuto in Dashbuilder HomeScreenView.subTitle=Dashbuilder offre strumenti per creare Business Dashboard. Seleziona uno strumento di seguito per iniziare ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_ja.properties ================================================ # # Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # logoBannerError=バナーをロードできませんでした。 logOut=ログアウト role=ロール menu_home=ホーム menu_gallery=ギャラリー menu_administration=管理 menu_security=セキュリティー menu_dataset_authoring=データセット menu_content_manager=コンテンツマネージャー menu_extensions_apps=アプリケーション menu_dashboards=ダッシュボード menu_dashboards_salesdb=売上ダッシュボード menu_dashboards_salesreports=売上レポート menu_dashboards_new=- 新規 - home_intro=Dashbuilder は汎用目的のダッシュボードおよびレポーティング web アプリケーションで、以下を可能にします。 home_upcoming=次回の機能 home_feature1=ダッシュボードの視覚設定およびパーソナル化 home_feature2=複数のグラフ作成ライブラリーを使用した異なるタイプの視覚化サポート home_feature3=データセット定義作成のための UI エディター home_feature4=グラフ作成視覚化の定義のための完全機能エディター home_feature5=インタラクティブなレポート表の定義 home_feature6=異なるプロトコルによる外部システムからのデータ抽出 home_feature7=アナリティクスおよびリアルタイムの両ダッシュボードのサポート home_feature8=D3 JS & Lienzo GWT をベースにした新規レンダラー home_feature9=階層的 (入れ子グループ) ディスプレイヤータイプ: ツリー & パイ home_feature10=複数のデータシリーズをサポート home_feature11=豊富なモビリティーサポート home_feature12=アラートおよび SLA 設定 home_feature13=RESTful API home_arch=アーキテクチャー home_arch1=図表レンダリング技術に関連付けられていません。プラグ可能なレンダラー。 home_arch2=データストレージに関連付けられていません。 home_arch3=CSV ファイル、データベース、または Java ジェネレーターからデータを読み取る機能。 home_arch4=分離されたクライアント層とサーバー層。純粋に軽量なクライアントダッシュボードを構築する機能。 home_arch5=パフォーマンス改善のためにクライアント上でデータセットをプッシュおよび処理する機能。 home_arch6a=ベースとなっているのは home_arch6b=Web 上のリッチなワークベンチスタイルのアプリケーションを構築するためのフレームワーク。 home_furtherinfo=詳細情報は、プロジェクトの web ページを参照してください。 home_license=Licensed under the Apache License, Version 2.0 notification_dashboard_created={0} ダッシュボードが作成されました notification_dashboard_deleted={0} ダッシュボードが削除されました dashboard_new_displayer=新規ディスプレイヤー dashboard_delete_popup_title=ダッシュボードの削除 dashboard_delete_popup_content=このダッシュボードを削除してもよろしいですか? dashboard_delete_dashboard=ダッシュボードの削除 salesdbpersp_salessummary=売上サマリー salesreportspersp_salesreports=売上レポート expensesdb_title=費用レポート expensesdb_tab_exp_evolution=費用の経過 expensesdb_tab_by_employee=従業員別 expensesdb_tab_all_exp=すべての費用 expensesdb_pie_title=オフィス別費用 expensesdb_pie_column1=オフィス expensesdb_pie_column2=部門 expensesdb_pie_column3=従業員 expensesdb_bar_title=部門別費用 expensesdb_bar_column1=合計金額 expensesdb_bubble_title=従業員別費用" expensesdb_bubble_column1=合計 expensesdb_bubble_column2=平均 expensesdb_bubble_column3=従業員 expensesdb_bubble_column4=費用レポートの数 expensesdb_line_title=費用の経過 expensesdb_line_column1=合計金額 expensesdb_table_title=費用レポートのリスト expensesdb_table_column1=オフィス expensesdb_table_column2=部門 expensesdb_table_column3=従業員 expensesdb_table_column4=金額 expensesdb_table_column5=日付 gallerytree_home=ギャラリー gallerytree_home_p1=ギャラリーには、Dashbuilder でサポートされる各種ディスプレイヤータイプがすべて実例として含まれています。「ダッシュボード」ノードには、複数のディスプレイヤーをフル機能が搭載されたエンドユーザーダッシュボードに統合する方法の例も含まれています。 gallerytree_home_s2a=例はすべて、Dashbuilder の GWT ディスプレイヤー API を使って構築されます。内部機能やソースコードに興味がある場合は、 gallerytree_home_s2b=GitHub で参照してください。 gallerytree_home_ghublink=ファイル gallerytree_title=ギャラリーツリー gallerytree_bar=棒グラフ gallerytree_bar_horiz=水平 gallerytree_bar_horiz_title=製品別 gallerytree_bar_horiz_column1=合計金額 gallerytree_bar_vert=垂直 gallerytree_bar_vert_title=製品別 gallerytree_bar_vert_column1=合計金額 gallerytree_bar_vert_dd=ドリルダウン gallerytree_bar_vert_dd_title=パイプライン別/ステータス別/営業担当者別 gallerytree_bar_vert_dd_column1=合計金額 gallerytree_bar_vert_dd_column2=合計金額 gallerytree_bar_vert_dd_column3=合計金額 gallerytree_bar_multi=複数 gallerytree_bar_stacked=スタック gallerytree_bar_multi_title=国別 (最小/最大/平均) gallerytree_bar_multi_column1=最小 gallerytree_bar_multi_column2=最大 gallerytree_bar_multi_column3=平均 gallerytree_pie=円グラフ gallerytree_pie_basic=ベーシック gallerytree_pie_basic_title=ステータス gallerytree_pie_basic_column1=合計金額 gallerytree_pie_3d=3D gallerytree_pie_3d_title=ステータス gallerytree_pie_3d_column1=合計金額 gallerytree_pie_donut=ドーナツ gallerytree_pie_donut_title=ステータス gallerytree_pie_donut_column1=合計金額 gallerytree_pie_dd=ドリルダウン gallerytree_pie_dd_title=パイプライン別/ステータス別/営業担当者別 gallerytree_pie_dd_column1=合計金額 gallerytree_pie_dd_column2=合計金額 gallerytree_pie_dd_column3=合計金額 gallerytree_line=折れ線グラフ gallerytree_line_basic=ベーシック gallerytree_line_basic_title=売上機会の経過 gallerytree_line_basic_column1=終了日 gallerytree_line_basic_column2=合計金額 gallerytree_line_multi=複数 gallerytree_line_multi_title=国別 (最小/最大/平均) gallerytree_line_multi_column1=最小 gallerytree_line_multi_column2=最大 gallerytree_line_multi_column3=平均 gallerytree_line_multi_static=複数 (静的) gallerytree_line_multi_static_title=年間売上経過 gallerytree_line_multi_static_column1=2014 年の売上 gallerytree_line_multi_static_column2=2015 年の売上 gallerytree_line_multi_static_column3=2016 年の売上 gallerytree_area=エリアチャート gallerytree_area_basic=ベーシック gallerytree_area_basic_title=予測パイプライン gallerytree_area_basic_column1=予測金額 gallerytree_area_fixed=固定 (月別) gallerytree_area_fixed_title=パイプライン (最良月) gallerytree_area_fixed_column1=終了日 gallerytree_area_fixed_column2=1 か月あたりの予測金額 gallerytree_area_dd=ドリルダウン gallerytree_area_dd_title=予測パイプライン gallerytree_area_dd_column1=終了日 gallerytree_area_dd_column2=予測金額 gallerytree_bubble=バブルチャート gallerytree_bubble_basic=ベーシック gallerytree_bubble_basic_title=国別の機会配分 gallerytree_bubble_basic_column1=機会の数 gallerytree_bubble_basic_column2=平均確率 gallerytree_bubble_basic_column3=予測金額 gallerytree_bubble_basic_column4=国 gallerytree_meter=メーターチャート gallerytree_meter_basic=ベーシック gallerytree_meter_basic_title=売上目標 gallerytree_meter_basic_column1=合計金額 gallerytree_meter_multi=複数 gallerytree_meter_multi_title=1 年あたりの予測金額 gallerytree_meter_multi_column1=合計金額 gallerytree_meter_multi_static=複数 (静的) gallerytree_meter_multi_static_title=心拍数 gallerytree_meter_multi_static_column1=担当者 gallerytree_meter_multi_static_column2=心拍数 gallerytree_metrics=メトリックス gallerytree_metrics_basic=ベーシック gallerytree_metrics_basic_title=売上 (本四半期) gallerytree_metrics_basic_column1=売上 (本四半期) gallerytree_metrics_basic_static=基本 (静的) gallerytree_metrics_basic_static_title=ツイート! gallerytree_metrics_basic_static_column1=ツイート gallerytree_map=マップ gallerytree_map_region=マーカー gallerytree_map_region_title=国別 gallerytree_map_region_column1=合計金額 gallerytree_map_marker=リージョン gallerytree_map_marker_title=国別 gallerytree_map_marker_column1=合計金額 gallerytree_table=テーブルレポート gallerytree_table_basic=ベーシック gallerytree_table_basic_title=機会のリスト gallerytree_table_basic_column1=国 gallerytree_table_basic_column2=顧客 gallerytree_table_basic_column3=製品 gallerytree_table_basic_column4=営業担当者 gallerytree_table_basic_column5=状態 gallerytree_table_basic_column6=ソース gallerytree_table_basic_column7=作成 gallerytree_table_basic_column8=予測 gallerytree_table_basic_column9=終了日 gallerytree_table_basic_column10=金額 gallerytree_table_filtered=フィルター gallerytree_table_filtered_title=米国 & ブラジルの機会 gallerytree_table_filtered_column1=顧客 gallerytree_table_filtered_column2=製品 gallerytree_table_filtered_column3=状態 gallerytree_table_filtered_column4=ソース gallerytree_table_filtered_column5=作成 gallerytree_table_filtered_column6=予測 gallerytree_table_filtered_column7=終了日 gallerytree_table_filtered_column8=金額 gallerytree_table_grouped=グループ化 gallerytree_table_grouped_title=国サマリー gallerytree_table_grouped_column1=国 gallerytree_table_grouped_column2=#機会 gallerytree_table_grouped_column3=最小 gallerytree_table_grouped_column4=最大 gallerytree_table_grouped_column5=平均 gallerytree_table_grouped_column6=合計 gallerytree_table_default_dd=デフォルト (ドリルダウン) gallerytree_table_default_dd_title=機会のリスト gallerytree_table_default_dd_column1=国 gallerytree_table_default_dd_column2=顧客 gallerytree_table_default_dd_column3=製品 gallerytree_table_default_dd_column4=営業担当者 gallerytree_table_default_dd_column5=状態 gallerytree_table_default_dd_column6=ソース gallerytree_table_default_dd_column7=作成 gallerytree_table_default_dd_column8=予測 gallerytree_table_default_dd_column9=終了日 gallerytree_table_default_dd_column10=金額 gallerytree_selector=セレクター gallerytree_selector_dropdown=ドロップダウン gallerytree_selector_labels=ラベル gallerytree_selector_slider=スライダー gallerytree_db=ダッシュボード gallerytree_db_salesgoals=売上目標 gallerytree_db_salespipe=売上パイプライン gallerytree_db_salespcountry=国別売上 gallerytree_db_salesreps=売上レポート gallerytree_db_expreps=費用レポート gallerytree_db_clustermetrics=クラスターメトリクス gallerywidget_unknown=未知のギャラリーウィジェット: gallerywidget_dataset_modif=データセットが変更されました。ビューを更新中 ... gallerywidget_dataset_loaded=データセットがサーバー [{0} からロードされました。{1} Kb] metrics_server_detail_title=サーバーメトリクス (垂直) metrics_server_detail_backbutton_tt=戻る metrics_server_detail_modebutton_tt_viewtable=テーブルとして表示 metrics_server_detail_modebutton_tt_viewcharts=チャートとして表示 metrics_server_detail_lasthour_summary=過去 1 時間のサマリー metrics_server_detail_cpu_usage=CPU 使用率 (%) metrics_server_detail_mem_usage=メモリー使用量 (Gb) metrics_server_detail_netw_usage=ネットワーク使用量 (kbps) metrics_server_detail_disk_usage=ディスク使用量 (Mb) metrics_server_detail_live_procs=ライブプロセス metrics_server_detail_cpu1_title=CPU 1 % metrics_server_detail_cpu2_title=CPU 2 % metrics_server_detail_mem_title=メモリー消費 metrics_server_detail_netw_title=ネットワーク帯域幅 metrics_server_detail_disk_title=ディスク使用量 metrics_server_detail_disk_column1=空きディスク容量 metrics_server_detail_disk_column2=使用済みディスク容量 metrics_server_detail_procs_running_title=実行中プロセス metrics_server_detail_procs_running_column1=実行中 metrics_server_detail_procs_sleeping_title=スリープ状態のプロセス metrics_server_detail_procs_sleeping_column1=スリープ状態 metrics_server_detail_rt_table_title=リアルタイムの {0} メトリクス metrics_server_detail_rt_table_column1=分 metrics_server_detail_rt_table_column2=CPU0 metrics_server_detail_rt_table_column3=CPU1 metrics_server_detail_rt_table_column4=使用済みメモリー容量 (Gb) metrics_server_detail_rt_table_column5=空きメモリー容量 (Gb) metrics_server_detail_rt_table_column6=アップストリーム (kbps) metrics_server_detail_rt_table_column7=ダウンストリーム (kbps) metrics_server_detail_rt_table_column8=実行中プロセス metrics_server_detail_rt_table_column9=スリープ状態のプロセス metrics_server_detail_rt_table_column10=使用済みディスク容量 (Mb) metrics_server_detail_rt_table_column11=空きディスク容量 (Mb) metrics_server_vert_title=サーバーメトリクス (垂直) metrics_server_vert_default_tt=サーバーの詳細を表示するためにクリック metrics_server_vert_cpu_tt=CPU 使用率 (%) metrics_server_vert_usedmem_tt=使用済みメモリー容量 (Gb) metrics_server_vert_netbw_tt=ネットワーク BW (kbps) metrics_server_vert_procs_tt=実行中/スリープ状態のプロセス metrics_server_vert_disk_tt=ディスク使用量 (Mb) metrics_server_vert_cpu1_title=CPU 1 % metrics_server_vert_cpu2_title=CPU 2 % metrics_server_vert_memconsumption_title=メモリー消費 metrics_server_vert_netbw_title=ネットワーク帯域幅 metrics_server_vert_procs_title=実行中/スリープ状態のプロセス metrics_server_vert_du_title=ディスク使用量 metrics_server_vert_du_free=空きディスク容量 (Mb) metrics_server_vert_du_used=使用済みディスク容量 (Mb) metrics_server_vert_serverdown={0} がダウン metrics_cluster_title=クラスターメトリクス metrics_cluster_messages_heading=ダッシュボードの初期化中 ... metrics_cluster_metricselector_label=メトリック metrics_cluster_chartselector_label=チャートのタイプ metrics_cluster_metricselector_cpu=CPU % metrics_cluster_metricselector_mem=メモリー metrics_cluster_metricselector_disk=ディスク metrics_cluster_metricselector_netw=ネットワーク metrics_cluster_metricselector_proc=プロセス metrics_cluster_chartselector_bar=バー metrics_cluster_chartselector_line=Line metrics_cluster_chartselector_area=エリア metrics_cluster_column_cpu=CPU % metrics_cluster_column_cpu_y=CPU % metrics_cluster_column_df=空きディスク容量 metrics_cluster_column_df_y=ギガバイト metrics_cluster_column_du=使用済みディスク容量 metrics_cluster_column_du_y=ギガバイト metrics_cluster_column_memf=空きメモリー容量 metrics_cluster_column_memf_y=ギガバイト metrics_cluster_column_memu=使用済みメモリー容量 metrics_cluster_column_memu_y=ギガバイト metrics_cluster_column_procsrn=実行中プロセス metrics_cluster_column_procsrn_y=プロセス metrics_cluster_column_procssl=スリープ状態のプロセス metrics_cluster_column_procssl_y=プロセス metrics_cluster_column_netrx=ネット。Rx metrics_cluster_column_netrx_y=Kb/s metrics_cluster_column_nettx=ネット。Tx metrics_cluster_column_nettx_y=Kb/s metrics_cluster_column_time=時間 metrics_rt_title=システムメトリクス (リアルタイム) metrics_rt_serverup= 稼働 metrics_rt_serverdown= ダウン sales_bycountry_title=国別売上 sales_bycountry_bubble_title=国別の機会配分 sales_bycountry_bubble_column1=機会の数 sales_bycountry_bubble_column2=平均確率 sales_bycountry_bubble_column3=予測金額 sales_bycountry_map_title=国別 sales_bycountry_map_column1=合計金額 sales_bycountry_table_title=機会のリスト sales_bycountry_table_column1=国 sales_bycountry_table_column2=顧客 sales_bycountry_table_column3=製品 sales_bycountry_table_column4=営業担当者 sales_bycountry_table_column5=状態 sales_bycountry_table_column6=作成 sales_bycountry_table_column7=予測 sales_bycountry_table_column8=終了日 sales_bycountry_table_column9=金額 sales_bydate_title=売上パイプライン sales_bydate_area_title=予測パイプライン sales_bydate_area_column1=金額 sales_bydate_pie_years_title=年 sales_bydate_pie_years_column1=発生 sales_bydate_pie_quarters_title=四半期 sales_bydate_pie_quarters_column1=発生 sales_bydate_bar_weekday_title=曜日 sales_bydate_bar_weekday_column1=発生 sales_bydate_pie_pipe_title=パイプライン sales_bydate_pie_pipe_column1=機会の数 sales_bydate_table_title=機会のリスト sales_bydate_table_column1=国 sales_bydate_table_column2=顧客 sales_bydate_table_column3=製品 sales_bydate_table_column4=営業担当者 sales_bydate_table_column5=状態 sales_bydate_table_column6=金額 sales_bydate_table_column7=予測 sales_bydate_table_column8=作成 sales_bydate_table_column9=終了日 sales_bydate_selector_total=合計 sales_goals_title=売上目標 sales_goals_meter_title=売上目標 sales_goals_meter_column1=合計金額 sales_goals_line_title=予測パイプライン sales_goals_line_column1=終了日 sales_goals_line_column2=合計金額 sales_goals_line_column3=予測金額 sales_goals_bar_byproduct_title=製品別 sales_goals_bar_byproduct_column1=製品 sales_goals_bar_byproduct_column2=合計 sales_goals_bar_byproduct_column3=予測 sales_goals_bar_byempl_title=従業員別 sales_goals_bar_byempl_column1=従業員 sales_goals_bar_byempl_column2=金額 sales_goals_bubble_title=国別の機会配分 sales_goals_bubble_column1=機会の数 sales_goals_bubble_column2=平均確率 sales_goals_bubble_column3=予測金額 sales_tablereports_title=売上レポート sales_tablereports_tab_byyear=年別 sales_tablereports_tab_bycountry=国別 sales_tablereports_tab_byproduct=製品別 sales_tablereports_tab_bysalesman=営業担当者別 sales_tablereports_all_title=機会のリスト sales_tablereports_all_column1=国 sales_tablereports_all_column2=顧客 sales_tablereports_all_column3=製品 sales_tablereports_all_column4=営業担当者 sales_tablereports_all_column5=状態 sales_tablereports_all_column6=作成 sales_tablereports_all_column7=予測 sales_tablereports_all_column8=終了日 sales_tablereports_all_column9=金額 sales_tablereports_bycountry_title=国サマリー sales_tablereports_bycountry_column1=国 sales_tablereports_bycountry_column2=#機会 sales_tablereports_bycountry_column3=最小 sales_tablereports_bycountry_column4=最大 sales_tablereports_bycountry_column5=平均 sales_tablereports_bycountry_column6=合計 sales_tablereports_byproduct_title=製品サマリー sales_tablereports_byproduct_column1=製品 sales_tablereports_byproduct_column2=#機会 sales_tablereports_byproduct_column3=最小 sales_tablereports_byproduct_column4=最大 sales_tablereports_byproduct_column5=平均 sales_tablereports_byproduct_column6=合計 sales_tablereports_bysalesman_title=担当者別売上 sales_tablereports_bysalesman_column1=営業担当者 sales_tablereports_bysalesman_column2=#機会 sales_tablereports_bysalesman_column3=最小 sales_tablereports_bysalesman_column4=最大 sales_tablereports_bysalesman_column5=平均 sales_tablereports_bysalesman_column6=合計 sales_tablereports_byyear_title=年度サマリー sales_tablereports_byyear_column1=作成日 sales_tablereports_byyear_column2=#機会 sales_tablereports_byyear_column3=最小 sales_tablereports_byyear_column4=最大 sales_tablereports_byyear_column5=平均 sales_tablereports_byyear_column6=合計 salesopps_displayers_by_pipeline_title=パイプラインステータス salesopps_displayers_by_status_title=ステータス salesopps_displayers_by_salesman_title=営業担当者別 salesopps_displayers_by_exp_pipeline_title=予測金額 salesopps_displayers_by_exp_pipeline_column1=予測金額 salesopps_displayers_by_product_title=製品別 salesopps_displayers_by_product_column1=合計金額 salesopps_displayers_by_country_title=国別 salesopps_displayers_by_country_column1=合計金額 salesopps_displayers_country_summary_title=国サマリー salesopps_displayers_country_summary_column1=国 salesopps_displayers_country_summary_column2=合計 salesopps_displayers_country_summary_column3=数値 salesopps_displayers_country_summary_column4=平均 salesopps_displayers_country_summary_column5=最小 salesopps_displayers_country_summary_column6=最大 salesopps_displayers_all_list_title=機会のリスト content_manager_dashboard=ダッシュボード content_manager_dashboards=ダッシュボード content_manager_noDashboards=ダッシュボードがありません HomeScreenView.title=Dashbuilder にようこそ HomeScreenView.subTitle=Dashbuilder には、Business Dashboards を作成するツールが含まれます。開始するには、以下からツールを選択します。 ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_pt_BR.properties ================================================ logoBannerError=Falha ao carregar o banner. logOut=Sair role=Função menu_home=Página Principal menu_gallery=Galería menu_extensions_apps=Aplicativos menu_dashboards=Painéis menu_dashboards_salesdb=Painel de vendas menu_dashboards_salesreports=Relatório de Vendas menu_dashboards_new=- Novo - home_intro=O Dashbuilder serve como um painel de uso geral e um aplicativo web para notificações que permite\: home_upcoming=Recursos futuros home_feature1=Configuração visual e personalização de paineis home_feature2=Suporte para tipos diferentes de visualização usando diversas bibliotecas de gráficos home_feature3=Editor da IU para a criação de definições de conjuntos de dados home_feature4=Editor com todos os recursos para a definição das visualizações de gráficos home_feature5=Definição das tabelas interativas de relatórios home_feature6=Extração de dados com sistemas externos, através de diferentes protocolos home_feature7=Suporte tanto para paineis de análise quanto de tempo real home_feature8=Novos renderizadores baseados em D3 JS & Lienzo GWT home_feature9=Tipos de exibidores (grupo aninhado) hierárquicos\: Árvore & Gráfico de Setores home_feature10=Suporte para múltiplas séries de dados home_feature11=Suporte para mobilidade avançada home_feature12=Configuração de SLA e alertas home_feature13=API RESTful home_arch=Arquitetura home_arch1=Não associada a nenhuma tecnologia de renderização de gráficos. Renderizadores conectáveis. home_arch2=Não associada a nenhum armazenamento de dados. home_arch3=Abilidade de ler dados de\: arquivos CSV, bancos de dados, pesquisa elástica ou geradores de Java. home_arch4=Camadas de servidor & cliente separadas. Abilidade de construir paineis do cliente leves e puros. home_arch5=Abilidade de extrair & lidar com conjuntos de dados no painel do cliente para um melhor desempenho. home_arch6a=Baseado no home_arch6b=, um framework para a criação de aplicativos baseado em workbench de estilo avançado na web. home_furtherinfo=Para mais informações, visite o site do projeto home_license=Licenciado nos termos da Apache License, Versão 2.0 notification_dashboard_created={0} painéis criados notification_dashboard_deleted={0} painéis removidos dashboard_new_displayer=Novo Exibidor dashboard_delete_popup_title=Remover painel dashboard_delete_popup_content=Você tem certeza que deseja excluir este painel? dashboard_delete_dashboard=Remover painel salesdbpersp_salessummary=Sumário de Vendas salesreportspersp_salesreports=Relatório de Vendas expensesdb_title=Relatório de despesas expensesdb_tab_exp_evolution=Evolução de Despesas expensesdb_tab_by_employee=Por Funcionário expensesdb_tab_all_exp=Todas as Despesas expensesdb_pie_title=Despesas por Escritório expensesdb_pie_column1=Escritório expensesdb_pie_column2=Departamento expensesdb_pie_column3=Funcionário expensesdb_bar_title=Despesas por Departamento expensesdb_bar_column1=Quantia Total expensesdb_bubble_title=Despesas por Funcionário" expensesdb_bubble_column1=Total expensesdb_bubble_column2=Média expensesdb_bubble_column3=Funcionário expensesdb_bubble_column4=Número de relatórios de despesas expensesdb_line_title=Evolução de despesas expensesdb_line_column1=Quantia Total expensesdb_table_title=Lista de relatório de despesas expensesdb_table_column1=Escritório expensesdb_table_column2=Departamento expensesdb_table_column3=Funcionário expensesdb_table_column4=Quantia expensesdb_table_column5=Data gallerytree_home=Galeria gallerytree_home_p1=A galeria contém exemplos de todos os tipos de exibidores com suporte no Dashbuilder. O nó "Paineis" (dashboards) também contém exemplos de como combinar vários exibidores em paineis com todos os recursos para o usuário final. gallerytree_home_s2a=Todos os exemplos são criados usando a API do Exibidor GWT do Dashbuilder. Caso esteja interessado no funcionamento interno ou gostaria de ver como é o código fonte, veja o seguinte gallerytree_home_s2b=no GitHub. gallerytree_home_ghublink=arquivo gallerytree_title=Árvore da Galeria gallerytree_bar=Gráfico de Barra gallerytree_bar_horiz=Horizontal gallerytree_bar_horiz_title=Pelo produto gallerytree_bar_horiz_column1=Quantia Total gallerytree_bar_vert=Vertical gallerytree_bar_vert_title=Pelo produto gallerytree_bar_vert_column1=Quantia Total gallerytree_bar_vert_dd=Drill-down gallerytree_bar_vert_dd_title=Por Pipeline/Status/Vendedor gallerytree_bar_vert_dd_column1=Quantia Total gallerytree_bar_vert_dd_column2=Quantia Total gallerytree_bar_vert_dd_column3=Quantia Total gallerytree_bar_multi=Múltiplo gallerytree_bar_stacked=Empilhado gallerytree_bar_multi_title=Por país (min/max/média) gallerytree_bar_multi_column1=Min gallerytree_bar_multi_column2=Max gallerytree_bar_multi_column3=Média gallerytree_pie=Gráfico torta gallerytree_pie_basic=Básico gallerytree_pie_basic_title=Por status gallerytree_pie_basic_column1=Quantia Total gallerytree_pie_3d=3d gallerytree_pie_3d_title=Por status gallerytree_pie_3d_column1=Quantia Total gallerytree_pie_donut=Donut gallerytree_pie_donut_title=Por status gallerytree_pie_donut_column1=Quantia Total gallerytree_pie_dd=Drill-down gallerytree_pie_dd_title=Por Pipeline/Status/Vendedor gallerytree_pie_dd_column1=Quantia Total gallerytree_pie_dd_column2=Quantia Total gallerytree_pie_dd_column3=Quantia Total gallerytree_line=Gráfico de linha gallerytree_line_basic=Básico gallerytree_line_basic_title=Evolução das oportunidades de vendas gallerytree_line_basic_column1=Data de encerramento gallerytree_line_basic_column2=Quantia Total gallerytree_line_multi=Múltiplo gallerytree_line_multi_title=Por país (min/max/média) gallerytree_line_multi_column1=Min gallerytree_line_multi_column2=Max gallerytree_line_multi_column3=Média gallerytree_line_multi_static=Múltiplo (estático) gallerytree_line_multi_static_title=Evolução de vendas Por Ano gallerytree_line_multi_static_column1=Vendas em 2014 gallerytree_line_multi_static_column2=Vendas em 2015 gallerytree_line_multi_static_column3=Vendas em 2016 gallerytree_area=Gráfico de Área gallerytree_area_basic=Básico gallerytree_area_basic_title=Pipeline Esperada gallerytree_area_basic_column1=Quantia esperada gallerytree_area_fixed=Fixo (por mês) gallerytree_area_fixed_title=Pipeline (melhor mês) gallerytree_area_fixed_column1=Data de encerramento gallerytree_area_fixed_column2=Quantia esperada por mês gallerytree_area_dd=Drill-down gallerytree_area_dd_title=Pipeline Esperada gallerytree_area_dd_column1=Data de encerramento gallerytree_area_dd_column2=Quantia esperada gallerytree_bubble=Gráfico Bubble gallerytree_bubble_basic=Básico gallerytree_bubble_basic_title=Oportunidades de distribuição por país gallerytree_bubble_basic_column1=número de oportunidades gallerytree_bubble_basic_column2=Probabilidade de média gallerytree_bubble_basic_column3=Quantia esperada gallerytree_bubble_basic_column4=País gallerytree_meter=Gráfico medidor gallerytree_meter_basic=Básico gallerytree_meter_basic_title=Objetivo de Vendas gallerytree_meter_basic_column1=Quantia Total gallerytree_meter_multi=Múltiplo gallerytree_meter_multi_title=Quantia esperada por ano gallerytree_meter_multi_column1=Quantia Total gallerytree_meter_multi_static=Múltiplo (estático) gallerytree_meter_multi_static_title=Rítmo cardíaco gallerytree_meter_multi_static_column1=Pessoa gallerytree_meter_multi_static_column2=Rítmo cardíaco gallerytree_metrics=Métricas gallerytree_metrics_basic=Básico gallerytree_metrics_basic_title=Vendas (trimestre atual) gallerytree_metrics_basic_column1=Vendas (trimestre atual) gallerytree_metrics_basic_static=Básico (estático) gallerytree_metrics_basic_static_title=Tweets\! gallerytree_metrics_basic_static_column1=Tweets gallerytree_map=Mapa gallerytree_map_region=Marcadores gallerytree_map_region_title=Por país gallerytree_map_region_column1=Quantia Total gallerytree_map_marker=Regiões gallerytree_map_marker_title=Por país gallerytree_map_marker_column1=Quantia Total gallerytree_table=Tabela de relatório gallerytree_table_basic=Básico gallerytree_table_basic_title=Lista de oportunidades gallerytree_table_basic_column1=País gallerytree_table_basic_column2=Cliente gallerytree_table_basic_column3=Produto gallerytree_table_basic_column4=Vendedor gallerytree_table_basic_column5=Status gallerytree_table_basic_column6=Fonte gallerytree_table_basic_column7=Criação gallerytree_table_basic_column8=Esperada gallerytree_table_basic_column9=Encerramento gallerytree_table_basic_column10=Quantia gallerytree_table_filtered=Filtrado gallerytree_table_filtered_title=Oportunidades no EUA & Brasil gallerytree_table_filtered_column1=Cliente gallerytree_table_filtered_column2=Produto gallerytree_table_filtered_column3=Status gallerytree_table_filtered_column4=Fonte gallerytree_table_filtered_column5=Criação gallerytree_table_filtered_column6=Esperada gallerytree_table_filtered_column7=Encerramento gallerytree_table_filtered_column8=Quantia gallerytree_table_grouped=Agrupado gallerytree_table_grouped_title=Sumário do País gallerytree_table_grouped_column1=País gallerytree_table_grouped_column2=\#Opps gallerytree_table_grouped_column3=Min gallerytree_table_grouped_column4=Max gallerytree_table_grouped_column5=Média gallerytree_table_grouped_column6=Total gallerytree_table_default_dd=Default (drill-down) gallerytree_table_default_dd_title=Lista de oportunidades gallerytree_table_default_dd_column1=País gallerytree_table_default_dd_column2=Cliente gallerytree_table_default_dd_column3=Produto gallerytree_table_default_dd_column4=Vendedor gallerytree_table_default_dd_column5=Status gallerytree_table_default_dd_column6=Fonte gallerytree_table_default_dd_column7=Criação gallerytree_table_default_dd_column8=Esperada gallerytree_table_default_dd_column9=Encerramento gallerytree_table_default_dd_column10=Quantia gallerytree_db=Painéis gallerytree_db_salesgoals=Objetivo de Vendas gallerytree_db_salespipe=Pipeline de Vendas gallerytree_db_salespcountry=Vendas por país gallerytree_db_salesreps=Relatório de Vendas gallerytree_db_expreps=Relatório de despesas gallerytree_db_clustermetrics=Métricas de cluster gallerywidget_unknown=Aplicativo de galeria desconhecido gallerywidget_dataset_modif=Os dados determinados foram modificados. Atualizando a visualização... gallerywidget_dataset_loaded=Data set carregado a partir do servidor [{0}, {1} Kb] metrics_server_detail_title=Métricas de Servidor ( Vertical) metrics_server_detail_backbutton_tt=Retornar metrics_server_detail_modebutton_tt_viewtable=Visualizar como tabela metrics_server_detail_modebutton_tt_viewcharts=Visualizar como gráficos metrics_server_detail_lasthour_summary=Sumário da última hora metrics_server_detail_cpu_usage=Uso da CPU (%) metrics_server_detail_mem_usage=Uso da memória (Gb) metrics_server_detail_netw_usage=Uso de rede (kbps) metrics_server_detail_disk_usage=Uso de disco (Mb) metrics_server_detail_live_procs=Vendedor metrics_server_detail_cpu1_title=CPU 1 % metrics_server_detail_cpu2_title=CPU 2 % metrics_server_detail_mem_title=Consumo de memória metrics_server_detail_netw_title=Largura de Banda da Rede metrics_server_detail_disk_title=Uso de disco metrics_server_detail_disk_column1=Espaço no disco livre metrics_server_detail_disk_column2=Espaço usado no disco metrics_server_detail_procs_running_title=Processos de execução metrics_server_detail_procs_running_column1=Execução metrics_server_detail_procs_sleeping_title=Processos de espera metrics_server_detail_procs_sleeping_column1=Em espera metrics_server_detail_rt_table_title=Métrica {0} tempo real metrics_server_detail_rt_table_column1=Minuto metrics_server_detail_rt_table_column2=CPU0 metrics_server_detail_rt_table_column3=CPU1 metrics_server_detail_rt_table_column4=Memória usada metrics_server_detail_rt_table_column5=Memória livre (Gb) metrics_server_detail_rt_table_column6=Upstream (kbps) metrics_server_detail_rt_table_column7=Downstream (kbps) metrics_server_detail_rt_table_column8=Processos de execução metrics_server_detail_rt_table_column9=Processos de espera metrics_server_detail_rt_table_column10=Disco usado (Mb) metrics_server_detail_rt_table_column11=Disco livre (Mb) metrics_server_vert_title=Métricas de servidor (Vertical) metrics_server_vert_default_tt=Clique para exibir detalhes de servidor metrics_server_vert_cpu_tt=Uso de CPU (%) metrics_server_vert_usedmem_tt=Memória usada (Gb) metrics_server_vert_netbw_tt=Rede BW (kbps) metrics_server_vert_procs_tt=Processos de Execução/Em espera metrics_server_vert_disk_tt=Uso de disco (Mb) metrics_server_vert_cpu1_title=CPU 1 % metrics_server_vert_cpu2_title=CPU 2 % metrics_server_vert_memconsumption_title=Consumo de memória metrics_server_vert_netbw_title=Largura de Banda da Rede metrics_server_vert_procs_title=Processos de Execução/Em espera metrics_server_vert_du_title=Uso de disco metrics_server_vert_du_free=Disco livre (Mb) metrics_server_vert_du_used=Disco usado (Mb) metrics_server_vert_serverdown={0} está baixo metrics_cluster_title=Métricas de cluster metrics_cluster_messages_heading=Inicializando o Painel metrics_cluster_metricselector_label=Métrica metrics_cluster_chartselector_label=Tipo de Gráfico metrics_cluster_metricselector_cpu=CPU % metrics_cluster_metricselector_mem=Memória metrics_cluster_metricselector_disk=Disco metrics_cluster_metricselector_netw=Rede metrics_cluster_metricselector_proc=Processos metrics_cluster_chartselector_bar=Barra metrics_cluster_chartselector_line=Linha metrics_cluster_chartselector_area=Área metrics_cluster_column_cpu=CPU % metrics_cluster_column_cpu_y=CPU % metrics_cluster_column_df=Disco livre metrics_cluster_column_df_y=Gigabytes metrics_cluster_column_du=Uso de disco metrics_cluster_column_du_y=Gigabytes metrics_cluster_column_memf=Memória livre metrics_cluster_column_memf_y=Gigabytes metrics_cluster_column_memu=Memória usada metrics_cluster_column_memu_y=Gigabytes metrics_cluster_column_procsrn=Execução de processos metrics_cluster_column_procsrn_y=Processos metrics_cluster_column_procssl=Processos Em espera metrics_cluster_column_procssl_y=Processos metrics_cluster_column_netrx=Net. Rx metrics_cluster_column_netrx_y=Kb/s metrics_cluster_column_nettx=Net. Tx metrics_cluster_column_nettx_y=Kb/s metrics_cluster_column_time=Tempo metrics_rt_title=Métricas de Sistema (Tempo Real) metrics_rt_serverup=está ativado metrics_rt_serverdown=está desativado sales_bycountry_title=Vendas por país sales_bycountry_bubble_title=Oportunidades de distribuição por país sales_bycountry_bubble_column1=Número de oportunidades sales_bycountry_bubble_column2=Probabilidade de média sales_bycountry_bubble_column3=Quantia esperada sales_bycountry_map_title=Por país sales_bycountry_map_column1=Quantia Total sales_bycountry_table_title=Lista de oportunidades sales_bycountry_table_column1=País sales_bycountry_table_column2=Cliente sales_bycountry_table_column3=Produto sales_bycountry_table_column4=Vendedor sales_bycountry_table_column5=Status sales_bycountry_table_column6=Criação sales_bycountry_table_column7=Esperada sales_bycountry_table_column8=Encerramento sales_bycountry_table_column9=Quantia sales_bydate_title=Pipeline de Vendas sales_bydate_area_title=Pipeline esperada sales_bydate_area_column1=Quantia sales_bydate_pie_years_title=Ano sales_bydate_pie_years_column1=Ocorrências sales_bydate_pie_quarters_title=Trimestre sales_bydate_pie_quarters_column1=Ocorrências sales_bydate_bar_weekday_title=Dia da semana sales_bydate_bar_weekday_column1=Ocorrências sales_bydate_pie_pipe_title=Pipeline sales_bydate_pie_pipe_column1=Número de oportunidades sales_bydate_table_title=Lista de oportunidades sales_bydate_table_column1=País sales_bydate_table_column2=Cliente sales_bydate_table_column3=Produto sales_bydate_table_column4=Vendedor sales_bydate_table_column5=Status sales_bydate_table_column6=Quantia sales_bydate_table_column7=Esperada sales_bydate_table_column8=Criação sales_bydate_table_column9=Encerramento sales_bydate_selector_total=Total sales_goals_title=Objetivo de Vendas sales_goals_meter_title=Objetivo de Vendas sales_goals_meter_column1=Quantia Total sales_goals_line_title=Pipeline esperada sales_goals_line_column1=Data de encerramento sales_goals_line_column2=Quantia Total sales_goals_line_column3=Quantia esperada sales_goals_bar_byproduct_title=Pelo produto sales_goals_bar_byproduct_column1=Produto sales_goals_bar_byproduct_column2=Total sales_goals_bar_byproduct_column3=Esperada sales_goals_bar_byempl_title=Por Funcionário sales_goals_bar_byempl_column1=Funcionário sales_goals_bar_byempl_column2=Quantia sales_goals_bubble_title=Oportunidades de distribuição por país sales_goals_bubble_column1=número de oportunidades sales_goals_bubble_column2=Probabilidade de média sales_goals_bubble_column3=Quantia esperada sales_tablereports_title=Relatório de Vendas sales_tablereports_tab_byyear=Por ano sales_tablereports_tab_bycountry=Por país sales_tablereports_tab_byproduct=Pelo produto sales_tablereports_tab_bysalesman=Por pessoa de vendas sales_tablereports_all_title=Lista de oportunidades sales_tablereports_all_column1=País sales_tablereports_all_column2=Cliente sales_tablereports_all_column3=Produto sales_tablereports_all_column4=Vendedor sales_tablereports_all_column5=Status sales_tablereports_all_column6=Criação sales_tablereports_all_column7=Esperada sales_tablereports_all_column8=Encerramento sales_tablereports_all_column9=Quantia sales_tablereports_bycountry_title=Sumário do País sales_tablereports_bycountry_column1=País sales_tablereports_bycountry_column2=\#Oportunidades sales_tablereports_bycountry_column3=Min sales_tablereports_bycountry_column4=Max sales_tablereports_bycountry_column5=Média sales_tablereports_bycountry_column6=Total sales_tablereports_byproduct_title=Sumário do Produto sales_tablereports_byproduct_column1=Produto sales_tablereports_byproduct_column2=\#Oportunidades sales_tablereports_byproduct_column3=Min sales_tablereports_byproduct_column4=Max sales_tablereports_byproduct_column5=Média sales_tablereports_byproduct_column6=Total sales_tablereports_bysalesman_title=Vendas por pessoa sales_tablereports_bysalesman_column1=Pessoa de vendas sales_tablereports_bysalesman_column2=\#Oportunidades sales_tablereports_bysalesman_column3=Min sales_tablereports_bysalesman_column4=Max sales_tablereports_bysalesman_column5=Média sales_tablereports_bysalesman_column6=Total sales_tablereports_byyear_title=Sumário do ano sales_tablereports_byyear_column1=Data de criação sales_tablereports_byyear_column2=\#Oportunidades sales_tablereports_byyear_column3=Min sales_tablereports_byyear_column4=Max sales_tablereports_byyear_column5=Média sales_tablereports_byyear_column6=Total salesopps_displayers_by_pipeline_title=Status do Pipeline salesopps_displayers_by_status_title=Por status salesopps_displayers_by_salesman_title=Por pessoa de vendas salesopps_displayers_by_exp_pipeline_title=Quantia esperada salesopps_displayers_by_exp_pipeline_column1=Quantia esperada salesopps_displayers_by_product_title=Pelo produto salesopps_displayers_by_product_column1=Quantia Total salesopps_displayers_by_country_title=Por país salesopps_displayers_by_country_column1=Quantia Total salesopps_displayers_country_summary_title=Sumário do País salesopps_displayers_country_summary_column1=PAÍS salesopps_displayers_country_summary_column2=TOTAL salesopps_displayers_country_summary_column3=NÚMERO salesopps_displayers_country_summary_column4=MÉDIA salesopps_displayers_country_summary_column5=MIN salesopps_displayers_country_summary_column6=MAX salesopps_displayers_all_list_title=Lista de oportunidades ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/AppConstants_zh_CN.properties ================================================ logoBannerError=加载标题失败。 logOut=退出 role=角色 menu_home=主目录 menu_gallery=图库 menu_extensions_apps=应用程序 menu_dashboards=仪表板 menu_dashboards_salesdb=销售仪表板 menu_dashboards_salesreports=销售报告 menu_dashboards_new=- 新建 - home_intro=Dashbuilder 是仪表板的常规目的,同时报告允许以下功能的 web 应用程序: home_upcoming=即将推出的功能 home_feature1=仪表板的可视化配置及个性化 home_feature2=支持使用几个图标库进行不同类型的可视化 home_feature3=用户数据集定义的 UI 编辑器 home_feature4=用于图表可视化的完整配置的编辑器 home_feature5=互动式报告表格定义 home_feature6=从外部系统通过不同协议进行数据提取 home_feature7=支持分析及实时仪表板 home_feature8=基于 D3 JS & Lienzo GWT 的新呈现器 home_feature9=分层(嵌套组)显示器类型:树状 & 饼状 home_feature10=支持多个数据系列 home_feature11=丰富的移动性支持 home_feature12=警告及 SLA 配置 home_feature13=RESTful API home_arch=架构 home_arch1=不依赖任何图表呈现技术。可插拔呈现器。 home_arch2=不依赖任何数据存储。 home_arch3=可读取的数据格式:CSV 文件、数据库、弹性搜索或 Java 生成器。 home_arch4=分离的客户端 & 服务器层。构建单纯轻加权客户端仪表板的能力。 home_arch5=在客户端中 push & 处理数据集以获得更好性能的能力。 home_arch6a=基于 home_arch6b=在网页中构建有丰富 workbench 形式应用程序的框架。 home_furtherinfo=详情请查看 Apache License,版本 2.0. home_license=采用 Apache License 版本 2.0 注册。 notification_dashboard_created=创建了 {0} 仪表板 notification_dashboard_deleted=删除了 {0} 仪表板 dashboard_new_displayer=新建显示屏 dashboard_delete_popup_title=删除仪表板 dashboard_delete_popup_content=您确定要删除这个仪表板吗? dashboard_delete_dashboard=删除仪表板 salesdbpersp_salessummary=销售总览 salesreportspersp_salesreports=销售报告 expensesdb_title=费用报表 expensesdb_tab_exp_evolution=费用评估 expensesdb_tab_by_employee=按雇员 expensesdb_tab_all_exp=所有费用 expensesdb_pie_title=办公室费用 expensesdb_pie_column1=办公室 expensesdb_pie_column2=部门 expensesdb_pie_column3=雇员 expensesdb_bar_title=部门费用 expensesdb_bar_column1=总金额 expensesdb_bubble_title=雇员费用 expensesdb_bubble_column1=总计 expensesdb_bubble_column2=平均 expensesdb_bubble_column3=雇员 expensesdb_bubble_column4=费用报表的数量 expensesdb_line_title=费用评估 expensesdb_line_column1=总金额 expensesdb_table_title=费用报表列表 expensesdb_table_column1=办公室 expensesdb_table_column2=部门 expensesdb_table_column3=雇员 expensesdb_table_column4=金额 expensesdb_table_column5=日期 gallerytree_home=图库 gallerytree_home_p1=该图库中包含 Dashbuilder 支持的所有不同显示器类型的实例。节点 "Dashboards" 还包含一组如何将不同显示器组合为全功能终端用户仪表板的示例。 gallerytree_home_s2a=所有示例均使用 Dashbuilder 的 GWT Displayer API 构建。如果您有兴趣或向了解源代码,请查看 gallerytree_home_s2b=\ GitHub。 gallerytree_home_ghublink=文件 gallerytree_title=图库树 gallerytree_bar=柱状图 gallerytree_bar_horiz=水平视图 gallerytree_bar_horiz_title=按产品 gallerytree_bar_horiz_column1=总金额 gallerytree_bar_vert=垂直视图 gallerytree_bar_vert_title=按产品 gallerytree_bar_vert_column1=总金额 gallerytree_bar_vert_dd=查看明细 gallerytree_bar_vert_dd_title=按渠道/状态/销售人员 gallerytree_bar_vert_dd_column1=总金额 gallerytree_bar_vert_dd_column2=总金额 gallerytree_bar_vert_dd_column3=总金额 gallerytree_bar_multi=多重 gallerytree_bar_stacked=堆叠图 gallerytree_bar_multi_title=按国家(最小/最大/平均) gallerytree_bar_multi_column1=最小值 gallerytree_bar_multi_column2=最大值 gallerytree_bar_multi_column3=平均值 gallerytree_pie=饼图 gallerytree_pie_basic=基本视图 gallerytree_pie_basic_title=按照状态 gallerytree_pie_basic_column1=总金额 gallerytree_pie_3d=3d gallerytree_pie_3d_title=按照状态 gallerytree_pie_3d_column1=总金额 gallerytree_pie_donut=圈图 gallerytree_pie_donut_title=按照状态 gallerytree_pie_donut_column1=总金额 gallerytree_pie_dd=查看明细 gallerytree_pie_dd_title=按渠道/状态/销售人员 gallerytree_pie_dd_column1=总金额 gallerytree_pie_dd_column2=总金额 gallerytree_pie_dd_column3=总金额 gallerytree_line=线型图 gallerytree_line_basic=基本视图 gallerytree_line_basic_title=销售机会评估 gallerytree_line_basic_column1=结束日期 gallerytree_line_basic_column2=总金额 gallerytree_line_multi=多重 gallerytree_line_multi_title=按国家(最小/最大/平均) gallerytree_line_multi_column1=最小值 gallerytree_line_multi_column2=最大值 gallerytree_line_multi_column3=平均值 gallerytree_line_multi_static=多重(静态) gallerytree_line_multi_static_title=年度销售情况 gallerytree_line_multi_static_column1=2014 年销售情况 gallerytree_line_multi_static_column2=2015 年销售情况 gallerytree_line_multi_static_column3=2016 年销售情况 gallerytree_area=面积图 gallerytree_area_basic=基本视图 gallerytree_area_basic_title=期望的渠道 gallerytree_area_basic_column1=期望的金额 gallerytree_area_fixed=固定视图(每月) gallerytree_area_fixed_title=渠道(最好的一个月) gallerytree_area_fixed_column1=结束日期 gallerytree_area_fixed_column2=每月的期望金额 gallerytree_area_dd=查看明细 gallerytree_area_dd_title=渠道的期望值 gallerytree_area_dd_column1=结束日期 gallerytree_area_dd_column2=期望的金额 gallerytree_bubble=气泡图 gallerytree_bubble_basic=基本视图 gallerytree_bubble_basic_title=按国家分布的机会 gallerytree_bubble_basic_column1=机会数量 gallerytree_bubble_basic_column2=平均几率 gallerytree_bubble_basic_column3=期望的金额 gallerytree_bubble_basic_column4=国家 gallerytree_meter=计量图表 gallerytree_meter_basic=基本视图 gallerytree_meter_basic_title=销售目标 gallerytree_meter_basic_column1=总金额 gallerytree_meter_multi=多重 gallerytree_meter_multi_title=每年的期望金额 gallerytree_meter_multi_column1=总金额 gallerytree_meter_multi_static=多重(静态) gallerytree_meter_multi_static_title=Heart rate gallerytree_meter_multi_static_column1=人员 gallerytree_meter_multi_static_column2=Heart rate gallerytree_metrics=度量 gallerytree_metrics_basic=基本视图 gallerytree_metrics_basic_title=销售额(当前季度) gallerytree_metrics_basic_column1=销售额(当前季度) gallerytree_metrics_basic_static=基本视图(静态) gallerytree_metrics_basic_static_title=Tweets\! gallerytree_metrics_basic_static_column1=Tweets gallerytree_map=图表 gallerytree_map_region=标识 gallerytree_map_region_title=按国家 gallerytree_map_region_column1=总金额 gallerytree_map_marker=地区 gallerytree_map_marker_title=按国家 gallerytree_map_marker_column1=总金额 gallerytree_table=报告表 gallerytree_table_basic=基本视图 gallerytree_table_basic_title=机会列表 gallerytree_table_basic_column1=国家 gallerytree_table_basic_column2=客户 gallerytree_table_basic_column3=产品 gallerytree_table_basic_column4=销售人员 gallerytree_table_basic_column5=状态 gallerytree_table_basic_column6=来源 gallerytree_table_basic_column7=创建 gallerytree_table_basic_column8=期望值 gallerytree_table_basic_column9=结束日期 gallerytree_table_basic_column10=金额 gallerytree_table_filtered=过滤的 gallerytree_table_filtered_title=美国和巴西的机会 gallerytree_table_filtered_column1=客户 gallerytree_table_filtered_column2=产品 gallerytree_table_filtered_column3=状态 gallerytree_table_filtered_column4=来源 gallerytree_table_filtered_column5=创建 gallerytree_table_filtered_column6=期望值 gallerytree_table_filtered_column7=结束日期 gallerytree_table_filtered_column8=金额 gallerytree_table_grouped=分组的 gallerytree_table_grouped_title=国家总览 gallerytree_table_grouped_column1=国家 gallerytree_table_grouped_column2=\#Opps gallerytree_table_grouped_column3=最小值 gallerytree_table_grouped_column4=最大值 gallerytree_table_grouped_column5=平均值 gallerytree_table_grouped_column6=总计 gallerytree_table_default_dd=默认视图(明细) gallerytree_table_default_dd_title=机会列表 gallerytree_table_default_dd_column1=国家 gallerytree_table_default_dd_column2=客户 gallerytree_table_default_dd_column3=产品 gallerytree_table_default_dd_column4=销售人员 gallerytree_table_default_dd_column5=状态 gallerytree_table_default_dd_column6=来源 gallerytree_table_default_dd_column7=创建 gallerytree_table_default_dd_column8=期望值 gallerytree_table_default_dd_column9=结束日期 gallerytree_table_default_dd_column10=金额 gallerytree_db=仪表板 gallerytree_db_salesgoals=销售目标 gallerytree_db_salespipe=销售渠道 gallerytree_db_salespcountry=每个国家的销售额 gallerytree_db_salesreps=销售报告 gallerytree_db_expreps=费用报表 gallerytree_db_clustermetrics=群集度量 gallerywidget_unknown=未知的图库小工具 gallerywidget_dataset_modif=这个数据集已被修改。刷新视图... gallerywidget_dataset_loaded=数据集已从服务器加载 [{0}, {1} Kb] metrics_server_detail_title=服务器度量(垂直) metrics_server_detail_backbutton_tt=回退 metrics_server_detail_modebutton_tt_viewtable=表视图 metrics_server_detail_modebutton_tt_viewcharts=图表视图 metrics_server_detail_lasthour_summary=最近一小时总览 metrics_server_detail_cpu_usage=CPU 利用率(%) metrics_server_detail_mem_usage=内存利用率(Gb) metrics_server_detail_netw_usage=网络利用率(kbps) metrics_server_detail_disk_usage=磁盘利用率(Mb) metrics_server_detail_live_procs=活动进程 metrics_server_detail_cpu1_title=CPU 1 % metrics_server_detail_cpu2_title=CPU 2 % metrics_server_detail_mem_title=内存消耗 metrics_server_detail_netw_title=网络带宽 metrics_server_detail_disk_title=磁盘利用率 metrics_server_detail_disk_column1=空闲磁盘空间 metrics_server_detail_disk_column2=已用磁盘空间 metrics_server_detail_procs_running_title=运行的进程 metrics_server_detail_procs_running_column1=正在运行 metrics_server_detail_procs_sleeping_title=休眠的进程 metrics_server_detail_procs_sleeping_column1=正在休眠 metrics_server_detail_rt_table_title=实时 {0} 度量 metrics_server_detail_rt_table_column1=分钟 metrics_server_detail_rt_table_column2=CPU0 metrics_server_detail_rt_table_column3=CPU1 metrics_server_detail_rt_table_column4=已用内存(Gb) metrics_server_detail_rt_table_column5=空闲内存(Gb) metrics_server_detail_rt_table_column6=上行流量(kbps) metrics_server_detail_rt_table_column7=下行流量(kbps) metrics_server_detail_rt_table_column8=运行的进程 metrics_server_detail_rt_table_column9=休眠的进程 metrics_server_detail_rt_table_column10=已用磁盘空间(Mb) metrics_server_detail_rt_table_column11=空闲磁盘空间(Mb) metrics_server_vert_title=服务器度量(垂直) metrics_server_vert_default_tt=点击以显示服务器细节 metrics_server_vert_cpu_tt=CPU 利用率(%) metrics_server_vert_usedmem_tt=已用内存(Gb) metrics_server_vert_netbw_tt=网络带宽(kbps) metrics_server_vert_procs_tt=运行的/休眠的进程 metrics_server_vert_disk_tt=磁盘利用率(Mb) metrics_server_vert_cpu1_title=CPU 1 % metrics_server_vert_cpu2_title=CPU 2 % metrics_server_vert_memconsumption_title=内存消耗 metrics_server_vert_netbw_title=网络带宽 metrics_server_vert_procs_title=运行的/休眠的进程 metrics_server_vert_du_title=磁盘利用率 metrics_server_vert_du_free=空闲磁盘空间(Mb) metrics_server_vert_du_used=已用磁盘空间(Mb) metrics_server_vert_serverdown={0} 已下线 metrics_cluster_title=群集度量 metrics_cluster_messages_heading=正在初始化仪表板... metrics_cluster_metricselector_label=度量 metrics_cluster_chartselector_label=图表类型 metrics_cluster_metricselector_cpu=CPU % metrics_cluster_metricselector_mem=内存 metrics_cluster_metricselector_disk=磁盘 metrics_cluster_metricselector_netw=网络 metrics_cluster_metricselector_proc=流程 metrics_cluster_chartselector_bar=柱状图 metrics_cluster_chartselector_line=线形图 metrics_cluster_chartselector_area=面积图 metrics_cluster_column_cpu=CPU % metrics_cluster_column_cpu_y=CPU % metrics_cluster_column_df=空闲磁盘空间 metrics_cluster_column_df_y=Gigabytes metrics_cluster_column_du=已用磁盘空间 metrics_cluster_column_du_y=Gigabytes metrics_cluster_column_memf=空闲内存 metrics_cluster_column_memf_y=Gigabytes metrics_cluster_column_memu=已用内存 metrics_cluster_column_memu_y=Gigabytes metrics_cluster_column_procsrn=运行的进程 metrics_cluster_column_procsrn_y=进程 metrics_cluster_column_procssl=休眠的进程 metrics_cluster_column_procssl_y=进程 metrics_cluster_column_netrx=网络接收 metrics_cluster_column_netrx_y=Kb/s metrics_cluster_column_nettx=网络传输 metrics_cluster_column_nettx_y=Kb/s metrics_cluster_column_time=时间 metrics_rt_title=系统度量(实时) metrics_rt_serverup=上线 metrics_rt_serverdown=下线 sales_bycountry_title=每个国家的销售额 sales_bycountry_bubble_title=按国家分布的机会 sales_bycountry_bubble_column1=机会数量 sales_bycountry_bubble_column2=平均几率 sales_bycountry_bubble_column3=期望的金额 sales_bycountry_map_title=按国家 sales_bycountry_map_column1=总金额 sales_bycountry_table_title=机会列表 sales_bycountry_table_column1=国家 sales_bycountry_table_column2=客户 sales_bycountry_table_column3=产品 sales_bycountry_table_column4=销售人员 sales_bycountry_table_column5=状态 sales_bycountry_table_column6=创建 sales_bycountry_table_column7=期望值 sales_bycountry_table_column8=结束日期 sales_bycountry_table_column9=金额 sales_bydate_title=销售渠道 sales_bydate_area_title=渠道期望值 sales_bydate_area_column1=金额 sales_bydate_pie_years_title=年 sales_bydate_pie_years_column1=出现率 sales_bydate_pie_quarters_title=季度 sales_bydate_pie_quarters_column1=出现率 sales_bydate_bar_weekday_title=星期几 sales_bydate_bar_weekday_column1=出现率 sales_bydate_pie_pipe_title=渠道 sales_bydate_pie_pipe_column1=机会数量 sales_bydate_table_title=机会列表 sales_bydate_table_column1=国家 sales_bydate_table_column2=客户 sales_bydate_table_column3=产品 sales_bydate_table_column4=销售人员 sales_bydate_table_column5=状态 sales_bydate_table_column6=金额 sales_bydate_table_column7=期望值 sales_bydate_table_column8=创建 sales_bydate_table_column9=结束 sales_bydate_selector_total=总计 sales_goals_title=销售目标 sales_goals_meter_title=销售目标 sales_goals_meter_column1=总金额 sales_goals_line_title=渠道期望值 sales_goals_line_column1=结束日期 sales_goals_line_column2=总金额 sales_goals_line_column3=期望的金额 sales_goals_bar_byproduct_title=按产品 sales_goals_bar_byproduct_column1=产品 sales_goals_bar_byproduct_column2=总计 sales_goals_bar_byproduct_column3=期望值 sales_goals_bar_byempl_title=按雇员 sales_goals_bar_byempl_column1=雇员 sales_goals_bar_byempl_column2=金额 sales_goals_bubble_title=按国家分布的机会 sales_goals_bubble_column1=机会数量 sales_goals_bubble_column2=平均几率 sales_goals_bubble_column3=期望的金额 sales_tablereports_title=销售报告 sales_tablereports_tab_byyear=按年 sales_tablereports_tab_bycountry=按国家 sales_tablereports_tab_byproduct=按产品 sales_tablereports_tab_bysalesman=按销售人员 sales_tablereports_all_title=机会列表 sales_tablereports_all_column1=国家 sales_tablereports_all_column2=客户 sales_tablereports_all_column3=产品 sales_tablereports_all_column4=销售人员 sales_tablereports_all_column5=状态 sales_tablereports_all_column6=创建 sales_tablereports_all_column7=期望值 sales_tablereports_all_column8=结束 sales_tablereports_all_column9=金额 sales_tablereports_bycountry_title=国家总览 sales_tablereports_bycountry_column1=国家 sales_tablereports_bycountry_column2=\#Opps sales_tablereports_bycountry_column3=最小值 sales_tablereports_bycountry_column4=最大值 sales_tablereports_bycountry_column5=平均值 sales_tablereports_bycountry_column6=总计 sales_tablereports_byproduct_title=产品总览 sales_tablereports_byproduct_column1=产品 sales_tablereports_byproduct_column2=\#Opps sales_tablereports_byproduct_column3=最小值 sales_tablereports_byproduct_column4=最大值 sales_tablereports_byproduct_column5=平均值 sales_tablereports_byproduct_column6=总计 sales_tablereports_bysalesman_title=销售额(按人) sales_tablereports_bysalesman_column1=销售人员 sales_tablereports_bysalesman_column2=\#Opps sales_tablereports_bysalesman_column3=最小值 sales_tablereports_bysalesman_column4=最大值 sales_tablereports_bysalesman_column5=平均值 sales_tablereports_bysalesman_column6=总计 sales_tablereports_byyear_title=年度总览 sales_tablereports_byyear_column1=创建日期 sales_tablereports_byyear_column2=\#Opps sales_tablereports_byyear_column3=最小值 sales_tablereports_byyear_column4=最大值 sales_tablereports_byyear_column5=平均值 sales_tablereports_byyear_column6=总计 salesopps_displayers_by_pipeline_title=渠道状态 salesopps_displayers_by_status_title=按状态 salesopps_displayers_by_salesman_title=按销售人员 salesopps_displayers_by_exp_pipeline_title=期望的金额 salesopps_displayers_by_exp_pipeline_column1=期望的金额 salesopps_displayers_by_product_title=按产品 salesopps_displayers_by_product_column1=总金额 salesopps_displayers_by_country_title=按国家 salesopps_displayers_by_country_column1=总金额 salesopps_displayers_country_summary_title=国家总览 salesopps_displayers_country_summary_column1=国家 salesopps_displayers_country_summary_column2=总计 salesopps_displayers_country_summary_column3=数量 salesopps_displayers_country_summary_column4=平均值 salesopps_displayers_country_summary_column5=最小值 salesopps_displayers_country_summary_column6=最大值 salesopps_displayers_all_list_title=机会列表 ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants.properties ================================================ loginTitle=Dashbuilder welcome=Welcome to Dashbuilder ! powered=Powered By Dashbuilder userName=Username password=Password signIn=Sign In loginFailed=Login failed: Not Authorized loginAsAnotherUser=Login as another user logoutSuccessful=Logout successful loginAgain=Login again ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants_de.properties ================================================ loginTitle=Dashbuilder welcome=Willkommen bei Dashbuilder \! powered=Powered By Dashbuilder userName=Benutzername password=Passwort signIn=Anmeldung loginFailed=Anmeldung fehlgeschlagen\: Nicht autorisiert loginAsAnotherUser=Anmeldung als anderer Benutzer logoutSuccessful=Abmeldung erfolgreich loginAgain=Erneut anmelden ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants_es.properties ================================================ loginTitle=Dashbuilder welcome=¡Bienvenido a Dashbuilder! powered=Con tecnología de Dashbuilder userName=Nombre de usuario password=Contraseña signIn=Iniciar sesión loginFailed=El inicio de sesión ha fallado: No autorizado loginAsAnotherUser=Iniciar sesión como otro usuario logoutSuccessful=Se ha cerrado sesión correctamente loginAgain=Volver a iniciar sesión ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants_fr.properties ================================================ loginTitle=Dashbuilder welcome=Bienvenue dans Dashbuilder powered=Avec la technologie Dashbuilder userName=Nom d''utilisateur password=Mot de passe signIn=Se connecter loginFailed=La connexion a échoué : Non autorisée loginAsAnotherUser=Se connecter sous l''identité d''un autre utilisateur logoutSuccessful=Déconnexion réussie loginAgain=Se reconnecter ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants_it.properties ================================================ loginTitle=Dashbuilder welcome=Benvenuto in Dashbuilder ! powered=Powered By Dashbuilder userName=Nome utente password=Password signIn=Accedi loginFailed=Accesso non riuscito: Non autorizzato loginAsAnotherUser=Accedi come un altro utente logoutSuccessful=Logout effettuato con successo loginAgain=Accedi di nuovo ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants_ja.properties ================================================ loginTitle=Dashbuilder welcome=Dashbuilder にようこそ! powered=Powered By Dashbuilder userName=ユーザ名 password=パスワード signIn=サインイン loginFailed=ログインに失敗しました: 承認されていません loginAsAnotherUser=別のユーザー logoutSuccessful=正常にログアウトしました loginAgain=再度ログイン ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants_pt_BR.properties ================================================ loginTitle=Dashbuilder welcome=Bem-vindo ao Dashbuilder \! powered=Desenvolvido por Dashbuilder userName=Nome de usuário password=Senha signIn=Entrar loginFailed=Falha de login\: Não Autorizado loginAsAnotherUser=Faça o login como outro usuário logoutSuccessful=Saída com êxito loginAgain=Faça o login novamente ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/client/resources/i18n/LoginConstants_zh_CN.properties ================================================ loginTitle=Dashbuilder welcome=欢迎使用 Dashbuilder! powered=Dashbuilder 为您提供更多方便 userName=用户名 password=密码 signIn=登录 loginFailed=登录失败:未授权 loginAsAnotherUser=作为其他用户登录 logoutSuccessful=成功退出 loginAgain=再次登录 ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/public/css/uberfire-loading.css ================================================ /* * Copyright 2010 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Loading indicator at Startup */ #loading { position: absolute; left: 45%; top: 40%; padding: 2px; z-index: 20001; height: auto; border: 1px solid #ccc; } #loading a { color: #225588; } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/org/dashbuilder/public/css/uberfire-showcase.css ================================================ html, body { height: 100%; } /* Override PatternFly default css so border isn't duplicated */ .navbar-pf { border-top: none; } .navbar-pf ul.navbar-utility { top: -25px; } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/security-management.properties ================================================ # # Copyright 2016 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # org.uberfire.ext.security.management.api.userManagementServices=WildflyCLIUserManagementService ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/resources/security-policy.properties ================================================ # # Authorization Policy # # The entries in this file must comply with the following format: # # "classifier.identifier.setting.extra=value" # # classifier = role|group # identifier = An existing role or group identifier (depending on the classifier type) # setting = home|priority|permission # extra = Extra setting information. Mandatory, for instance, to define a permission's name # value = The setting value (depends on the setting selected). Value expected per setting type: # # - home: An existing perspective identifier to redirect after login # - priority: An integer indicating how priority is this role|group compared to others. Used for conflict resolution. # - permission: A name representing a specific feature or capability over a given resource. # # Default settings default.home=HomePerspective default.permission.perspective.create=false default.permission.perspective.update=false default.permission.perspective.delete=false default.permission.perspective.read=false default.permission.perspective.read.HomePerspective=true # Role "admin" role.admin.permission.perspective.create=true role.admin.permission.perspective.update=true role.admin.permission.perspective.delete=true role.admin.permission.perspective.read=true ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/beans.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/datasets/README.md ================================================ How to deploy a data set definition ============================ * Create a ".dset" file containing the data set JSON definition. * Create an empty ".dset.deploy" file in order to launch the automatic deployment. To undeploy/remove a data set definition ============================ * Create an empty ".undeploy" file in order to force the removal of the data set from the system. * Notice that is the identifier of the data set you want to remove. If the data set has been previously deployed (using the above mechanism) then the UUID is the one defined within the ".dset" file. If it's been defined through the UI tooling then it can be read on the data set editor screen. ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/datasets/clusterMetrics.dset ================================================ { "uuid": "clusterMetrics", "name": "Cluster Metrics", "provider": "BEAN", "isPublic": true, "pushEnabled": false, "pushMaxSize": 1024, "refreshTime": "1second", "refreshAlways": "true", "generatorClass": "org.dashbuilder.backend.ClusterMetricsGenerator", "generatorParams": [ {"param": "timeFrame", "value": "10minute"}, {"param": "aliveNodes", "value": "server1,server2,server3,server4,server5"}, {"param": "overloadedNodes", "value": ""} ] } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/datasets/expenseReports.csv ================================================ office;department;employee;date;amount Barcelona;Engineering;Roxie Foraker;12-11-2012;120.35 Barcelona;Engineering;Roxie Foraker;12-01-2012;1,100.10 Barcelona;Engineering;Roxie Foraker;11-01-2012;900.10 Barcelona;Services;Jamie Gilbeau;10-12-2012;340.34 Barcelona;Services;Jamie Gilbeau;09-15-2012;300.00 Barcelona;Services;Jamie Gilbeau;08-17-2012;152.25 Madrid;Services;Roxie Foraker;07-01-2012;800.80 Madrid;Services;Roxie Foraker;06-01-2012;911.11 Madrid;Sales;Nita Marling;05-11-2012;75.75 Madrid;Sales;Nita Marling;03-11-2012;100.00 Madrid;Sales;Nita Marling;03-16-2012;220.80 Madrid;Sales;Nita Marling;03-02-2012;344.90 Brno;Support;Darryl Innes;02-09-2012;567.89 Brno;Support;Darryl Innes;01-13-2012;400.40 Brno;Support;Darryl Innes;01-11-2012;1,001.90 Brno;Engineering;Julio Burdge;11-02-2011;200.20 Brno;Engineering;Julio Burdge;09-01-2011;159.01 Brno;Engineering;Julio Burdge;08-22-2011;300.00 Brno;Engineering;Julio Burdge;07-23-2011;800.24 Brno;Sales;Neva Hunger;06-11-2011;995.30 Brno;Sales;Neva Hunger;06-11-2011;234.30 Westford;Engineering;Kathrine Janas;05-17-2011;233.49 Westford;Engineering;Kathrine Janas;04-12-2011;1,100.10 Westford;Engineering;Kathrine Janas;03-13-2011;1,402.30 Westford;Engineering;Kathrine Janas;02-13-2011;490.10 Westford;Engineering;Kathrine Janas;02-09-2011;600.34 Westford;Sales;Jerri Preble;12-23-2010;899.03 Westford;Sales;Jerri Preble;11-30-2010;343.45 Westford;Management;Donald M. Stanton;10-29-2010;983.03 Westford;Management;Donald M. Stanton;10-11-2010;43.03 Raleigh;Management;Hannah B. Mackey;09-01-2010;234.34 Raleigh;Management;Hannah B. Mackey;07-02-2010;543.45 Raleigh;Management;Hannah B. Mackey;06-02-2010;193.45 Raleigh;Management;Loretta R. Havens;05-03-2010;992.20 Raleigh;Management;Loretta R. Havens;04-23-2010;494.40 Raleigh;Engineering;Tony L. Crawford;02-18-2010;233.09 Raleigh;Engineering;Tony L. Crawford;02-22-2010;293.49 Raleigh;Engineering;Tony L. Crawford;12-23-2009;401.40 Raleigh;Engineering;Tony L. Crawford;07-19-2009;209.55 Raleigh;Support;Eileen L. Pereira;06-12-2009;300.01 Raleigh;Support;Eileen L. Pereira;06-13-2009;450.60 Raleigh;Support;Eileen L. Pereira;06-14-2009;320.90 Raleigh;Support;Eileen L. Pereira;06-15-2009;303.90 London;Engineering;Alan P. Adamson;06-12-2009;404.30 London;Engineering;Alan P. Adamson;05-12-2009;868.45 London;Engineering;Alan P. Adamson;05-13-2009;333.45 London;Management;Patricia J. Behr;04-14-2009;565.56 London;Management;Patricia J. Behr;03-02-2009;345.45 London;Management;Patricia J. Behr;02-03-2009;700.66 London;Management;Patricia J. Behr;01-04-2009;921.90 ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/datasets/expenseReports.dset ================================================ { "uuid": "expenseReports", "name": "Expense Reports", "provider": "CSV", "isPublic": true, "pushEnabled": true, "pushMaxSize": 1024, "refreshTime": "2 second", "refreshAlways": "false", "filePath": "expenseReports.csv", "separatorChar": ";", "quoteChar": "\"", "escapeChar": "\\", "datePattern": "MM-dd-yyyy", "numberPattern": "#,###.##", "columns": [ {"id": "office", "type": "label"}, {"id": "department", "type": "label"}, {"id": "employee", "type": "label"}, {"id": "amount", "type": "number", "pattern": "#,###.##"}, {"id": "date", "type": "date", "pattern": "MM-dd-yyyy"} ] } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/datasets/salesOpportunities.dset ================================================ { "uuid": "salesOpportunities", "name": "Sales Opportunities", "provider": "BEAN", "pushEnabled": false, "pushMaxSize": 2048, "isPublic": true, "generatorClass": "org.dashbuilder.backend.SalesDataSetGenerator", "generatorParams": [ {"param": "startYear", "value": "-1"}, {"param": "endYear", "value": "3"}, {"param": "oppsPerMonth", "value": "30"} ] } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/datasets/worldPopulation.csv ================================================ City / Urban area,Country,Population,Land area,Density Tokyo/Yokohama,Japan,"33,200,000","6,993","4,750" New York Metro,USA,"17,800,000","8,683","2,050" Sao Paulo,Brazil,"17,700,000","1,968","9,000" Seoul/Incheon,South Korea,"17,500,000","1,049","16,700" Mexico City,Mexico,"17,400,000","2,072","8,400" Osaka/Kobe/Kyoto,Japan,"16,425,000","2,564","6,400" Manila,Philippines,"14,750,000","1,399","10,550" Mumbai,India,"14,350,000",484,"29,650" Delhi,India,"14,300,000","1,295","11,050" Jakarta,Indonesia,"14,250,000","1,360","10,500" Lagos,Nigeria,"13,400,000",738,"18,150" Kolkata,India,"12,700,000",531,"23,900" Cairo,Egypt,"12,200,000","1,295","9,400" Los Angeles,USA,"11,789,000","4,320","2,750" Buenos Aires,Argentina,"11,200,000","2,266","4,950" Rio de Janeiro,Brazil,"10,800,000","1,580","6,850" Moscow,Russia,"10,500,000","2,150","4,900" Shanghai,China,"10,000,000",746,"13,400" Karachi,Pakistan,"9,800,000",518,"18,900" Paris,France,"9,645,000","2,723","3,550" Istanbul,Turkey,"9,000,000","1,166","7,700" Nagoya,Japan,"9,000,000","2,875","3,150" Beijing,China,"8,614,000",748,"11,500" Chicago,USA,"8,308,000","5,498","1,500" London,UK,"8,278,000","1,623","5,100" Shenzhen,China,"8,000,000",466,"17,150" Essen/D�sseldorf,Germany,"7,350,000","2,642","2,800" Tehran,Iran,"7,250,000",686,"10,550" Bogota,Colombia,"7,000,000",518,"13,500" Lima,Peru,"7,000,000",596,"11,750" Bangkok,Thailand,"6,500,000","1,010","6,450" Johannesburg/East Rand,South Africa,"6,000,000","2,396","2,500" Chennai,India,"5,950,000",414,"14,350" Taipei,Taiwan,"5,700,000",376,"15,200" Baghdad,Iraq,"5,500,000",596,"9,250" Santiago,Chile,"5,425,000",648,"8,400" Bangalore,India,"5,400,000",534,"10,100" Hyderabad,India,"5,300,000",583,"9,100" St Petersburg,Russia,"5,300,000",622,"8,550" Philadelphia,USA,"5,149,000","4,661","1,100" Lahore,Pakistan,"5,100,000",622,"8,200" Kinshasa,Congo,"5,000,000",469,"10,650" Miami,USA,"4,919,000","2,891","1,700" Ho Chi Minh City,Vietnam,"4,900,000",518,"9,450" Madrid,Spain,"4,900,000",945,"5,200" Tianjin,China,"4,750,000",453,"10,500" Kuala Lumpur,Malaysia,"4,400,000","1,606","2,750" Toronto,Canada,"4,367,000","1,655","2,650" Milan,Italy,"4,250,000","1,554","2,750" Shenyang,China,"4,200,000",453,"9,250" Dallas/Fort Worth,USA,"4,146,000","3,644","1,150" Boston,USA,"4,032,000","4,497",900 Belo Horizonte,Brazil,"4,000,000",868,"4,600" Khartoum,Sudan,"4,000,000",583,"6,850" Riyadh,Saudi Arabia,"4,000,000","1,101","3,650" Singapore,Singapore,"4,000,000",479,"8,350" Washington,USA,"3,934,000","2,996","1,300" Detroit,USA,"3,903,000","3,267","1,200" Barcelona,Spain,"3,900,000",803,"4,850" Houston,USA,"3,823,000","3,355","1,150" Athens,Greece,"3,685,000",684,"5,400" Berlin,Germany,"3,675,000",984,"3,750" Sydney,Australia,"3,502,000","1,687","2,100" Atlanta,USA,"3,500,000","5,083",700 Guadalajara,Mexico,"3,500,000",596,"5,900" San Francisco/Oakland,USA,"3,229,000","1,365","2,350" Montreal.,Canada,"3,216,000","1,740","1,850" Monterey,Mexico,"3,200,000",479,"6,700" Melbourne,Australia,"3,162,000","2,080","1,500" Ankara,Turkey,"3,100,000",583,"5,300" Recife,Brazil,"3,025,000",376,"8,050" Phoenix/Mesa,USA,"2,907,000","2,069","1,400" Durban,South Africa,"2,900,000",829,"3,500" Porto Alegre,Brazil,"2,800,000",583,"4,800" Dalian,China,"2,750,000",389,"7,100" Jeddah,Saudi Arabia,"2,750,000",777,"3,550" Seattle,USA,"2,712,000","2,470","1,100" Cape Town,South Africa,"2,700,000",686,"3,950" San Diego,USA,"2,674,000","2,026","1,300" Fortaleza,Brazil,"2,650,000",583,"4,550" Curitiba,Brazil,"2,500,000",648,"3,850" Rome,Italy,"2,500,000",842,"2,950" Naples,Italy,"2,400,000",583,"4,100" Minneapolis/St. Paul,USA,"2,389,000","2,316","1,050" Tel Aviv,Israel,"2,300,000",453,"5,050" Birmingham,UK,"2,284,000",600,"3,800" Frankfurt,Germany,"2,260,000",984,"2,300" Lisbon,Portugal,"2,250,000",881,"2,550" Manchester,UK,"2,245,000",558,"4,000" San Juan,Puerto Rico,"2,217,000","2,309",950 Katowice,Poland,"2,200,000",544,"4,050" Tashkent,Uzbekistan,"2,200,000",531,"4,150" Fukuoka,Japan,"2,150,000",544,"3,950" Baku/Sumqayit,Azerbaijan,"2,100,000",544,"3,850" St. Louis,USA,"2,078,000","2,147",950 Baltimore,USA,"2,076,000","1,768","1,150" Sapporo,Japan,"2,075,000",414,"5,000" Tampa/St. Petersburg,USA,"2,062,000","2,078","1,000" Taichung,Taiwan,"2,000,000",510,"3,900" Warsaw,Poland,"2,000,000",466,"4,300" Denver,USA,"1,985,000","1,292","1,550" Cologne/Bonn,Germany,"1,960,000",816,"2,400" Hamburg,Germany,"1,925,000",829,"2,300" Dubai,UAE,"1,900,000",712,"2,650" Pretoria,South Africa,"1,850,000",673,"2,750" Vancouver,Canada,"1,830,000","1,120","1,650" Beirut,Lebanon,"1,800,000",648,"2,800" Budapest,Hungary,"1,800,000",702,"2,550" Cleveland,USA,"1,787,000","1,676","1,050" Pittsburgh,USA,"1,753,000","2,208",800 Campinas,Brazil,"1,750,000",492,"3,550" Harare,Zimbabwe,"1,750,000",712,"2,450" Brasilia,Brazil,"1,625,000",583,"2,800" Kuwait,Kuwait,"1,600,000",544,"2,950" Munich,Germany,"1,600,000",518,"3,100" Portland,USA,"1,583,000","1,228","1,300" Brussels,Belgium,"1,570,000",712,"2,200" Vienna,Austria,"1,550,000",453,"3,400" San Jose,USA,"1,538,000",674,"2,300" Damman,Saudi Arabia,"1,525,000",673,"2,250" Copenhagen,Denmark,"1,525,000",816,"1,850" Brisbane,Australia,"1,508,000","1,603",950 Riverside/San Bernardino,USA,"1,507,000","1,136","1,350" Cincinnati,USA,"1,503,000","1,740",850 Accra,Ghana,"1,500,000",453,"3,300" ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/datasets/worldPopulation.dset ================================================ { "uuid": "worldResidents", "name": "World Population", "provider": "CSV", "isPublic": true, "filePath": "worldPopulation.csv", "separatorChar": ",", "quoteChar": "\"", "escapeChar": "\\", "datePattern": "MM-dd-yyyy", "numberPattern": "#,###.##", "columns": [ {"id": "City / Urban area", "type": "label"}, {"id": "Country", "type": "label"}, {"id": "Population", "type": "number"}, {"id": "Population", "type": "number"}, {"id": "Land area", "type": "number"}, {"id": "Density", "type": "number"} ] } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/jboss-deployment-structure.xml ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/jboss-web.xml ================================================ other ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/WEB-INF/web.xml ================================================ GzipFilter org.uberfire.backend.server.util.gzip.GzipFilter GzipFilter *.js request-capture org.uberfire.ext.security.server.SecurityIntegrationFilter request-capture * Avoid Host Page Cache org.uberfire.ext.security.server.CacheHeadersFilter Avoid Host Page Cache /dashbuilder.html Host Page Patch org.jboss.errai.security.server.servlet.UserHostPageFilter Host Page Patch /dashbuilder.html GWT Locale Filter org.uberfire.server.locale.GWTLocaleHeaderFilter GWT Locale Filter /dashbuilder.html UberFire Security Headers Filter org.uberfire.ext.security.server.SecureHeadersFilter x-frame-options SAMEORIGIN x-xss-protection-enable true x-xss-protection-block true UberFire Security Headers Filter * LoginRedirectServlet org.uberfire.ext.security.server.LoginRedirectServlet display-after-login /dashbuilder.html LoginRedirectServlet /login FORM /login.jsp /login.jsp?message=Login failed. Please try again. ErraiServlet org.jboss.errai.bus.server.servlet.DefaultBlockingServlet service-locator org.jboss.errai.cdi.server.CDIServiceLocator 1 ErraiServlet *.erraiBus UberfireFileUploadServlet org.uberfire.server.FileUploadServlet includes-path git://**,default://** excludes-path file://** UberfireFileUploadServlet /org.dashbuilder.DashbuilderShowcase/defaulteditor/upload/* UberfireFileDownloadServlet org.uberfire.server.FileDownloadServlet includes-path git://**,default://** excludes-path file://** UberfireFileDownloadServlet /org.dashbuilder.DashbuilderShowcase/defaulteditor/download/* DashbuilderExternalComponentsServlet org.dashbuilder.external.ExternalComponentServlet DashbuilderExternalComponentsServlet /dashbuilder/component/* Administrator - Manages application configuration and creates dashboards admin User - Consumes existing dashboards user openResources /org.dashbuilder.DashbuilderShowcase/patternfly/* default /dashbuilder.html /org.dashbuilder.DashbuilderShowcase/* *.erraiBus /plugins/* /dashbuilder/component/* admin user download /org.dashbuilder.DashbuilderShowcase/archive /org.dashbuilder.DashbuilderShowcase/defaulteditor/upload/* /org.dashbuilder.DashbuilderShowcase/defaulteditor/download/* admin user public /org.dashbuilder.DashbuilderShowcase/css/* /org.dashbuilder.DashbuilderShowcase/fonts/* /org.dashbuilder.DashbuilderShowcase/img/* 403 /not_authorized.jsp index.jsp ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/banner/banner.html ================================================ ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/dashbuilder.html ================================================ Dashbuilder

    Please wait

    Loading application...
    ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/index.jsp ================================================ <% String queryString = request.getQueryString(); String redirectURL = request.getContextPath() +"/login?"+(queryString==null?"":queryString); response.sendRedirect(redirectURL); %> ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/login.jsp ================================================ <%-- ~ Copyright 2016 Red Hat, Inc. and/or its affiliates. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --%> <%@ page import="java.util.Locale" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <% Locale locale = null; try { locale = new Locale( request.getParameter( "locale" ) ); } catch ( Exception e ) { locale = request.getLocale(); } %> Dashbuilder Dashbuilder Logo
    ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/logout.jsp ================================================ <%-- ~ Copyright 2015 Red Hat, Inc. and/or its affiliates. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.Locale" %> <% request.logout(); javax.servlet.http.HttpSession httpSession = request.getSession(false); if (httpSession != null) { httpSession.invalidate(); } Locale locale = null; try { locale = new Locale( request.getParameter( "locale" ) ); } catch ( Exception e ) { locale = request.getLocale(); } %> Dashbuilder Dashbuilder Logo
    ================================================ FILE: dashbuilder/dashbuilder-webapp/src/main/webapp/not_authorized.jsp ================================================ <%-- ~ Copyright 2015 Red Hat, Inc. and/or its affiliates. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.Locale" %> <% request.getSession().invalidate(); Locale locale = null; try { locale = new Locale( request.getParameter( "locale" ) ); } catch ( Exception e ) { locale = request.getLocale(); } %> Dashbuilder Dashbuilder Logo
    ================================================ FILE: dashbuilder/dashbuilder-webapp/src/test/java/org/dashbuilder/security/SecurityPolicyTest.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dashbuilder.security; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import javax.enterprise.event.Event; import org.dashbuilder.perspectives.PerspectiveIds; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.backend.events.AuthorizationPolicyDeployedEvent; import org.uberfire.backend.server.authz.AuthorizationPolicyDeployer; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.AuthorizationResult; import org.uberfire.security.authz.Permission; import org.uberfire.security.authz.PermissionCollection; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.impl.authz.DefaultPermissionManager; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.uberfire.security.authz.AuthorizationResult.*; @RunWith(MockitoJUnitRunner.class) public class SecurityPolicyTest { static final String HOME_PERSPECTIVE = PerspectiveIds.HOME; static final List DEFAULT_DENIED = Arrays.asList( "perspective.read", "perspective.create", "perspective.delete", "perspective.update"); @Mock AuthorizationPolicyStorage storage; @Mock Event deployedEvent; AuthorizationPolicyDeployer deployer; PermissionManager permissionManager; AuthorizationPolicy policy; @Before public void setUp() throws Exception { permissionManager = new DefaultPermissionManager(); deployer = new AuthorizationPolicyDeployer(storage, permissionManager, deployedEvent); URL fileURL = Thread.currentThread().getContextClassLoader().getResource("security-policy.properties"); Path policyDir = Paths.get(fileURL.toURI()).getParent(); deployer.deployPolicy(policyDir); ArgumentCaptor policyCaptor = ArgumentCaptor.forClass(AuthorizationPolicy.class); verify(storage).loadPolicy(); verify(storage).savePolicy(policyCaptor.capture()); policy = policyCaptor.getValue(); } @Test public void testPolicyDeployment() { assertNotNull(policy); assertEquals(policy.getRoles().size(), 1); verify(storage).savePolicy(policy); verify(deployedEvent).fire(any()); } @Test public void testDefaultPermissions() { assertEquals(policy.getHomePerspective(), HOME_PERSPECTIVE); PermissionCollection pc = policy.getPermissions(); for (String permissionName : DEFAULT_DENIED) { Permission p = pc.get(permissionName); assertNotNull(p); assertEquals(p.getResult(), ACCESS_DENIED); } } @Test public void testAdminPermissions() { testPermissions(new RoleImpl("admin"), null, HOME_PERSPECTIVE, ACCESS_GRANTED, null); } public void testPermissions(Role role, List exceptionList, String homeExpected, AuthorizationResult defaultExpected, AuthorizationResult exceptionExpected) { assertEquals(role != null ? policy.getHomePerspective(role) : policy.getHomePerspective(), homeExpected); PermissionCollection pc = policy.getPermissions(role); for (String permissionName : DEFAULT_DENIED) { if (exceptionList == null || !exceptionList.contains(permissionName)) { Permission p = pc.get(permissionName); assertNotNull(p); assertEquals(p.getResult(), defaultExpected); } } if (exceptionList != null) { for (String permissionName : exceptionList) { Permission p = pc.get(permissionName); assertNotNull(p); assertEquals(p.getResult(), exceptionExpected); } } } } ================================================ FILE: dashbuilder/dashbuilder-webapp/src/test/resources/datasources/h2-test-ds.xml ================================================ jdbc:h2:~/test;DATABASE_TO_UPPER=FALSE h2 sa sa ================================================ FILE: dashbuilder/pom.xml ================================================ 4.0.0 org.uberfire uberfire-parent 7.75.0-SNAPSHOT org.dashbuilder dashbuilder-parent 7.75.0-SNAPSHOT pom Dashbuilder Project dashbuilder-backend dashbuilder-shared dashbuilder-client dashbuilder-packaging dashbuilder-webapp dashbuilder-runtime fullProfile full dashbuilder-distros ================================================ FILE: dashbuilder/scripts/release/dashbuilder-createAndDeploy.sh ================================================ #!/bin/bash -e # removing dashbuilder artifacts from local maven repo (basically all possible SNAPSHOTs) if [ -d $MAVEN_REPO_LOCAL ]; then rm -rf $MAVEN_REPO_LOCAL/org/dashbuilder/ fi # clone the repository and branch git clone git@github.com:dashbuilder/dashbuilder.git --branch $baseBranch # checkout the release branch cd $WORKSPACE/dashbuilder git checkout -b $releaseBranch $baseBranch # upgrades the version to the release/tag version sh scripts/release/update-version.sh $newVersion # update files that are not automatically changed with the update-version.sh script sed -i "$!N;s/.*.<\/version.org.uberfire>/$uberfireVersion<\/version.org.uberfire>/;P;D" pom.xml sed -i "$!N;s/.*.<\/version.org.jboss.errai>/$erraiVersion<\/version.org.jboss.errai>/;P;D" pom.xml sed -i "$!N;s/.*.<\/version.org.kie.soup>/$kiesoupVersion<\/version.org.kie.soup>/;P;D" pom.xml # git add and commit the version update changes git add . commitMsg="update to version $newVersion" git commit -m "$commitMsg" if [ "$target" == "community" ]; then stagingProfile=15c58a1abc895b else stagingProfile=15c3321d12936e fi # build the repos & deploy into local dir (will be later copied into staging repo) deployDir=$WORKSPACE/deployDir # (1) do a full build, but deploy only into local dir # we will deploy into remote staging repo only once the whole build passed (to save time and bandwith) mvn -B -e -U clean deploy -Dfull -Drelease -T1C -DaltDeploymentRepository=local::default::file://$deployDir -Dmaven.test.failure.ignore=true\ -Dgwt.memory.settings="-Xmx2g -Xms1g -Xss1M" -Dgwt.compiler.localWorkers=2 # (2) upload the content to remote staging repo cd $deployDir mvn -B -e org.sonatype.plugins:nexus-staging-maven-plugin:1.6.5:deploy-staged-repository -DnexusUrl=https://repository.jboss.org/nexus -DserverId=jboss-releases-repository\ -DrepositoryDirectory=$deployDir -DstagingProfileId=$stagingProfile -DstagingDescription="dashbuilder $newVersion" -DstagingProgressTimeoutMinutes=30 cd $WORKSPACE/dashbuilder # pushes the release-branches to rhub.com:jboss-integration or github.com:dashbuilder [IMPORTANT: "push -n" (--dryrun) should be replaced by "push" when script is finished and will be applied] if [ "$target" == "community" ]; then git push origin $releaseBranch else git remote add upstream git@github.com:jboss-integration/dashbuilder.git git push upstream $releaseBranch git push upstream $baseBranch fi ================================================ FILE: dashbuilder/scripts/release/dashbuilder-pushTag.sh ================================================ #!/bin/bash -e # clone the repository and the release-branch if [ "$target" == "productized" ]; then git clone git@github.com:jboss-integration/dashbuilder.git --branch $releaseBranch else git clone git@github.com:dashbuilder/dashbuilder.git --branch $releaseBranch fi commitMsg="Tagging $tag" cd $WORKSPACE/dashbuilder # pushes the TAG to ssh://jb-ip-tooling-jenkins@code.engineering.redhat.com/dashbuilder [IMPORTANT: "push -n" (--dryrun) should be replaced by "push" when script is ready] if [ "$target" == "productized" ]; then git tag -a $TAG -m "$commitMsg" git remote add gerrit ssh://jb-ip-tooling-jenkins@code.engineering.redhat.com/dashbuilder git push gerrit $tag else git tag -a $TAG -m "$commitMsg" git push origin $tag fi ================================================ FILE: dashbuilder/scripts/release/dashbuilder-updateVersion.sh ================================================ #!/bin/bash -e targetUser=kiereleaseuser remoteUrl=git@github.com:kiereleaseuser/dashbuilder.git DATE=$(date "+%Y-%m-%d") # clone the repository and branch of dashbuilder git clone git@github.com:dashbuilder/dashbuilder.git --branch $baseBranch cd $WORKSPACE/dashbuilder prBranch=dashbuilder-upgrade-version-$DATE-$baseBranch git checkout -b $prBranch $baseBranch git remote add $targetUser $remoteUrl # upgrades the version to next development version of dashbuilder sh scripts/release/update-version.sh $newVersion # change properties via sed as they don't update automatically sed -i \ -e "$!N;s/.*.<\/version.org.uberfire>/$uberfireDevelVersion<\/version.org.uberfire>/;" \ -e "s/.*.<\/version.org.jboss.errai>/$erraiDevelVerison<\/version.org.jboss.errai>/;P;D" \ pom.xml # git add and commit the version update changes git add . commitMsg="update to next development version $newVersion" git commit -m "$commitMsg" # do a build of dashbuilder mvn -B -e -U clean install -Dfull -Dgwt.memory.settings="-Xmx3g -Xms1g -Xss1M" # Raise a PR source=dashbuilder git push $targetUser $prBranch hub pull-request -m "$commitMsg" -b $source:$baseBranch -h $targetUser:$prBranch ================================================ FILE: dashbuilder/scripts/release/update-version.sh ================================================ #!/bin/bash set -e # Updates the version for all Dashbuilder modules initializeWorkingDirAndScriptDir() { # Set working directory and remove all symbolic links workingDir=`pwd -P` # Go the script directory cd `dirname $0` # If the file itself is a symbolic link (ignoring parent directory links), then follow that link recursively # Note that scriptDir=`pwd -P` does not do that and cannot cope with a link directly to the file scriptFileBasename=`basename $0` while [ -L "$scriptFileBasename" ] ; do scriptFileBasename=`readlink $scriptFileBasename` # Follow the link cd `dirname $scriptFileBasename` scriptFileBasename=`basename $scriptFileBasename` done # Set script directory and remove other symbolic links (parent directory links) scriptDir=`pwd -P` } mvnVersionsSet() { newVersion=$1 mvn -B -N -Dfull versions:set -DnewVersion=$newVersion -DallowSnapshots=true -DgenerateBackupPoms=false } initializeWorkingDirAndScriptDir dashbuilderTopLevelDir="$scriptDir/../.." if [ $# != 1 ] ; then echo echo "Usage:" echo " $0 newVersion" echo "For example:" echo " $0 0.5.0.Final" echo exit 1 fi newVersion=$1 startDateTime=`date +%s` cd $dashbuilderTopLevelDir mvnVersionsSet $newVersion # fix leftovers not covered by the first run cd $dashbuilderTopLevelDir/dashbuilder-bom mvnVersionsSet $newVersion endDateTime=`date +%s` spentSeconds=`expr $endDateTime - $startDateTime` echo echo "Total time: ${spentSeconds}s" ================================================ FILE: drools_jbpm_eclipse_formatter_config.xml ================================================ ================================================ FILE: pom.xml ================================================ 4.0.0 org.kie kie-parent 7.75.0-SNAPSHOT org.uberfire uberfire-parent 7.75.0-SNAPSHOT pom UberFire parent The parent contains all metadata (including plugins) and also dependency versions. All UberFire modules (except for user BOMs like 'uberfire-bom') should (transitively) inherit from this POM. 2012 JBoss by Red Hat http://www.jboss.org/ Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo ${project.version} ${version.org.kie} 3.18.1 1.0.4 1.10.0 2.29.4 0.5.17 3.1.1 16.6.0 16.6.0 2.1.25 1.3.3 1.2.61 0.1 3.0.1 5.5.0 0.6.6 2.5.1 1.12.1 1.2.7.SP1 2.19.1 linux-x86_64 osx-x86_64 3.3.0 ${maven.build.timestamp} https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/ https://repository.jboss.org/nexus/content/repositories/snapshots/ 4.3.5.Final 1.2.13 0.3 5.0.2 1.4.0.Final ${version.org.uberfire.latestFinal.release} ${project.version} 1.1.1 0.1.1 1.3.6 8.0.28 1.15.3 1.2.6 1.2.3.GA 1.0.0.GA jboss-public-repository-group JBoss Public Repository Group https://repository.jboss.org/nexus/content/groups/public/ true never true daily jboss-public-repository-group JBoss Public Repository Group https://repository.jboss.org/nexus/content/groups/public/ true true scm:git:git@github.com:uberfire/uberfire.git scm:git:git@github.com:uberfire/uberfire.git https://github.com/uberfire/uberfire jira https://issues.jboss.org/browse/UF org.apache.maven.plugins maven-resources-plugin UTF-8 org.codehaus.mojo build-helper-maven-plugin parse-version add-source generate-sources add-source target/generated-sources/annotations org.codehaus.mojo gwt-maven-plugin ${version.com.google.gwt} org.apache.felix maven-bundle-plugin true true <_removeheaders>Ignore-Package <_nouses>true <_snapshot>${osgi.snapshot.qualifier} ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}.${osgi.snapshot.qualifier} NONE org.apache.maven.plugins maven-surefire-plugin false false true ${project.build.directory} true **/*Test.java **/*IntegrationTest.java -Xmx1024m -Dfile.encoding=UTF-8 org.apache.maven.plugins maven-failsafe-plugin integration-test verify **/*IntegrationTest.java -Xmx1024m -Dfile.encoding=UTF-8 org.apache.maven.plugins maven-source-plugin attach-sources jar-no-fork 2 ${project.artifactId}.source ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}.${osgi.snapshot.qualifier} ${project.name} ${project.organization.name} ${project.artifactId};version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}.${osgi.snapshot.qualifier}";roots:="." attach-test-sources test-jar-no-fork 2 ${project.artifactId}.tests.source ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}.${osgi.snapshot.qualifier} ${project.name} ${project.organization.name} ${project.artifactId}.tests;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}.${osgi.snapshot.qualifier}";roots:="." org.commonjava.maven.plugins project-sources-maven-plugin 1.0 project-sources-archive initialize archive org.codehaus.mojo versions-maven-plugin 2.2 org.apache.maven.plugins maven-release-plugin false true org.apache.maven.plugins maven-javadoc-plugin http://docs.oracle.com/javase/8/docs/api 128m 512m false true true org.codehaus.mojo jaxb2-maven-plugin 1.3 org.eclipse.m2e lifecycle-mapping 1.0.0 org.codehaus.mojo build-helper-maven-plugin [1.7,) parse-version org.codehaus.mojo gwt-maven-plugin [2.3.0,) resources org.codehaus.mojo build-helper-maven-plugin org.apache.maven.plugins maven-source-plugin maven-enforcer-plugin maven-clean-plugin ${basedir} src/main/webapp/WEB-INF/deploy/ src/main/webapp/WEB-INF/classes/ src/main/webapp/WEB-INF/lib/ .errai/ .niogit/** com.google.code.maven-replacer-plugin replacer 1.5.2 **/*Constants_de.properties **/*Constants_es.properties **/*Constants_fr.properties **/*Constants_ja.properties **/*Constants_pt_BR.properties **/*Constants_zh_CN.properties **/*Constants_ru.properties **/ErraiApp.properties '' ' ' '' org.zanata zanata-maven-plugin 2.3.0 **/ErraiApp.properties ${session.executionRootDirectory}/src/main/config/zanata.xml src/main/resources/ src/main/resources/ **/*Constants.properties org.apache.maven.plugins maven-jar-plugin org.apache.maven.plugins maven-failsafe-plugin maven-antrun-plugin create-default-i18n-resource process-resources run org.apache.maven.plugins maven-checkstyle-plugin org/uberfire/build/uberfire_checks.xml org/uberfire/build/uberfire_license_header.txt graph org.fusesource.mvnplugins maven-graph-plugin 1.38 dependency-graph-reactor install reactor true org.revapi revapi-maven-plugin 0.8.1 org.revapi revapi-java 0.13.1 ${project.groupId}:${project.artifactId}:${revapi.oldUberFireVersion} ${project.groupId}:${project.artifactId}:${revapi.newUberFireVersion} src/build/revapi-config.json filters ignores nonBreaking potentiallyBreaking check check verify report report package run-code-coverage *Lexer org.jacoco org.jacoco.agent runtime ${version.jacoco.plugin} test org.jacoco org.jacoco.agent runtime test org.jacoco jacoco-maven-plugin ${version.jacoco.plugin} true ${jacoco.exec.file} ${jacoco.excludes} default-instrument instrument default-restore-instrumented-classes restore-instrumented-classes net.ltgt.gwt.maven gwt-maven-plugin true maven-surefire-plugin ${jacoco.exec.file} org.jacoco jacoco-maven-plugin uberfire-commons uberfire-api uberfire-client-api uberfire-security uberfire-nio2-backport uberfire-io uberfire-server uberfire-backend uberfire-js uberfire-testing-utils uberfire-experimental uberfire-workbench uberfire-packaging uberfire-preferences uberfire-extensions uberfire-m2repo-editor uberfire-message-console uberfire-project uberfire-rest uberfire-services uberfire-structure uberfire-test-utils uberfire-workingset uberfire-ssh uberfire-showcase dashbuilder appformer-js-bridge appformer-js appformer-client-api appformer-js-monaco org.uberfire uberfire-bom ${version.org.kie} pom import org.kie kie-bom ${version.org.kie} pom import org.kie.soup kie-soup-bom ${version.org.kie.soup} pom import org.jboss.errai errai-jaxrs-client test-jar ${version.org.jboss.errai} jakarta.enterprise jakarta.enterprise.cdi-api ${version.jakarta.enterprise.cdi-api} org.eclipse.jgit org.eclipse.jgit ${version.org.eclipse.jgit} commons-logging commons-logging org.eclipse.jgit org.eclipse.jgit.http.server ${version.org.eclipse.jgit} commons-logging commons-logging javax.servlet servlet-api org.keycloak keycloak-core ${version.org.keycloak} org.keycloak keycloak-common ${version.org.keycloak} org.keycloak keycloak-adapter-core ${version.org.keycloak} com.google.jsinterop base ${version.com.google.jsinterop.base} com.allen-sauer.gwt.dnd gwt-dnd ${version.com.allen-sauer.gwt.dnd} javax.servlet javax.servlet-api org.scannotation scannotation ${version.org.scannotation} javassist javassist org.jboss.byteman byteman ${version.org.jboss.byteman} test org.jboss.byteman byteman-submit ${version.org.jboss.byteman} test org.jboss.byteman byteman-install ${version.org.jboss.byteman} test org.jboss.byteman byteman-bmunit ${version.org.jboss.byteman} test io.netty netty ${version.io.netty.old} org.infinispan infinispan-client-hotrod ${version.org.infinispan} org.jboss.spec.javax.transaction jboss-transaction-api_1.2_spec ch.qos.logback logback-classic org.jboss.marshalling jboss-marshalling-osgi org.infinispan infinispan-commons ${version.org.infinispan} org.jboss.marshalling jboss-marshalling-osgi org.infinispan.protostream protostream ${version.org.infinispan.protostream} org.wildfly.security wildfly-elytron ${version.org.wildfly.security} org.apache.activemq artemis-jms-client ${version.org.apache.activemq.artemis} org.jboss.spec.javax.jms jboss-jms-api_2.0_spec org.apache.geronimo.specs geronimo-json_1.0_spec commons-logging commons-logging io.netty netty-buffer ${version.io.netty} io.netty netty-transport ${version.io.netty} io.netty netty-handler ${version.io.netty} io.netty netty-transport-native-epoll ${version.io.netty} ${netty-transport-native-epoll-classifier} io.netty netty-transport-native-kqueue ${version.io.netty} ${netty-transport-native-kqueue-classifier} io.netty netty-codec-http ${version.io.netty} com.github.tdomzal junit-docker-rule ${version.jnuit.docker.rule} test com.spotify docker-client ${version.com.spotify.docker} test commons-logging commons-logging ch.qos.logback logback-classic ${version.ch.qos.logback} ch.qos.logback logback-core ${version.ch.qos.logback} org.apache.httpcomponents httpclient ${version.org.apache.httpcomponents.httpclient} commons-logging commons-logging com.jcraft jsch ${version.com.jcraft} com.googlecode.json-simple json-simple ${version.com.googlecode.jsonsimple} jar com.googlecode.jtype jtype ${version.com.googlecode.jtype} org.jboss.msc jboss-msc ${version.org.jboss.jboss-msc} org.apache.logging.log4j log4j-to-slf4j ${version.org.apache.logging.log4j} mysql mysql-connector-java ${version.org.mysql-driver} test org.postgresql postgresql test org.mariadb.jdbc mariadb-java-client ${version.org.mariadb.jdbc} test org.arquillian.cube arquillian-cube-docker-junit-rule ${version.org.arquillian.cube} test javax.enterprise cdi-api log4j log4j com.github.docker-java docker-java org.arquillian.cube arquillian-cube-requirement-spi org.jboss.marshalling marshalling-api ${version.org.jboss.marshalling.api} test org.jboss.shrinkwrap shrinkwrap-impl-base ${version.org.jboss.shrinkwrap} test junit junit ${version.junit} org.assertj assertj-core ${version.org.assertj} junit junit test org.mockito mockito-core test org.assertj assertj-core test com.google.inject guice test javax.inject javax.inject ================================================ FILE: uberfire-api/.gitignore ================================================ /target /local # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject /*.ipr /*.iws /*.iml # Repository wide ignore mac DS_Store files .DS_Store ================================================ FILE: uberfire-api/pom.xml ================================================ 4.0.0 org.uberfire uberfire-parent 7.75.0-SNAPSHOT ../pom.xml uberfire-api jar UberFire API UberFire API org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.jboss.errai errai-common org.jboss.errai errai-ioc org.jboss.errai errai-security-server org.jboss.errai errai-marshalling com.google.elemental2 elemental2-dom com.google.gwt gwt-user provided com.google.jsinterop jsinterop-annotations ================================================ FILE: uberfire-api/src/main/java/org/uberfire/annotations/Customizable.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.inject.Qualifier; /** * Internal annotation used to inject/produce beans in a way that the user can provide a default * implementation for them, otherwise a fallback implementation will be used. */ @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Customizable { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/annotations/FallbackImplementation.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.inject.Qualifier; /** * Internal annotation used to qualify fallback implementations, that will be used when the user * does not provide another (default) implementation. */ @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface FallbackImplementation { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/FileSystem.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.util.List; import java.util.Set; public interface FileSystem { List getRootDirectories(); Set supportedFileAttributeViews(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/IsVersioned.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; public interface IsVersioned { boolean hasVersionSupport(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/ObservablePath.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import org.uberfire.commons.lifecycle.Disposable; import org.uberfire.mvp.Command; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.rpc.SessionInfo; public interface ObservablePath extends Path, Disposable { void onRename(final Command command); void onDelete(final Command command); void onUpdate(final Command command); void onCopy(final Command command); void onConcurrentRename(final ParameterizedCommand command); void onConcurrentDelete(final ParameterizedCommand command); void onConcurrentUpdate(final ParameterizedCommand command); void onConcurrentCopy(final ParameterizedCommand command); ObservablePath wrap(final Path path); Path getOriginal(); public interface OnConcurrentUpdateEvent extends SessionInfo { Path getPath(); } public interface OnConcurrentDelete extends SessionInfo { Path getPath(); } public interface OnConcurrentRenameEvent extends SessionInfo { Path getSource(); Path getTarget(); } public interface OnConcurrentCopyEvent extends SessionInfo { Path getSource(); Path getTarget(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/Path.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import jsinterop.annotations.JsType; @JsType public interface Path extends Comparable { String getFileName(); String toURI(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/PathFactory.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.util.HashMap; import java.util.Map; import org.jboss.errai.common.client.api.annotations.Portable; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotEmpty; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; public final class PathFactory { public static final String LOCK_FILE_EXTENSION = ".ulock"; public static String VERSION_PROPERTY = "hasVersionSupport"; private PathFactory() { } public static Path newPath(final String fileName, final String uri) { return new PathImpl(checkNotEmpty("fileName", fileName), checkNotEmpty("uri", uri)); } public static Path newPathBasedOn(final String fileName, final String uri, final Path path) { return new PathImpl(checkNotEmpty("fileName", fileName), checkNotEmpty("uri", uri), checkNotNull("path", path)); } public static Path newPath(final String fileName, final String uri, final Map attrs) { return new PathImpl(checkNotEmpty("fileName", fileName), checkNotEmpty("uri", uri), attrs); } public static Path newLock(final Path path) { Path lockPath = newLockPath(path); return PathFactory.newPath(path.getFileName() + LOCK_FILE_EXTENSION, lockPath.toURI() + LOCK_FILE_EXTENSION); } /** * Returns a path of a lock for the provided file. *

    * Examples: *

    *

         * default://main@myteam/dora/src/main/resources/com/myteam/dora/sample.drl
         *           branch@space/project/path/to/file.extension                      =>
         * default://locks@system/system/myteam/main/dora/src/main/resources/com/myteam/dora/sample.drl
         *
         * 
    * * @param path the path of a file for which a lock should be created, must not be null. * @return the lock path */ public static Path newLockPath(final Path path) { checkNotNull("path", path); final String systemUri = path.toURI().replaceFirst("(/|\\\\)([^/&^\\\\]*)@([^/&^\\\\]*)", "$1locks@system/system$1$3$1$2"); return PathFactory.newPath("/", systemUri); } /** * Returns the path of the locked file for the provided lock. *

    * Examples: *

    *

         * default://locks@system/system/myteam/main/dora/src/main/resources/com/myteam/dora/sample.drl.ulock
         * default://main@myteam/dora/src/main/resources/com/myteam/dora/sample.drl
         *           branch@space/project/path/to/file.extension                      =>
         * 
    * * @param lockPath the path of a lock, must not be null. * @return the locked path. */ public static Path fromLock(final Path lockPath) { checkNotNull("path", lockPath); final String uri = lockPath.toURI().replaceFirst("locks@system/system(/|\\\\)([^/&^\\\\]*)(/|\\\\)([^/&^\\\\]*)", "$4@$2"); return PathFactory.newPath(lockPath.getFileName().replace(LOCK_FILE_EXTENSION, ""), uri.replace(LOCK_FILE_EXTENSION, "")); } @Portable public static class PathImpl implements Path, IsVersioned { private String uri = null; private String fileName = null; private HashMap attributes = null; private boolean hasVersionSupport = false; public PathImpl() { } public PathImpl(final String fileName, final String uri) { this(fileName, uri, (Map) null); } private PathImpl(final String fileName, final String uri, final Map attrs) { this.fileName = fileName; this.uri = uri; if (attrs == null) { this.attributes = new HashMap(); } else { if (attrs.containsKey(VERSION_PROPERTY)) { hasVersionSupport = (Boolean) attrs.remove(VERSION_PROPERTY); } if (attrs.size() > 0) { this.attributes = new HashMap(attrs); } else { this.attributes = new HashMap(); } } } private PathImpl(final String fileName, final String uri, final Path path) { this.fileName = fileName; this.uri = uri; if (path instanceof PathImpl) { this.hasVersionSupport = ((PathImpl) path).hasVersionSupport; } } @Override public String getFileName() { return fileName; } @Override public String toURI() { return uri; } public Map getAttributes() { return attributes; } @Override public int compareTo(final Path another) { return this.uri.compareTo(another.toURI()); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Path)) { return false; } final Path path = (Path) o; return this.toURI().equals(path.toURI()); } @Override public boolean hasVersionSupport() { return hasVersionSupport; } @Override public int hashCode() { return uri.hashCode(); } @Override public String toString() { return "PathImpl{" + "uri='" + uri + '\'' + ", fileName='" + fileName + '\'' + ", attrs=" + attributes + '}'; } } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/PathSupport.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; public final class PathSupport { public static boolean isVersioned(final Path path) { return path instanceof IsVersioned && ((IsVersioned) path).hasVersionSupport(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/ForceUnlockEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs.impl; import org.uberfire.backend.vfs.Path; /** * Client-local event to indicate that the specified path's lock should be * released. This is used in admin functionality for overriding locks. The user * currently holding the lock will not be notified and can potentially lose * data. */ public class ForceUnlockEvent { private final Path path; public ForceUnlockEvent(Path path) { this.path = path; } public Path getPath() { return path; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/LockInfo.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs.impl; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; /** * Holds lock information about a {@link Path}. */ @Portable public class LockInfo { private final boolean locked; private final String lockedBy; private final Path file; private final transient Path lock; public LockInfo(@MapsTo("locked") boolean locked, @MapsTo("lockedBy") String lockedBy, @MapsTo("file") Path file) { this(locked, lockedBy, file, null); } public LockInfo(boolean locked, String lockedBy, Path file, Path lock) { this.locked = locked; this.lockedBy = lockedBy; this.file = file; this.lock = lock; } public static LockInfo unlocked() { return new LockInfo(false, null, null); } public boolean isLocked() { return locked; } public String lockedBy() { return lockedBy; } public Path getFile() { return file; } public Path getLock() { return lock; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((file == null) ? 0 : file.hashCode()); result = prime * result + (locked ? 1231 : 1237); result = prime * result + ((lockedBy == null) ? 0 : lockedBy.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; } LockInfo other = (LockInfo) obj; if (file == null) { if (other.file != null) { return false; } } else if (!file.equals(other.file)) { return false; } if (locked != other.locked) { return false; } if (lockedBy == null) { if (other.lockedBy != null) { return false; } } else if (!lockedBy.equals(other.lockedBy)) { return false; } return true; } @Override public String toString() { return "[file=" + file + ", lockedBy=" + lockedBy + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/LockResult.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs.impl; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; /** * Represents the result of a lock request and holds the last read * {@link LockInfo}. */ @Portable public class LockResult { private final boolean success; private final LockInfo lockInfo; public LockResult(@MapsTo("success") boolean success, @MapsTo("lockInfo") LockInfo lockInfo) { this.success = success; this.lockInfo = lockInfo; } public static LockResult acquired(final Path path, final String lockedBy) { return new LockResult(true, new LockInfo(true, lockedBy, path)); } public static LockResult released(final Path path) { return new LockResult(true, new LockInfo(false, null, path)); } public static LockResult failed(final LockInfo lockInfo) { return new LockResult(false, lockInfo); } public static LockResult error() { return new LockResult(false, null); } public boolean isSuccess() { return success; } public LockInfo getLockInfo() { return lockInfo; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/backend/vfs/impl/ObservablePathImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs.impl; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.Dependent; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.jboss.errai.common.client.api.annotations.Portable; import org.jboss.errai.ioc.client.container.IOC; import org.jboss.errai.security.shared.api.identity.User; import org.uberfire.backend.vfs.IsVersioned; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.backend.vfs.Path; import org.uberfire.mvp.Command; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.rpc.SessionInfo; import org.uberfire.workbench.events.ResourceBatchChangesEvent; import org.uberfire.workbench.events.ResourceChange; import org.uberfire.workbench.events.ResourceCopied; import org.uberfire.workbench.events.ResourceCopiedEvent; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamed; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdatedEvent; @Portable @Dependent public class ObservablePathImpl implements ObservablePath, IsVersioned { private Path path; private transient Path original; @Inject transient SessionInfo sessionInfo; private transient List onRenameCommand = new ArrayList(); private transient List onDeleteCommand = new ArrayList(); private transient List onUpdateCommand = new ArrayList(); private transient List onCopyCommand = new ArrayList(); private transient List> onConcurrentRenameCommand = new ArrayList>(); private transient List> onConcurrentDeleteCommand = new ArrayList>(); private transient List> onConcurrentUpdateCommand = new ArrayList>(); private transient List> onConcurrentCopyCommand = new ArrayList>(); public ObservablePathImpl() { } public static String removeExtension(final String filename) { if (filename == null) { return null; } final int index = indexOfExtension(filename); if (index == -1) { return filename; } else { return filename.substring(0, index); } } public static int indexOfExtension(final String filename) { if (filename == null) { return -1; } final int extensionPos = filename.lastIndexOf("."); return extensionPos; } @Override public ObservablePath wrap(final Path path) { if (path instanceof ObservablePathImpl) { this.original = ((ObservablePathImpl) path).path; } else { this.original = path; } this.path = this.original; return this; } // Lazy-population of "original" for ObservablePathImpl de-serialized from a serialized PerspectiveDefinition that circumvent the "wrap" feature. // Renamed resources hold a reference to the old "original" Path which is needed to maintain an immutable hashCode used as part of the compound // Key for Activity and Place Management). However re-hydration stores the PartDefinition in a HashSet using the incorrect hashCode. By not // storing the "original" in the serialized form we can guarantee hashCodes in de-serialized PerspectiveDefinitions remain immutable. // See https://bugzilla.redhat.com/show_bug.cgi?id=1200472 for the re-producer. public Path getOriginal() { if (this.original == null) { wrap(this.path); } return this.original; } @Override public String getFileName() { return path.getFileName(); } @Override public String toURI() { return path.toURI(); } @Override public boolean hasVersionSupport() { return path instanceof IsVersioned && ((IsVersioned) path).hasVersionSupport(); } @Override public int compareTo(final Path o) { return path.compareTo(o); } @Override public void onRename(final Command command) { this.onRenameCommand.add(command); } @Override public void onDelete(final Command command) { this.onDeleteCommand.add(command); } @Override public void onUpdate(final Command command) { this.onUpdateCommand.add(command); } @Override public void onCopy(final Command command) { this.onCopyCommand.add(command); } @Override public void onConcurrentRename(final ParameterizedCommand command) { this.onConcurrentRenameCommand.add(command); } @Override public void onConcurrentDelete(final ParameterizedCommand command) { this.onConcurrentDeleteCommand.add(command); } @Override public void onConcurrentUpdate(final ParameterizedCommand command) { this.onConcurrentUpdateCommand.add(command); } @Override public void onConcurrentCopy(final ParameterizedCommand command) { this.onConcurrentCopyCommand.add(command); } @Override public void dispose() { onRenameCommand.clear(); onDeleteCommand.clear(); onUpdateCommand.clear(); onCopyCommand.clear(); onConcurrentRenameCommand.clear(); onConcurrentDeleteCommand.clear(); onConcurrentUpdateCommand.clear(); onConcurrentCopyCommand.clear(); if (IOC.getBeanManager() != null) { IOC.getBeanManager().destroyBean(this); } } void onResourceRenamed(@Observes final ResourceRenamedEvent renamedEvent) { if (path != null && path.equals(renamedEvent.getPath())) { path = renamedEvent.getDestinationPath(); if (sessionInfo.getId().equals(renamedEvent.getSessionInfo().getId())) { executeRenameCommands(); } else { executeConcurrentRenameCommand(renamedEvent.getPath(), renamedEvent.getDestinationPath(), renamedEvent.getSessionInfo().getId(), renamedEvent.getSessionInfo().getIdentity()); } } } void onResourceDeleted(@Observes final ResourceDeletedEvent deletedEvent) { if (path != null && path.equals(deletedEvent.getPath())) { if (sessionInfo.getId().equals(deletedEvent.getSessionInfo().getId())) { executeDeleteCommands(); } else { executeConcurrentDeleteCommand(deletedEvent.getPath(), deletedEvent.getSessionInfo().getId(), deletedEvent.getSessionInfo().getIdentity()); } } } void onResourceUpdated(@Observes final ResourceUpdatedEvent updatedEvent) { if (path != null && path.equals(updatedEvent.getPath())) { if (sessionInfo.getId().equals(updatedEvent.getSessionInfo().getId())) { executeUpdateCommands(); } else { executeConcurrentUpdateCommand(updatedEvent.getPath(), updatedEvent.getSessionInfo().getId(), updatedEvent.getSessionInfo().getIdentity()); } } } void onResourceCopied(@Observes final ResourceCopiedEvent copiedEvent) { if (path != null && path.equals(copiedEvent.getPath())) { if (sessionInfo.getId().equals(copiedEvent.getSessionInfo().getId())) { executeCopyCommands(); } else { executeConcurrentCopyCommand(copiedEvent.getPath(), copiedEvent.getDestinationPath(), copiedEvent.getSessionInfo().getId(), copiedEvent.getSessionInfo().getIdentity()); } } } void onResourceBatchEvent(@Observes final ResourceBatchChangesEvent batchEvent) { if (path != null && batchEvent.containPath(path)) { if (sessionInfo.getId().equals(batchEvent.getSessionInfo().getId())) { for (final ResourceChange change : batchEvent.getChanges(path)) { switch (change.getType()) { case COPY: executeCopyCommands(); break; case DELETE: executeDeleteCommands(); break; case RENAME: path = ((ResourceRenamed) change).getDestinationPath(); executeRenameCommands(); break; case UPDATE: executeUpdateCommands(); break; } } } else { for (final ResourceChange change : batchEvent.getChanges(path)) { switch (change.getType()) { case COPY: executeConcurrentCopyCommand(path, ((ResourceCopied) change).getDestinationPath(), batchEvent.getSessionInfo().getId(), batchEvent.getSessionInfo().getIdentity()); break; case DELETE: executeConcurrentDeleteCommand(path, batchEvent.getSessionInfo().getId(), batchEvent.getSessionInfo().getIdentity()); break; case RENAME: executeConcurrentRenameCommand(path, ((ResourceRenamed) change).getDestinationPath(), batchEvent.getSessionInfo().getId(), batchEvent.getSessionInfo().getIdentity()); path = ((ResourceRenamed) change).getDestinationPath(); break; case UPDATE: executeConcurrentUpdateCommand(path, batchEvent.getSessionInfo().getId(), batchEvent.getSessionInfo().getIdentity()); break; } } } } } private void executeRenameCommands() { if (!onRenameCommand.isEmpty()) { for (final Command command : onRenameCommand) { command.execute(); } } } void executeConcurrentRenameCommand(final Path path, final Path destinationPath, final String sessionId, final User identity) { if (!onConcurrentRenameCommand.isEmpty()) { for (final ParameterizedCommand command : onConcurrentRenameCommand) { final OnConcurrentRenameEvent event = new OnConcurrentRenameEvent() { @Override public Path getSource() { return path; } @Override public Path getTarget() { return destinationPath; } @Override public String getId() { return sessionId; } @Override public User getIdentity() { return identity; } }; command.execute(event); } } } private void executeCopyCommands() { if (!onCopyCommand.isEmpty()) { for (final Command command : onCopyCommand) { command.execute(); } } } void executeConcurrentCopyCommand(final Path path, final Path destinationPath, final String sessionId, final User identity) { if (!onConcurrentCopyCommand.isEmpty()) { final OnConcurrentCopyEvent copyEvent = new OnConcurrentCopyEvent() { @Override public Path getSource() { return path; } @Override public Path getTarget() { return destinationPath; } @Override public String getId() { return sessionId; } @Override public User getIdentity() { return identity; } }; for (final ParameterizedCommand command : onConcurrentCopyCommand) { command.execute(copyEvent); } } } private void executeUpdateCommands() { if (!onUpdateCommand.isEmpty()) { for (final Command command : onUpdateCommand) { command.execute(); } } } void executeConcurrentUpdateCommand(final Path path, final String sessionId, final User identity) { if (!onConcurrentUpdateCommand.isEmpty()) { final OnConcurrentUpdateEvent event = new OnConcurrentUpdateEvent() { @Override public Path getPath() { return path; } @Override public String getId() { return sessionId; } @Override public User getIdentity() { return identity; } }; for (final ParameterizedCommand command : onConcurrentUpdateCommand) { command.execute(event); } } } private void executeDeleteCommands() { if (!onDeleteCommand.isEmpty()) { for (final Command command : onDeleteCommand) { command.execute(); } } } void executeConcurrentDeleteCommand(final Path path, final String sessionId, final User identity) { if (!onConcurrentDeleteCommand.isEmpty()) { final OnConcurrentDelete event = new OnConcurrentDelete() { @Override public Path getPath() { return path; } @Override public String getId() { return sessionId; } @Override public User getIdentity() { return identity; } }; for (final ParameterizedCommand command : onConcurrentDeleteCommand) { command.execute(event); } } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Path)) { return false; } if (o instanceof ObservablePathImpl) { return this.getOriginal().equals(((ObservablePathImpl) o).getOriginal()); } return this.getOriginal().equals(o); } @Override public int hashCode() { return this.getOriginal().toURI().hashCode(); } @Override public String toString() { return toURI(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/debug/Debug.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.debug; /** * Utility methods that help with debugging. */ public class Debug { /** * The code requires this list to have 16 entries */ private static final String[] CONSONANTS = {"b", "d", "f", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", "v", "w", "z"}; /** * The code requires this list to have 8 entries */ private static final String[] VOWELS = {"a", "e", "ee", "i", "o", "oo", "u", "y"}; /** * Makes a reasonably easy-to-pronounce gibberish word from the given number. On average, the word will have about * as many characters as the number would have when printed as a decimal, but (especially for large numbers) it will * be easier to remember as a single word. * @param num The number to convert. * @return The memorable string, unique to the given number. Never null. */ public static String toMemorableString(long num) { StringBuilder memorable = new StringBuilder(); long hashNum = Math.abs(num); for (; ; ) { int chunk = (int) (hashNum & 0xf); memorable.append(CONSONANTS[chunk]); hashNum >>= 4; if (hashNum == 0) { break; } chunk = (int) (hashNum & 7); memorable.append(VOWELS[chunk]); hashNum >>= 3; if (hashNum == 0) { break; } } return memorable.toString(); } /** * Composes a compact, memorable unique string for the given object instance. The name starts with the abbreviated * fully-qualified class name (see {@link #abbreviatedName(Class)}), an '@' character, then a gibberish word * representing the object's identity hash code (see {@link #toMemorableString(long)}). * @param o * @return */ public static String objectId(Object o) { if (o == null) { return null; } return abbreviatedName(o.getClass()) + "@" + toMemorableString(System.identityHashCode(o)); } /** * Returns a compact representation of the fully-qualified name of the given class. The string is built with the following components: *
      *
    1. the first letter of each component of the package name *
    2. a dot *
    3. the class name. If the class is an inner class, the name is of the form Outer$Inner *
        *

        * For classes in the default package, items 1 and 2 are omitted. * @param c the class whose name to abbreviate. Can be null, but will result in a null return value. * @return the abbreviated FQCN as described, or null if the input is null. */ public static String abbreviatedName(Class c) { if (c == null) { return null; } StringBuilder result = new StringBuilder(); String fqcn = c.getName(); int lastDot = -1; int thisDot = -1; while ((thisDot = fqcn.indexOf('.', thisDot + 1)) != -1) { result.append(fqcn.charAt(lastDot + 1)); lastDot = thisDot; } if (lastDot != -1) { result.append('.'); } result.append(fqcn.substring(lastDot + 1)); return result.toString(); } /** * Returns the short name of the given class (no package name). This is the same as java.lang.Class.shortName(), * which is not implemented in the GWT version of java.lang.Class. * @param c the class whose name to abbreviate. Can be null, but will result in a null return value. * @return the abbreviated FQCN as described, or null if the input is null. */ public static String shortName(Class c) { if (c == null) { return null; } return c.getName().substring(c.getName().lastIndexOf('.') + 1); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/GetContent.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Used in method that returns a {@code @WorkbenchClientEditor} content. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface GetContent { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/GetPreview.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Use in method that returns a {@code @WorkbenchClientEditor} content preview. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface GetPreview { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/IsDirty.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @deprecated The code generated by use of this annotation will never be called by the UberFire framework. Use * {@link OnMayClose} instead. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface IsDirty { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnClose.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Methods annotated with this will be called by the Workbench immediately after a WorkbenchPart is closed. * WorkbenchParts can perform any clean-up tasks in the annotated method, but this does not include removing the view * widget from the DOM; this will have already been taken care of by the framework. The method must take zero * arguments and return void. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnClose { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnContextAttach.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnContextAttach { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnFocus.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that the framework should call the target method when the activity is the current activity in the current * panel. Activities may choose to make their UI more prominent, or begin refreshing their data more aggressively when * they are focused. *

        * This annotation only has meaning on methods declared in or inherited by {@code @WorkbenchScreen} or * {@code @WorkbenchEditor} classes. *

        * The target method must take no arguments and return void. */ @Inherited @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnFocus { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnLostFocus.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that the framework should call the target method when the activity is no longer the current activity in the * current panel. Typically, methods bearing this annotation will undo whatever effects they set up on the corresponding * {@link OnFocus} method. *

        * This annotation only has meaning on methods declared in or inherited by {@code @WorkbenchScreen} or * {@code @WorkbenchEditor} classes. *

        * The target method must take no arguments and return void. */ @Inherited @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnLostFocus { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnMayClose.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Methods annotated with this will be called by the Workbench before the WorkbenchPart is closed. The method must be non-private, * take zero arguments and return a boolean indicating whether the WorkbenchPart can be closed (true, it can be closed; * false it cannot be closed). *

        * This annotation only works on methods of classes annotated with {@code @WorkbenchScreen} or {@code @WorkbenchEditor}. */ @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnMayClose { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnOpen.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Methods annotated with this are called by the Workbench when a WorkbenchPart * is displayed. OnOpen annotated methods are called after the WorkbenchPart's * OnStartup annotated method. The method should take zero arguments and return * void. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnOpen { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnSave.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @deprecated The code generated by use of this annotation will never be called by the UberFire framework. Use an * application-defined mechanism (perhaps a Saveable interface or a CDI event) instead. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnSave { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnShutdown.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnShutdown { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/OnStartup.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** *

        * Methods annotated with this are called by the Workbench before methods * annotated with {@code @OnOpen}. WorkbenchParts should perform any * initialisation activities here (for example load their content from a * persistent store). *

        *

        * For {@code @WorkbenchEditor}'s the method should take a single argument of * type {@code org.drools.guvnor.vfs.Path}. The Path specifies the URI for the * resource to be edited. For {@code @WorkbenchScreen} 's the method should have * zero arguments. The method should return void. *

        */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface OnStartup { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/SetContent.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Use in method that sets a {@code @WorkbenchClientEditor} content. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface SetContent { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/lifecycle/Validate.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * * */ package org.uberfire.lifecycle; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Validate { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/BiParameterizedCommand.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp; import java.util.function.BiConsumer; /** * A command representing a future activity, with two parameters. Similar to {@link BiConsumer} * This was deliberately created in addition to the existing GWT Command to allow better * re-use of menu structures when a WorkbenchPart is embedded within Eclipse. * This is the two-arity specialization of {@link ParameterizedCommand} */ @FunctionalInterface public interface BiParameterizedCommand { void execute(T parameter1, U parameter2); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/Command.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp; import jsinterop.annotations.JsType; /** * A command representing a future activity. This was deliberately created in * addition to the existing GWT Command to allow better re-use of menu * structures when a WorkbenchPart is embedded within Eclipse. */ @JsType public interface Command { public void execute(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/Commands.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp; /** * A collection of generic operations that can be used anywhere a {@link Command} is called for. */ public class Commands { /** * Has no effect when executed. */ public static final Command DO_NOTHING = new Command() { @Override public void execute() { } }; } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/ParameterizedCommand.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp; /** * A command representing a future activity. This was deliberately created in * addition to the existing GWT Command to allow better re-use of menu * structures when a WorkbenchPart is embedded within Eclipse. * In case you need two parameters, see {@link BiParameterizedCommand}. */ public interface ParameterizedCommand { public void execute(T parameter); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/PlaceRequest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp; import java.util.Map; import java.util.Set; import jsinterop.annotations.JsType; import org.uberfire.backend.vfs.Path; import org.uberfire.mvp.impl.DefaultPlaceRequest; /** * A request to navigate to a particular UberFire Workbench Place (a WorkbenchPerspective, a WorkbenchScreen, or a * WorkbenchEditor). Can include optional state parameters that are made available to the requested place. *

        * Place requests can be serialized to and created from a valid URL fragment identifier (the string that goes after the * {@code #} in the browser's location bar). */ @JsType public interface PlaceRequest { public static final PlaceRequest NOWHERE = new DefaultPlaceRequest("NOWHERE"); String getIdentifier(); void setIdentifier(String identifier); String getFullIdentifier(); String getParameter(final String key, final String defaultValue); Set getParameterNames(); Map getParameters(); PlaceRequest addParameter(final String name, final String value); // TODO (UF-88) when PlaceRequest is an immutable value type, cloning will no longer be a sensible operation PlaceRequest clone(); /** * Indicates whether or not the Workbench framework should add a browser history item when navigating to this place. */ boolean isUpdateLocationBarAllowed(); void setUpdateLocationBar(boolean updateLocationBar); /** * Returns the path associated with this {@link PlaceRequest}. */ default Path getPath() { // TODO go over all UF public API and start using Optional return null; } /** * Invokes {@link #toString()} but exported to JavaScript so it can be invoked from different scripts. */ default String asString() { return this.toString(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/impl/ConditionalPlaceRequest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp.impl; import java.util.Map; import java.util.function.Predicate; import org.uberfire.mvp.PlaceRequest; public class ConditionalPlaceRequest extends DefaultPlaceRequest { private PlaceRequest orElsePlaceRequest; private Predicate predicate; public ConditionalPlaceRequest() { super(); } /** * A predicate applied to determine if this place request * should be used or the alternative specified by #orElse * @param identifier The place ID, or an empty string for the default place. */ public ConditionalPlaceRequest(final String identifier) { super(identifier); } /** * Creates a conditional place request for the given place ID with the given * state parameters for that place. * @param identifier The place ID, or an empty string for the default place. * @param parameters Place-specific parameters to pass to the place. Must not be null. */ public ConditionalPlaceRequest(final String identifier, final Map parameters) { super(identifier, parameters); } /** * Creates a place request for the given place ID with the given * state parameters for that place. * @param predicate Represents if default place request should be used. * If false, the place request will be orElsePlaceRequest. */ public ConditionalPlaceRequest when(Predicate predicate) { this.predicate = predicate; return this; } /** * Creates a place request for the given place ID with the given * state parameters for that place. * @param orElsePlaceRequest alternative place request. */ public PlaceRequest orElse(PlaceRequest orElsePlaceRequest) { this.orElsePlaceRequest = orElsePlaceRequest; return this; } /** * Return the place request of this conditional PlaceRequest. * If there is no predicate or orElsePlaceRequest returns the * default place request. */ public PlaceRequest resolveConditionalPlaceRequest() { if (invalidConditionalPlaceRequest()) { return this; } if (predicate == null || predicate.test(this)) { return this; } else { return resolve(); } } private boolean invalidConditionalPlaceRequest() { return predicate == null || orElsePlaceRequest == null; } protected PlaceRequest resolve() { if (orElsePlaceRequest instanceof ConditionalPlaceRequest) { return ((ConditionalPlaceRequest) orElsePlaceRequest).resolveConditionalPlaceRequest(); } else { return orElsePlaceRequest; } } @Override public String getIdentifier() { if (invalidConditionalPlaceRequest()) { return identifier; } if (predicate == null || predicate.test(this)) { return identifier; } else { return resolve().getIdentifier(); } } @Override public Map getParameters() { if (invalidConditionalPlaceRequest()) { return parameters; } if (predicate == null || predicate.test(this)) { return parameters; } else { return resolve().getParameters(); } } @Override public PlaceRequest clone() { return new ConditionalPlaceRequest(identifier, parameters).when(predicate).orElse(orElsePlaceRequest); } /** * A conditional place request should be resolved before being compared to another default place request. * @param o A default or conditional place request. * @return True if the resolved conditional place request equals to the default place request or resolved * conditional place request passed, and false otherwise. */ @Override public boolean equals(final Object o) { if (o == null) { return false; } if (!(o instanceof DefaultPlaceRequest)) { return false; } if (this == o) { return true; } PlaceRequest that = (PlaceRequest) o; if (o instanceof ConditionalPlaceRequest) { that = ((ConditionalPlaceRequest) o).resolveConditionalPlaceRequest(); } if (invalidConditionalPlaceRequest()) { return super.equals(that); } if (predicate == null || predicate.test(this)) { return super.equals(that); } else { return resolve().equals(that); } } @Override public int hashCode() { if (invalidConditionalPlaceRequest()) { return super.hashCode(); } if (predicate == null || predicate.test(this)) { return super.hashCode(); } else { return resolve().hashCode(); } } @Override public String toString() { if (predicate == null || predicate.test(this)) { return super.toString(); } else { return resolve().toString(); } } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/impl/DefaultPlaceRequest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp.impl; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.mvp.PlaceRequest; @Portable public class DefaultPlaceRequest implements PlaceRequest { protected final Map parameters = new HashMap(); private boolean updateLocationBar; protected String identifier; public DefaultPlaceRequest() { this(""); } /** * Creates a place request for the given place ID. * @param identifier The place ID, or an empty string for the default place. */ public DefaultPlaceRequest(final String identifier) { this(identifier, Collections.emptyMap(), true); } /** * Creates a place request for the given place ID with the given * state parameters for that place. * @param identifier The place ID, or an empty string for the default place. * @param parameters Place-specific parameters to pass to the place. Must not be null. */ public DefaultPlaceRequest(final String identifier, final Map parameters) { this(identifier, parameters, true); } /** * Creates a place request for the given place ID, with the given state parameters for that place, and the given * preference of whether or not the browser's location bar should be updated. * @param identifier The place ID, or an empty string for the default place. * @param parameters Place-specific parameters to pass to the place. Must not be null. * @param updateLocationBar If true, the browser's history will be updated with this place request. If false, the location bar * will not be modified as a result of this place request. */ public DefaultPlaceRequest(final String identifier, final Map parameters, final boolean updateLocationBar) { this.identifier = identifier; this.parameters.putAll(parameters); this.updateLocationBar = updateLocationBar; } /** * Creates a new place request from a string that encodes a place ID and optional parameters in standard URL query * syntax. *

        * For example, the following returns a PlaceRequest with identifier {@code MyPlaceID} and two parameters, * {@code param1} and {@code param2}. *

             *   DefaultPlaceRequest.parse("MyPlaceID?param1=val1&param2=val2")
             * 
        * @param partNameAndParams specification of the place ID and optional parameter map. Special characters in the identifier, key * name, or key value can be escaped using URL encoding: for '%' use '%25'; for '&' use '%26'; for * '=' use '%3d'; for '?' use '%3f'. * @return a new PlaceRequest configured according to the given string. */ public static PlaceRequest parse(CharSequence partNameAndParams) { Map parameters = new LinkedHashMap(); StringBuilder nextToken = new StringBuilder(50); String foundPartName = null; String key = null; for (int i = 0; i < partNameAndParams.length(); i++) { char ch = partNameAndParams.charAt(i); switch (ch) { case '%': StringBuilder hexVal = new StringBuilder(2); hexVal.append(partNameAndParams.charAt(i + 1)); hexVal.append(partNameAndParams.charAt(i + 2)); nextToken.append((char) Integer.parseInt(hexVal.toString(), 16)); i += 2; break; case '?': if (foundPartName == null) { foundPartName = nextToken.toString(); nextToken = new StringBuilder(50); } else { nextToken.append('?'); } break; case '=': if (foundPartName == null) { nextToken.append('='); } else { key = nextToken.toString(); nextToken = new StringBuilder(50); } break; case '&': parameters.put(key, nextToken.toString()); nextToken = new StringBuilder(50); key = null; break; default: nextToken.append(ch); } } if (foundPartName == null) { foundPartName = nextToken.toString(); } else if (key != null) { parameters.put(key, nextToken.toString()); } else if (nextToken.length() > 0) { parameters.put(nextToken.toString(), ""); } return new DefaultPlaceRequest(foundPartName, parameters); } @Override public String getIdentifier() { return identifier; } @Override public void setIdentifier(String identifier) { this.identifier = identifier; } @Override public String getFullIdentifier() { StringBuilder fullIdentifier = new StringBuilder(); fullIdentifier.append(this.getIdentifier()); if (!this.getParameterNames().isEmpty()) { fullIdentifier.append("?"); } for (String name : this.getParameterNames()) { fullIdentifier.append(name).append("=").append(this.getParameter(name, null).toString()); fullIdentifier.append("&"); } if (fullIdentifier.length() != 0 && fullIdentifier.lastIndexOf("&") + 1 == fullIdentifier.length()) { fullIdentifier.deleteCharAt(fullIdentifier.length() - 1); } return fullIdentifier.toString(); } //TODO: Throw ValueFormatException if conversion to a String is not possible @Override public String getParameter(final String key, final String defaultValue) { final String value = parameters.get(key); if (value == null) { return defaultValue; } return value; } @Override public Set getParameterNames() { return parameters.keySet(); } @Override public Map getParameters() { return parameters; } @Override public PlaceRequest addParameter(final String name, final String value) { this.parameters.put(name, value); return this; } @Override public PlaceRequest clone() { return new DefaultPlaceRequest(identifier, parameters); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (!(o instanceof DefaultPlaceRequest)) { return false; } final DefaultPlaceRequest that = (DefaultPlaceRequest) o; if (getIdentifier() != null ? !getIdentifier().equals(that.getIdentifier()) : that.getIdentifier() != null) { return false; } return !(getParameters() != null ? !getParameters().equals(that.getParameters()) : that.getParameters() != null); } @Override public boolean isUpdateLocationBarAllowed() { return updateLocationBar; } @Override public void setUpdateLocationBar(boolean updateLocationBar) { this.updateLocationBar = updateLocationBar; } @Override public int hashCode() { int result = identifier.hashCode(); result = ~~result; result = 31 * result + parameters.hashCode(); result = ~~result; return result; } @Override public String toString() { return "PlaceRequest[\"" + identifier + "\" " + parameters + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/impl/ExternalPathPlaceRequest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp.impl; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsType; import org.uberfire.backend.vfs.Path; /** * A {@link PathPlaceRequest} originating from an external script. */ @JsType public class ExternalPathPlaceRequest extends DefaultPlaceRequest { private Path path; public ExternalPathPlaceRequest(Path path) { this.path = path; } @JsIgnore public static ExternalPathPlaceRequest create(PathPlaceRequest request) { return new ExternalPathPlaceRequest(request.getPath().getOriginal()); } @Override public Path getPath() { return path; } @Override public String toString() { return "ExternalPathPlaceRequest [path=" + path + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/impl/ForcedPlaceRequest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp.impl; import java.util.Map; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ForcedPlaceRequest extends DefaultPlaceRequest { public ForcedPlaceRequest() { super(""); } public ForcedPlaceRequest(final String identifier) { super(identifier); } public ForcedPlaceRequest(final String identifier, final Map parameters) { super(identifier, parameters); } /** * Creates a place request for the given place ID, with the given state parameters for that place, and the given * preference of whether or not the browser's location bar should be updated. * @param identifier The place ID, or an empty string for the default place. * @param parameters Place-specific parameters to pass to the place. Must not be null. * @param updateLocationBar If true, the browser's history will be updated with this place request. If false, the location bar * will not be modified as a result of this place request. */ public ForcedPlaceRequest(final String identifier, final Map parameters, final boolean updateLocationBar) { super(identifier, parameters, updateLocationBar); } @Override public String toString() { return "ForcedPlaceRequest [identifier=" + identifier + ", parameters=" + parameters + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/mvp/impl/PathPlaceRequest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp.impl; import java.util.Map; import javax.annotation.PreDestroy; import org.jboss.errai.common.client.api.annotations.Portable; import org.jboss.errai.ioc.client.container.IOC; import org.uberfire.backend.vfs.IsVersioned; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.backend.vfs.Path; import org.uberfire.mvp.PlaceRequest; import static org.uberfire.util.URIUtil.encode; @Portable public class PathPlaceRequest extends DefaultPlaceRequest { public static String NULL = "[null]"; private ObservablePath path; public PathPlaceRequest() { } public PathPlaceRequest(final Path path) { super(NULL); this.path = createObservablePath(path); } public PathPlaceRequest(final Path path, final Map parameters) { this(path); this.parameters.putAll(parameters); } public PathPlaceRequest(final Path path, final String id) { super(id); this.path = createObservablePath(path); } public PathPlaceRequest(final Path path, final String id, final Map parameters) { this(path, id); this.parameters.putAll(parameters); } protected ObservablePath createObservablePath(Path path) { return IOC.getBeanManager().lookupBean(ObservablePath.class).getInstance().wrap(path); } @Override public ObservablePath getPath() { return path; } @Override public String getFullIdentifier() { final StringBuilder fullIdentifier = new StringBuilder(); if (getIdentifier() != null) { fullIdentifier.append(this.getIdentifier()); } else { fullIdentifier.append(NULL); } fullIdentifier.append("?").append("path_uri").append("=").append(encode(path.toURI())).append("&") .append("file_name").append("=").append(encode(path.getFileName())).append("&"); if (path instanceof IsVersioned) { fullIdentifier.append("has_version_support").append("=").append(((IsVersioned) path).hasVersionSupport()).append("&"); } for (String name : this.getParameterNames()) { fullIdentifier.append(name).append("=").append(this.getParameter(name, null)); fullIdentifier.append("&"); } if (fullIdentifier.length() != 0 && fullIdentifier.lastIndexOf("&") + 1 == fullIdentifier.length()) { fullIdentifier.deleteCharAt(fullIdentifier.length() - 1); } return fullIdentifier.toString(); } @Override public PlaceRequest clone() { return new PathPlaceRequest(path, identifier, parameters); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (!(o instanceof PathPlaceRequest)) { return false; } if (!super.equals(o)) { return false; } final PathPlaceRequest that = (PathPlaceRequest) o; return !(getPath() != null ? !getPath().equals(that.getPath()) : that.getPath() != null); } @Override public int hashCode() { int result = super.hashCode(); result = ~~result; result = 31 * result + (getPath() != null ? getPath().hashCode() : 0); result = ~~result; return result; } @Override public String toString() { return "PathPlaceRequest[\"" + identifier + "\" " + parameters + "\" " + path + "]"; } @PreDestroy public void preDestroy() { getPath().dispose(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/paging/AbstractPageRow.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.paging; /** * A single row of a paged data */ public abstract class AbstractPageRow implements Comparable { public int compareTo(AbstractPageRow o) { return 0; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/paging/AbstractPathPageRow.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.paging; import org.uberfire.backend.vfs.Path; /** * A single row of a paged data */ public abstract class AbstractPathPageRow extends AbstractPageRow { private Path path; public AbstractPathPageRow() { super(); } public AbstractPathPageRow(final Path path) { super(); this.path = path; } public int compareTo(final AbstractPathPageRow other) { return path.compareTo(other.path); } public Path getPath() { return path; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/paging/PageRequest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.paging; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; /** * A generic request for paged data * @see PageResponse */ @Portable public class PageRequest { protected int startRowIndex = 0; protected Integer pageSize = null; // null returns all pages public PageRequest(@MapsTo("startRowIndex") int startRowIndex, @MapsTo("pageSize") Integer pageSize) { this.startRowIndex = startRowIndex; this.pageSize = pageSize; } // ************************************************************************ // Getters and setters // ************************************************************************ public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public int getStartRowIndex() { return startRowIndex; } public void setStartRowIndex(int startRowIndex) { this.startRowIndex = startRowIndex; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/paging/PageResponse.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.paging; import java.util.List; import org.jboss.errai.common.client.api.annotations.Portable; /** * A Page of data for display in a PagedTable */ @Portable public class PageResponse { // Is totalRowSize exact or undetermined private boolean totalRowSizeExact; // Total number of rows in whole data-set (not just page) private int totalRowSize; private int startRowIndex; private List pageRowList; private boolean lastPage; // ************************************************************************ // Getters and setters // ************************************************************************ public List getPageRowList() { return pageRowList; } public void setPageRowList(List assetPageRowList) { this.pageRowList = assetPageRowList; } public int getStartRowIndex() { return startRowIndex; } public void setStartRowIndex(int startRowIndex) { this.startRowIndex = startRowIndex; } public int getTotalRowSize() { return totalRowSize; } public void setTotalRowSize(int totalRowSize) { this.totalRowSize = totalRowSize; } public boolean isFirstPage() { return startRowIndex == 0L; } public boolean isLastPage() { return lastPage; } public void setLastPage(boolean lastPage) { this.lastPage = lastPage; } public boolean isTotalRowSizeExact() { return totalRowSizeExact; } public void setTotalRowSizeExact(boolean totalRowSizeExact) { this.totalRowSizeExact = totalRowSizeExact; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/plugin/PluginUtil.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.plugin; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsType; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * Utilities for working with external (GWT-compiled) plugins. */ public class PluginUtil { private PluginUtil() { } /** * {@link List} is a {@link JsType} but {@link Collection#iterator()} is * {@link JsIgnore}d and therefore not exported to JavaScript. *

        * This method takes a list and converts it to a new list so it can be * iterated over in the current script (e.g. using enhanced for loops), even * if the instance was provided by an external (GWT-compiled) script. * * @param externalList A list, possibly provided by an external script. Must not be null. * @return an immutable list containing the original elements of the * provided list */ public static List ensureIterable(List externalList) { checkNotNull("externalList", externalList); // toArray(T[]) is @JsIgnored @SuppressWarnings("unchecked") final List tmp = (List) Arrays.asList(externalList.toArray()); return Collections.unmodifiableList(tmp); } /** * {@link Set} is a {@link JsType} but {@link Collection#iterator()} is * {@link JsIgnore}d and therefore not exported to JavaScript. *

        * This method takes a set and converts it to a new set so it can be * iterated over in the current script (e.g. using enhanced for loops), even * if the instance was provided by an external (GWT-compiled) script. * * @param externalSet A set, possibly provided by an external script. Must not be null. * @return an immutable set containing the original elements of the provided * set */ public static Set ensureIterable(Set externalSet) { checkNotNull("externalSet", externalSet); // toArray(T[]) is @JsIgnored @SuppressWarnings("unchecked") final List tmp = (List) Arrays.asList(externalSet.toArray()); return Collections.unmodifiableSet(new HashSet(tmp)); } /** * {@link Integer} is not a {@link JsType} and can't be shared across * scripts. *

        * This method converts a regular int to an {@link Integer} using -1 as a * placeholder for null. * * @param value * @return boxed {@link Integer}, null if provided value is -1. */ public static Integer toInteger(int value) { return (value != -1) ? value : null; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/rpc/SessionInfo.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.rpc; import org.jboss.errai.security.shared.api.identity.User; public interface SessionInfo { String getId(); User getIdentity(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/rpc/impl/SessionInfoImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.rpc.impl; import javax.enterprise.inject.Alternative; import org.jboss.errai.security.shared.api.identity.User; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotEmpty; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; @Alternative public class SessionInfoImpl implements SessionInfo { private String id; private User identity; public SessionInfoImpl() { } public SessionInfoImpl(final String id, final User identity) { this.id = checkNotEmpty("id", id); this.identity = checkNotNull("identity", identity); } public SessionInfoImpl(final User identity) { this.identity = checkNotNull("identity", identity); } @Override public String getId() { return id; } public void setId(final String id) { this.id = id; } @Override public User getIdentity() { return identity; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof SessionInfo)) { return false; } SessionInfo that = (SessionInfo) o; if (!getId().equals(that.getId())) { return false; } return getIdentity().getIdentifier().equals(that.getIdentity().getIdentifier()); } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + identity.getIdentifier().hashCode(); return result; } @Override public String toString() { return "SessionInfoImpl [id=" + id + ", identity=" + identity + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/rpc/impl/SessionInfoMarshalller.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.rpc.impl; import org.jboss.errai.common.client.protocols.SerializationParts; import org.jboss.errai.marshalling.client.api.MarshallingSession; import org.jboss.errai.marshalling.client.api.annotations.ClientMarshaller; import org.jboss.errai.marshalling.client.api.annotations.ServerMarshaller; import org.jboss.errai.marshalling.client.api.json.EJValue; import org.jboss.errai.marshalling.client.marshallers.AbstractNullableMarshaller; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.uberfire.rpc.SessionInfo; @ClientMarshaller(SessionInfo.class) @ServerMarshaller(SessionInfo.class) public class SessionInfoMarshalller extends AbstractNullableMarshaller { @Override public SessionInfo doNotNullDemarshall(final EJValue ejValue, final MarshallingSession marshallingSession) { return new SessionInfoImpl(ejValue.isObject().get("id").isString().stringValue(), new UserImpl(ejValue.isObject().get("identityId").isString().stringValue())); } @Override public String doNotNullMarshall(final SessionInfo sessionInfo, final MarshallingSession marshallingSession) { return "{\"" + SerializationParts.ENCODED_TYPE + "\":\"" + SessionInfo.class.getName() + "\"," + "\"" + SerializationParts.OBJECT_ID + "\":\"" + sessionInfo.hashCode() + "\"," + "\"" + "id" + "\":\"" + sessionInfo.getId() + "\"," + "\"" + "identityId" + "\":\"" + sessionInfo.getIdentity().getIdentifier() + "\"}"; } @Override public SessionInfo[] getEmptyArray() { return new SessionInfo[0]; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/Contributor.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import java.util.Comparator; import java.util.Objects; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class Contributor { private String username; private ContributorType type; public Contributor() { } public Contributor(@MapsTo("username") final String username, @MapsTo("type") final ContributorType type) { this.username = username; this.type = type; } public String getUsername() { return username; } public ContributorType getType() { return type; } public void setType(ContributorType type) { this.type = type; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Contributor)) { return false; } Contributor that = (Contributor) o; return Objects.equals(username, that.username) && type == that.type; } @Override public int hashCode() { int result = username != null ? username.hashCode() : 0; result = ~~result; result = 31 * result + (type != null ? type.hashCode() : 0); result = ~~result; return result; } public static final Comparator COMPARATOR = (o1, o2) -> { if (o1.getType().equals(o2.getType())) { return o1.getUsername().toUpperCase().compareTo(o2.getUsername().toUpperCase()); } else { if (ContributorType.PRIORITY_ORDER.indexOf(o1.getType()) < ContributorType.PRIORITY_ORDER.indexOf(o2.getType())) { return -1; } else { return 1; } } }; } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/ContributorResource.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import java.util.Collection; public interface ContributorResource { Collection getContributors(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/ContributorType.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import java.util.Arrays; import java.util.List; public enum ContributorType { OWNER, ADMIN, CONTRIBUTOR; public static List PRIORITY_ORDER = Arrays.asList(OWNER, ADMIN, CONTRIBUTOR); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/Resource.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import java.util.Collections; import java.util.List; import jsinterop.annotations.JsType; /** * A generic interface for modelling resources, like UI assets: perspectives, screens or * editors or even backend resources like repositories, projects, data objects, etc... */ @JsType public interface Resource { /** * An identifier that is unique among all the resources of the same type * (see {@link Resource#getResourceType()}). */ String getIdentifier(); /** * Get the resource type classifier */ default ResourceType getResourceType() { return ResourceType.UNKNOWN; } /** * A list of dependent resources. *

        *

        * The dependency list is used for instance to determine if a user can * access a given resource. Should the access to all its dependencies is * denied, it is denied for this instance as well. *

        * @return A list of resources, never null. */ default List getDependencies() { return Collections.emptyList(); } /** * Check if this resource is of the provided type. The type name is used * here so this method can be used on instances from external (GWT-compiled) * scripts (enum equals and instanceof doesn't work across script boundaries). * @param typeName the resource type's name * @return true if the resource has the provided type, otherwise false. */ default boolean isType(String typeName) { return getResourceType().getName().equalsIgnoreCase(typeName); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/ResourceAction.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import jsinterop.annotations.JsType; /** * An action represents something that someone can do over a resource. * Can vary from a complex UI feature to a low-level action. *

        *

        This interface is intended to be extended by the different {@link Resource} types. It is up to every * resource type implementation to define the list of available actions.

        */ @JsType public interface ResourceAction { /** * The read action is common to all resource types. *

        Basically, it refers to the ability to access (view, read, ...) a resource

        */ ResourceAction READ = () -> "read"; /** * An string representation of the action. */ String getName(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/ResourceRef.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import java.util.ArrayList; import java.util.List; /** * A resource reference. Useful when a link to the real Resource object is not available. */ public class ResourceRef implements Resource { private String identifier; private ResourceType type; private List dependencies; public ResourceRef(String identifier, ResourceType type) { this(identifier, type, null); } public ResourceRef(String identifier, ResourceType type, List dependencies) { this.identifier = identifier; this.type = type; this.dependencies = new ArrayList<>(); this.setDependencies(dependencies); } @Override public String getIdentifier() { return identifier; } public void setIdentifier(String identifier) { this.identifier = identifier; } @Override public ResourceType getResourceType() { return type; } public void setResourceType(ResourceType type) { this.type = type; } @Override public List getDependencies() { return dependencies; } public void setDependencies(List deps) { this.dependencies.clear(); if (deps != null) { this.dependencies.addAll(deps); } } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/ResourceType.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import jsinterop.annotations.JsType; /** * Type interface for {@link Resource} instances */ @JsType public interface ResourceType { /** * Resource type declaration for those resources who do not declare a type. */ ResourceType UNKNOWN = () -> "unknown"; /** * An string representation of this type instance */ String getName(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/WorkbenchUserManager.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import org.jboss.errai.security.shared.api.identity.User; /** * Basic API to interact with the user system */ public interface WorkbenchUserManager { /** * Returns the platform {@link User} identified by a given identifier * @param identifier The {@link User} identifier * @return The correct {@link User} if exists or null. */ User getUser(String identifier); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/authz/ResourceActionRef.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security.authz; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsType; import org.uberfire.security.Resource; import org.uberfire.security.ResourceAction; import org.uberfire.security.ResourceRef; import org.uberfire.security.ResourceType; /** * A instance holding a resource reference plus an action */ @JsType public class ResourceActionRef { private Resource resource = null; private ResourceAction action = null; @JsIgnore public ResourceActionRef(Resource resource) { this(resource, ResourceAction.READ); } @JsIgnore public ResourceActionRef(Resource resource, ResourceAction action) { this.resource = resource; this.action = action; } @JsIgnore public ResourceActionRef(ResourceType type, ResourceAction action) { this.resource = new ResourceRef(null, type); this.action = action; } @JsIgnore public ResourceActionRef(ResourceType type, Resource resource, ResourceAction action) { this.resource = resource != null ? resource : new ResourceRef(null, type); this.action = action; } public Resource getResource() { return resource; } public ResourceAction getAction() { return action; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/authz/RuntimeContentResource.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security.authz; public interface RuntimeContentResource extends RuntimeResource { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/authz/RuntimeFeatureResource.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security.authz; public interface RuntimeFeatureResource extends RuntimeResource { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/authz/RuntimeResource.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security.authz; import jsinterop.annotations.JsType; import org.uberfire.security.Resource; @JsType public interface RuntimeResource extends Resource { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/security/authz/VotingStrategy.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security.authz; /** * A voting strategy establishes what to do when different authorization results are produced during the * evaluation of a permission over a protected resource. This is the case when the user is assigned with * more than one user and/or group. In such case, different strategies can be applied in order to resolve * what is the winning result. */ public enum VotingStrategy { /** * It is the most lenient strategy. Only a single positive vote is required. */ AFFIRMATIVE, /** * It is based on general agreement. It requires a majority of positive votes. */ CONSENSUS, /** * It is the less lenient strategy. It requires a 100% of positive votes. */ UNANIMOUS, /** * It is based on role/group priorities. The highest priority result wins. */ PRIORITY; } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/spaces/Space.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.spaces; import java.util.Objects; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class Space { private String name; public Space() { //cdi } public Space(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return name; } @Override public boolean equals(Object obj) { return obj instanceof Space && Objects.equals(name, ((Space) obj).getName()); } @Override public int hashCode() { return Objects.hashCode(name); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/spaces/SpacesAPI.java ================================================ package org.uberfire.spaces; import java.net.URI; import java.util.Optional; import com.google.gwt.core.shared.GwtIncompatible; public interface SpacesAPI { String DEFAULT_SPACE_NAME = "system"; Space DEFAULT_SPACE = new Space(DEFAULT_SPACE_NAME); String DASHBUILDER_SPACE_NAME = "dashbuilder"; Space DASHBUILDER_SPACE = new Space(DASHBUILDER_SPACE_NAME); String CONFIG_FOLDER_NAME = ".config"; String CONFIG_REPOSITORY_NAME = "config"; static String resolveSpacePath(final Scheme scheme, final String spaceName) { return scheme + "://" + spaceName + "/"; } static String resolveFileSystemPath(final Scheme scheme, final Space space, final String fsName) { return scheme + "://" + space.getName() + "/" + fsName; } static String resolveConfigFileSystemPath(final Scheme scheme, final String spaceName) { return resolveSpacePath(scheme, spaceName) + CONFIG_FOLDER_NAME + "/" + CONFIG_REPOSITORY_NAME; } @GwtIncompatible public URI resolveFileSystemURI(Scheme scheme, Space space, String fsName); static String sanitizeFileSystemName(final String fileSystemName) { // Only [A-Za-z0-9_\-.] are valid so strip everything else out return fileSystemName != null ? fileSystemName.replaceAll("[^A-Za-z0-9_\\-.]", "") : fileSystemName; } Space getSpace(String name); default Space getDefaultSpace() { return DEFAULT_SPACE; } Optional resolveSpace(String uri); enum Scheme { DEFAULT("default"), GIT("git"), FILE("file"); private final String name; Scheme(String name) { this.name = name; } @Override public String toString() { return name; } } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/util/URIUtil.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.util; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; /** * Utilities for working with URIs that functions the same in both client and server code. *

        * Implementation note: there is a separate GWT super-source implementation of this class for client-side use. If * modifying this class, be sure to go modify that one too. */ public final class URIUtil { public static String encode(final String content) { try { return URLEncoder.encode(content, "UTF-8"); } catch (UnsupportedEncodingException e) { } return null; } public static String decode(final String content) { try { return URLDecoder.decode(content, "UTF-8"); } catch (UnsupportedEncodingException e) { } return null; } public static String encodeQueryString(final String content) { return encode(content); } public static boolean isValid(final String uri) { try { URI.create(uri); return true; } catch (final Exception ignored) { } return false; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/annotations/VisibleAsset.java ================================================ package org.uberfire.workbench.annotations; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * This annotation represents a Resource that should be visible to end users. Any other resource not annotated with it * should not be shown. In case you need to inject a Resource that contains @VisibleAsset in an object that doesn't need * this concept you can add @Default qualifier to it. */ @Documented @Qualifier @Retention(RUNTIME) @Target({TYPE, PARAMETER, FIELD, METHOD}) public @interface VisibleAsset { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/category/Category.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workbench.category; public abstract class Category { public abstract String getName(); @Override public boolean equals(Object category) { if (category instanceof Category) { Category cat = (Category) category; return this.getName() == null ? cat.getName() == null : this.getName().equalsIgnoreCase(cat.getName()); } else { return false; } } @Override public int hashCode() { return getName() == null ? 0 : getName().toUpperCase().hashCode(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/category/Others.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workbench.category; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class Others extends Category { private static final String OTHERS = "OTHERS"; @Override public String getName() { return OTHERS; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/category/Undefined.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workbench.category; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class Undefined extends Category { private static final String UNDEFINED = "UNDEFINED"; @Override public String getName() { return UNDEFINED; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/diff/DiffMode.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.diff; public enum DiffMode { TEXTUAL, VISUAL } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/NotificationEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.mvp.PlaceRequest; /** * An event to show a notification pop-up in the Workbench */ @Portable public class NotificationEvent implements UberFireEvent { private String notification; private NotificationType type; private boolean isSingleton; private PlaceRequest placeRequest; private Integer initialTopOffset; private boolean autoHide = true; private String navigationText; private PlaceRequest navigationPlace; public NotificationEvent() { } public NotificationEvent(final String notification) { this(notification, NotificationType.DEFAULT, false, null); } public NotificationEvent(final String notification, final NotificationType type) { this(notification, type, false, null); } public NotificationEvent(final String notification, final boolean isSingleton) { this(notification, NotificationType.DEFAULT, isSingleton, null); } public NotificationEvent(final String notification, final NotificationType type, final boolean isSingleton) { this(notification, NotificationType.DEFAULT, isSingleton, null); } public NotificationEvent(final String notification, final NotificationType type, final boolean isSingleton, final PlaceRequest placeRequest) { this(notification, type, isSingleton, placeRequest, null); } public NotificationEvent(final String notification, final NotificationType type, final boolean isSingleton, final PlaceRequest placeRequest, final Integer initialTopOffset) { this.notification = notification; this.type = type; this.isSingleton = isSingleton; this.placeRequest = placeRequest; this.initialTopOffset = initialTopOffset; } public String getNotification() { return this.notification; } public NotificationType getType() { return type; } public boolean isSingleton() { return isSingleton; } public PlaceRequest getPlaceRequest() { return placeRequest; } public Integer getInitialTopOffset() { return initialTopOffset; } public NotificationEvent setAutoHide(final boolean autoHide) { this.autoHide = autoHide; return this; } public boolean autoHide() { return autoHide; } public NotificationEvent setNavigation(final String text, final PlaceRequest place) { this.navigationText = text; this.navigationPlace = place; return this; } public boolean hasNavigation() { return navigationText != null && navigationPlace != null; } public String getNavigationText() { return navigationText; } public PlaceRequest getNavigationPlace() { return navigationPlace; } @Override public String toString() { return "NotificationEvent [notification=" + notification + ", type=" + type + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (isSingleton ? 1231 : 1237); result = prime * result + ((notification == null) ? 0 : notification.hashCode()); result = prime * result + ((placeRequest == null) ? 0 : placeRequest.hashCode()); result = prime * result + ((initialTopOffset == null) ? 0 : initialTopOffset.hashCode()); result = prime * result + ((type == null) ? 0 : type.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; } NotificationEvent other = (NotificationEvent) obj; if (isSingleton != other.isSingleton) { return false; } if (notification == null) { if (other.notification != null) { return false; } } else if (!notification.equals(other.notification)) { return false; } if (placeRequest == null) { if (other.placeRequest != null) { return false; } } else if (!placeRequest.equals(other.placeRequest)) { return false; } if (initialTopOffset == null) { if (other.initialTopOffset != null) { return false; } } else if (!initialTopOffset.equals(other.initialTopOffset)) { return false; } if (type != other.type) { return false; } return true; } public static enum NotificationType { DEFAULT, ERROR, SUCCESS, INFO, WARNING } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/PluginAddedEvent.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class PluginAddedEvent extends PluginEvent { public PluginAddedEvent(@MapsTo("name") String name) { super(name); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/PluginEvent.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; public abstract class PluginEvent { private String name; public PluginEvent(String name) { this.name = name; } public String getName() { return name; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/PluginReloadedEvent.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class PluginReloadedEvent { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/PluginUpdatedEvent.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class PluginUpdatedEvent extends PluginEvent { public PluginUpdatedEvent(@MapsTo("name") String name) { super(name); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceAdded.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ResourceAdded implements UberFireEvent, ResourceChange { private String message; public ResourceAdded(@MapsTo("message") final String message) { this.message = message; } @Override public ResourceChangeType getType() { return ResourceChangeType.ADD; } @Override public String getMessage() { return message; } @Override public String toString() { return "ResourceAdded{" + "message='" + message + '\'' + '}'; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceAddedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * An Event indicating a Resource has been added */ @Portable public class ResourceAddedEvent extends ResourceAdded implements ResourceEvent { private Path path; private SessionInfo sessionInfo; public ResourceAddedEvent(@MapsTo("path") final Path path, @MapsTo("message") final String message, @MapsTo("sessionInfo") final SessionInfo sessionInfo) { super(message); this.path = checkNotNull("path", path); this.sessionInfo = checkNotNull("sessionInfo", sessionInfo); } @Override public Path getPath() { return this.path; } public SessionInfo getSessionInfo() { return sessionInfo; } @Override public String toString() { return "ResourceAddedEvent{" + "path=" + path + ", message=" + getMessage() + ", sessionInfo=" + sessionInfo + '}'; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceBatchChangesEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * An Event indicating a various changes to various Resources */ @Portable public class ResourceBatchChangesEvent implements UberFireEvent { private String message; private SessionInfo sessionInfo; private Map> batch = new HashMap>(); public ResourceBatchChangesEvent(@MapsTo("batch") final Map> batch, @MapsTo("message") final String message, @MapsTo("sessionInfo") final SessionInfo sessionInfo) { checkNotNull("batch", batch); this.batch.putAll(batch); this.message = message; this.sessionInfo = checkNotNull("sessionInfo", sessionInfo); } public Map> getBatch() { return this.batch; } public boolean containPath(final Path path) { return batch.containsKey(path); } public Collection getAffectedPaths() { return batch.keySet(); } public Collection getChanges(final Path path) { return batch.get(path); } public SessionInfo getSessionInfo() { return sessionInfo; } public String getMessage() { return message; } @Override public String toString() { return "ResourceBatchChangesEvent [sessionInfo=" + sessionInfo + ", batch=" + batch + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceChange.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; public interface ResourceChange { public ResourceChangeType getType(); public String getMessage(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceChangeType.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.Portable; /** * Types of change that can happen to a Resource */ @Portable public enum ResourceChangeType { ADD, DELETE, UPDATE, COPY, RENAME } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceCopied.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; @Portable public class ResourceCopied implements UberFireEvent, ResourceChange { private Path destinationPath; private String message; public ResourceCopied(@MapsTo("destinationPath") final Path destinationPath, @MapsTo("message") final String message) { this.destinationPath = checkNotNull("destinationPath", destinationPath); this.message = message; } @Override public ResourceChangeType getType() { return ResourceChangeType.COPY; } @Override public String getMessage() { return message; } public Path getDestinationPath() { return this.destinationPath; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceCopiedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * An Event indicating a Resource has been copied */ @Portable public class ResourceCopiedEvent extends ResourceCopied implements ResourceEvent { private Path sourcePath; private SessionInfo sessionInfo; public ResourceCopiedEvent(@MapsTo("sourcePath") final Path sourcePath, @MapsTo("destinationPath") final Path destinationPath, @MapsTo("message") final String message, @MapsTo("sessionInfo") final SessionInfo sessionInfo) { super(destinationPath, message); this.sourcePath = checkNotNull("sourcePath", sourcePath); this.sessionInfo = checkNotNull("sessionInfo", sessionInfo); } public SessionInfo getSessionInfo() { return sessionInfo; } @Override public Path getPath() { return this.sourcePath; } @Override public String toString() { return "ResourceCopiedEvent{" + "sourcePath=" + sourcePath + ", destinationPath=" + getDestinationPath() + ", message=" + getMessage() + ", sessionInfo=" + sessionInfo + '}'; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceDeleted.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ResourceDeleted implements UberFireEvent, ResourceChange { private String message; public ResourceDeleted(@MapsTo("message") final String message) { this.message = message; } @Override public ResourceChangeType getType() { return ResourceChangeType.DELETE; } @Override public String getMessage() { return message; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceDeletedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * An Event indicating a Resource has been deleted */ @Portable public class ResourceDeletedEvent extends ResourceDeleted implements ResourceEvent { private Path path; private SessionInfo sessionInfo; public ResourceDeletedEvent(@MapsTo("path") final Path path, @MapsTo("message") final String message, @MapsTo("sessionInfo") final SessionInfo sessionInfo) { super(message); this.path = checkNotNull("path", path); this.sessionInfo = checkNotNull("executedBy", sessionInfo); } @Override public Path getPath() { return this.path; } public SessionInfo getSessionInfo() { return sessionInfo; } @Override public String toString() { return "ResourceDeletedEvent{" + "path=" + path + ", message=" + getMessage() + ", sessionInfo=" + sessionInfo + '}'; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.uberfire.backend.vfs.Path; public interface ResourceEvent extends ResourceChange { public Path getPath(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceOpenedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * An Event indicating a Resource has been opened */ @Portable public class ResourceOpenedEvent implements UberFireEvent { private Path path; private SessionInfo sessionInfo; public ResourceOpenedEvent(@MapsTo("path") final Path path, @MapsTo("sessionInfo") final SessionInfo sessionInfo) { this.path = checkNotNull("path", path); this.sessionInfo = checkNotNull("sessionInfo", sessionInfo); } public Path getPath() { return this.path; } public SessionInfo getSessionInfo() { return sessionInfo; } @Override public String toString() { return "ResourceOpenedEvent [path=" + path + ", sessionInfo=" + sessionInfo + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceRenamed.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; @Portable public class ResourceRenamed implements UberFireEvent, ResourceChange { private Path destinationPath; private String message; public ResourceRenamed(@MapsTo("destinationPath") final Path destinationPath, @MapsTo("message") final String message) { this.destinationPath = checkNotNull("destinationPath", destinationPath); this.message = message; } @Override public ResourceChangeType getType() { return ResourceChangeType.RENAME; } @Override public String getMessage() { return message; } public Path getDestinationPath() { return this.destinationPath; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceRenamedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * An Event indicating a Resource has been renamed */ @Portable public class ResourceRenamedEvent extends ResourceRenamed implements ResourceEvent { private Path sourcePath; private SessionInfo sessionInfo; public ResourceRenamedEvent(@MapsTo("sourcePath") final Path sourcePath, @MapsTo("destinationPath") final Path destinationPath, @MapsTo("message") final String message, @MapsTo("sessionInfo") final SessionInfo sessionInfo) { super(destinationPath, message); this.sourcePath = checkNotNull("sourcePath", sourcePath); this.sessionInfo = checkNotNull("sessionInfo", sessionInfo); } public SessionInfo getSessionInfo() { return sessionInfo; } @Override public Path getPath() { return this.sourcePath; } @Override public String toString() { return "ResourceRenamedEvent [sourcePath=" + sourcePath + ", sessionInfo=" + sessionInfo + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceUpdated.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class ResourceUpdated implements UberFireEvent, ResourceChange { private String message; public ResourceUpdated(@MapsTo("message") final String message) { this.message = message; } @Override public ResourceChangeType getType() { return ResourceChangeType.UPDATE; } @Override public String getMessage() { return message; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/ResourceUpdatedEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.Path; import org.uberfire.rpc.SessionInfo; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * An Event indicating a Resource has been updated */ @Portable public class ResourceUpdatedEvent extends ResourceUpdated implements ResourceEvent { private Path path; private SessionInfo sessionInfo; public ResourceUpdatedEvent(@MapsTo("path") final Path path, @MapsTo("message") final String message, @MapsTo("sessionInfo") final SessionInfo sessionInfo) { super(message); this.path = checkNotNull("path", path); this.sessionInfo = checkNotNull("sessionInfo", sessionInfo); } @Override public Path getPath() { return this.path; } public SessionInfo getSessionInfo() { return sessionInfo; } @Override public String toString() { return "ResourceUpdatedEvent [path=" + path + ", sessionInfo=" + sessionInfo + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/UberFireEvent.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; /** * Marker interface that serves to group all UberFire framework events * together. For example, this allows you to create a single CDI observer that * observes all framework events. */ public interface UberFireEvent { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/events/UberfireJSAPIReadyEvent.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.events; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class UberfireJSAPIReadyEvent { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/ActivityResourceType.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import jsinterop.annotations.JsType; import org.uberfire.security.ResourceType; /** * An extension of the {@link ResourceType} interface holding an enumeration with the * different activity types subject to authorization management control. */ @JsType public enum ActivityResourceType implements ResourceType { PERSPECTIVE, SCREEN, EDITOR, CLIENT_EDITOR, POPUP, SPLASH; @Override public String getName() { return this.toString().toLowerCase(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/AppFormerActivities.java ================================================ /* * * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workbench.model; import java.util.List; /** * Defines the list of entities used in the workbench * If no backend implementation for this class exists, a default one will be provided. */ public interface AppFormerActivities { /** * Returns list of all the editors IDs used in the workbench. * * @return List of all editors. */ List getAllEditorIds(); /** * Returns list of all the perspectives used in the workbench. * * @return List of all perspectives. */ List getAllPerpectivesIds(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/AppFormerActivitiesProducer.java ================================================ /* * * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workbench.model; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Instance; import javax.enterprise.inject.Produces; import javax.inject.Inject; import org.uberfire.annotations.Customizable; import org.uberfire.annotations.FallbackImplementation; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; @Startup(value = StartupType.BOOTSTRAP, priority = -1) @ApplicationScoped public class AppFormerActivitiesProducer { @Inject private Instance appFormerActivities; @Inject @FallbackImplementation private AppFormerActivities defaultAppFormerActivities; @Produces @Customizable public AppFormerActivities appFormerActivitiesProducer() { if (this.appFormerActivities.isUnsatisfied()) { return defaultAppFormerActivities; } return this.appFormerActivities.get(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/CompassPosition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import jsinterop.annotations.JsType; import org.jboss.errai.common.client.api.annotations.Portable; /** * Positions to which a WorkbenchPanel can be added to the Workbench */ @Portable @JsType public enum CompassPosition implements Position { NONE, //Don't add anywhere NORTH, //North internal edge of a Parent panel SOUTH, //South internal edge of a Parent panel EAST, //East internal edge of a Parent panel WEST, //West internal edge of a Parent panel SELF, //Add to the Parent panel ROOT, //Add to the Workbench root CENTER; // Add to the panel center @Override public String getName() { return name(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import jsinterop.annotations.JsType; import org.uberfire.mvp.PlaceRequest; /** * A Part in the Workbench. Parts are added to Panels. */ @JsType public interface ContextDefinition { /** * Get the PlaceRequest that this Part will contain. * @return the place */ public PlaceRequest getPlace(); /** * Set the PlaceRequest that this Part will contain. * @param place the place to set */ public void setPlace(final PlaceRequest place); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/ContextDisplayMode.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import jsinterop.annotations.JsType; import org.jboss.errai.common.client.api.annotations.Portable; @JsType @Portable public enum ContextDisplayMode { SHOW, HIDE } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/CustomPanelDefinition.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import java.util.Optional; import com.google.gwt.user.client.ui.HasWidgets; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsType; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.mvp.PlaceRequest; /** * A custom {@link PanelDefinition} that is associated with a HasWidgets * or HTMLElement container. See {@link PlaceManager#goTo(PlaceRequest, HasWidgets)} * and {@link PlaceManager#goTo(PlaceRequest, HTMLElement)} */ @JsType public interface CustomPanelDefinition extends PanelDefinition { /** * Returns the HTMLElement container associated with the custom panel. */ @JsIgnore Optional getHtmlElementContainer(); /** * Returns the HasWidgets container associated with the custom panel. */ @JsIgnore Optional getHasWidgetsContainer(); /** * Returns the elemental2.dom.HTMLElement container associated with the custom panel. */ @JsIgnore Optional getElemental2HtmlElementContainer(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/DefaultAppFormerActivities.java ================================================ /* * * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workbench.model; import java.util.Arrays; import java.util.List; import javax.enterprise.context.ApplicationScoped; import org.uberfire.annotations.FallbackImplementation; /** * Default implementation for {@link AppFormerActivities}. To override it, just provide a default * CDI bean that implements {@link AppFormerActivities}. */ @ApplicationScoped @FallbackImplementation public class DefaultAppFormerActivities implements AppFormerActivities { protected DefaultAppFormerActivities() { } @Override public List getAllEditorIds() { return Arrays.asList(); } @Override public List getAllPerpectivesIds() { return Arrays.asList(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/NamedPosition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * Represents the position of a child panel by name. For example, within a templated perspective, panels are positioned * by ErraiUI DataField names. *

        * Positions that refer to the same field name compare equal to each other. *

        * Instances of this class are immutable. */ @Portable public class NamedPosition implements Position { /** * Represents the root panel of any templated perspective. */ public static final NamedPosition ROOT = new NamedPosition(""); private final String fieldName; /** * Creates a new position representing the ErraiUI {@code @DataField} with the given name. * If you are trying to refer to the root of the template itself, use {@link #ROOT}. * * @param fieldName the name of the data field. Must be non-null. */ public NamedPosition(@MapsTo("fieldName") String fieldName) { this.fieldName = checkNotNull("fieldName", fieldName); } /** * Returns the data field name this Position refers to. * * @return a non-null string. For the special {@link #ROOT} position constant, this is the empty string. */ @Override public String getName() { return fieldName; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((fieldName == null) ? 0 : fieldName.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; } NamedPosition other = (NamedPosition) obj; if (fieldName == null) { if (other.fieldName != null) { return false; } } else if (!fieldName.equals(other.fieldName)) { return false; } return true; } @Override public String toString() { return "NamedPosition{" + "fieldName='" + fieldName + '\'' + '}'; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/Notification.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import java.util.Date; import org.jboss.errai.common.client.api.Assert; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.workbench.events.NotificationEvent; import org.uberfire.workbench.events.NotificationEvent.NotificationType; /** * Represents a notification that has been displayed in the UberFire workbench. *

        * Instances of this class are normally created by the Workbench Notification Manager in response to a * {@link NotificationEvent} being fired as a CDI event. * @see NotificationEvent */ @Portable public class Notification { private NotificationType type; private String message; private Date timestamp; private State state; public Notification(@MapsTo("type") NotificationType type, @MapsTo("message") String message, @MapsTo("timestamp") Date timestamp, @MapsTo("state") State state) { this.type = Assert.notNull(type); this.message = Assert.notNull(message); this.timestamp = Assert.notNull(timestamp); this.state = Assert.notNull(state); } public NotificationType getType() { return type; } public void setType(NotificationType type) { this.type = type; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Date getTimestamp() { return timestamp; } public void setTimestamp(Date timestamp) { this.timestamp = timestamp; } public State getState() { return state; } public void setState(State state) { this.state = state; } @Override public String toString() { return "Notification [type=" + type + ", message=" + message + ", timestamp=" + timestamp + ", state=" + state + "]"; } public enum State { /** * The notification is newly created and has not yet been acknowledged by the user. */ NEW, /** * The notification has been acknowledged by the user. */ ACKNOWLEDGED } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/PanelDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import java.util.List; import java.util.Set; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsMethod; import jsinterop.annotations.JsType; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; /** * Describes a physical region within a Workbench Perspective. Panels have a set physical size that they occupy, which * is divided up between any panel decorations (a tab bar or dropdown list is common), one or more Parts (generally * Editors or Screens), one of which can be visible at a time, and also child Panel Definitions, all of which are * visible simultaneously. */ @JsType public interface PanelDefinition { /** * Special value for {@link #getPanelType()}. When adding a new child panel to a parent panel, if the child panel * has this type, the parent can create any type of PanelPresenter it likes. Typically, each panel type will have * some constant default child type that it uses in this scenario. */ String PARENT_CHOOSES_TYPE = "PARENT_CHOOSES_TYPE"; /** * Returns the DOM ID that will be given to a panel created from this definition. If null, no ID attribute will be * set on a panel created from this definition. */ public String getElementId(); /** * Specifies the DOM ID that should be given to the live panel's element. Applications are responsible for ensuring * the ID values are unique among all live panels. * @param id the DOM ID to give the panel when it is created. If null, no ID will be set on the panel. */ public void setElementId(final String id); /** * Specifies content that should be put in this panel's main display area when it is materialized. The content to * add is specified by a PartDefinition, at the core of which is a {@link PlaceRequest} that identifies a * WorkbenchActivity (either a screen or an editor). *

        * If the given part already belongs to an existing panel, it will be removed from that panel by a call to * removePart(part). * @param part The Part to add. Must not be null. The part's place must specify a WorkbenchActivity bean. */ public void addPart(final PartDefinition part); /** * Specifies content that should be put in this panel's main display area when it is materialized. *

        * This is a convenience method equivalent to * addPart(new PartDefinitionImpl(DefaultPlaceRequest.parse(partSpec))). * @param partSpec An PlaceRequest ID with optional parameters, encoded as specified in * {@link DefaultPlaceRequest#parse(CharSequence)}. Must not be null. The place ID must specify a * WorkbenchActivity bean (either a screen or an editor). * @return the PartDefinition object that was created and added to this panel definition. */ @JsMethod(name = "addPartById") public PartDefinition addPart(final String partSpec); /** * Removes the given part definition from this panel definition. * @param part The Part to be removed * @return true if the part was found and removed; false if it did not belong to this panel in the first place. */ public boolean removePart(final PartDefinition part); /** * Get the Parts contained in the Panel * @return The parts */ public Set getParts(); /** * Returns this panel's immediate child panels. * @return a snapshot of the current child list. The list is not modifiable, and will not change as panels are added * and removed from this panel. The returned list is never null. */ public List getChildren(); /** * Insert a Panel as an immediate child at the given Position. If this * Panel already has a child at the specified position the existing Panel at * that position becomes a child of the Panel being added at the same * Position. * @param position The Position to add the child * @param panel The child Panel */ public void insertChild(final Position position, final PanelDefinition panel); /** * Append a Panel at the first empty child position. If this Panel already * has a child at the specified position the descendants are followed until * an empty position is found. * @param position The Position to add the child * @param panel The child Panel */ @JsMethod(name = "appendChildAtPosition") public void appendChild(final Position position, final PanelDefinition panel); /** * Append a Panel at the first empty child position. If this Panel already * has a child at the specified position the descendants are followed until * an empty position is found. * @param panel The child Panel */ public void appendChild( final PanelDefinition panel); /** * Return the parent panel, or null if {@link #isRoot()}} returns true. * @return a parent panel definition or null if at the top of the hierarchy */ public PanelDefinition getParent(); /** * Get the Panel's immediate child Panel at the given Position * @param position The child Panel's Position * @return The child Panel or null, if a child does not exist at the given * Position */ public PanelDefinition getChild(final Position position); /** * Remove a child from the Panel * @param position */ public void removeChild(final Position position); /** * Is this Panel the root of the Perspective definition * @return True if the Panel is the root */ public boolean isRoot(); /** * Specifies the WorkbenchPanelPresenter implementation that should be used when adding this panel to the UI. Must * refer to a Dependent-scoped Errai IOC bean type. * @return fully-qualified class name of the WorkbenchPanelPresenter implementation to use. Must not be null, but * may be the special value {@link #PARENT_CHOOSES_TYPE}. */ public String getPanelType(); /** * Specifies the WorkbenchPanelPresenter implementation that should be used when adding this panel to the UI. Must * refer to a Dependent-scoped Errai IOC bean type. * @param fqcn fully-qualified class name of the WorkbenchPanelPresenter implementation to use. Must not be null, but * may be the special value {@link #PARENT_CHOOSES_TYPE}. */ public void setPanelType(String fqcn); /** * Get the height of the Panel in pixels * @return The height, or null if not set */ @JsIgnore public Integer getHeight(); /** * Set the height of this panel in pixels using a primitive int to make this method exportable to JS. * @param width The width to set. */ default void setHeight(int height) { setHeight(Integer.valueOf(height)); } /** * Get the height of this panel in pixels as a primitive int to make this method exportable to JS. * @return The height, or -1 if not set. */ default int getHeightAsInt() { final Integer height = getHeight(); return (height != null) ? height : -1; } /** * Set the height of this panel in pixels. * @param height The height to set. If null, the existing height value is retained. */ @JsIgnore public void setHeight(Integer height); /** * Get the width of this panel in pixels. * @return The width, or null if not set. */ @JsIgnore public Integer getWidth(); /** * Set the width of this panel in pixels using a primitive int to make this method exportable to JS. * @param width The width to set. */ default void setWidth(int width) { setWidth(Integer.valueOf(width)); } /** * Get the width of this panel in pixels as a primitive int to make this method exportable to JS. * @return The width, or -1 if not set. */ default int getWidthAsInt() { final Integer width = getWidth(); return (width != null) ? width : -1; } /** * Set the width of this panel in pixels. * @param width The width to set. If null, the existing width value is retained. */ @JsIgnore public void setWidth(Integer width); /** * Get the minimum height of this panel in pixels. * @return The minimum height, or null if not set. */ @JsIgnore public Integer getMinHeight(); /** * Set the minimum height of the Panel in pixels * @param minHeight The minimum height, or null if not set */ @JsIgnore public void setMinHeight(Integer minHeight); /** * Get the minimum width of this panel in pixels as a primitive int to make this method exportable to JS. * @return The height, or -1 if not set. */ default int getMinHeightAsInt() { final Integer height = getMinHeight(); return (height != null) ? height : -1; } /** * Get the minimum width of the Panel in pixels * @return The minimum width, or null if not set */ @JsIgnore public Integer getMinWidth(); /** * Set the minimum width of the Panel in pixels * @param minWidth The width, or null if not set */ @JsIgnore public void setMinWidth(Integer minWidth); /** * Get the minimum width of this panel in pixels as a primitive int to make this method exportable to JS. * @return The width, or -1 if not set. */ default int getMinWidthAsInt() { final Integer width = getMinWidth(); return (width != null) ? width : -1; } /** * Get the Position of the Panel relate to it's Parent *

        * TODO remove this. parent panels should track the positions of their children; making it a property of the child * is error-prone when moving panels around in the UI. * @return The Position of the Panel */ public Position getPosition(); /** * Set the Position of the Panel relative to it's parent. *

        * TODO remove this. parent panels should track the positions of their children; making it a property of the child * is error-prone when moving panels around in the UI. * @param position The Position of the Panel relative to it's parent */ public void setPosition(Position position); /** * Has the Panel been expanded to a maximum size * @return true If maximized */ public boolean isMaximized(); ContextDefinition getContextDefinition(); void setContextDefinition(final ContextDefinition contextDefinition); ContextDisplayMode getContextDisplayMode(); void setContextDisplayMode(final ContextDisplayMode contextDisplayMode); /** * Invokes {@link #toString()} but exported to JavaScript so it can be invoked from different scripts. */ default String asString() { return this.toString(); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/PartDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import jsinterop.annotations.JsType; import org.uberfire.mvp.PlaceRequest; /** * Describes the assignment of a {@link PlaceRequest} to a tab/card/item in a {@link PanelDefinition}. Given this * information, you can find out (or dictate) which panel within the current perspective will contain the GUI element * for the given PlaceRequest. However, the {@link PartDefinition} does not contain any information about the GUI * itself, presumably because PartDefinition objects can be sent to the server. The UI (Widget) information is contained * with UIPart. The mapping of PartDefinitions to UIParts is maintained by a PanelManager. */ @JsType public interface PartDefinition { PlaceRequest getPlace(); void setPlace(final PlaceRequest place); PanelDefinition getParentPanel(); void setParentPanel(final PanelDefinition parentPanel); ContextDefinition getContextDefinition(); void setContextDefinition(final ContextDefinition contextDefinition); ContextDisplayMode getContextDisplayMode(); void setContextDisplayMode(final ContextDisplayMode contextDisplayMode); /** * Invokes {@link #toString()} but exported to JavaScript so it can be invoked from different scripts. */ default String asString() { return this.toString(); } boolean isSelectable(); void setSelectable(boolean selectable); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/PerspectiveDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import jsinterop.annotations.JsType; /** * Meta-data defining a Perspective. A Perspective is a set of Panels and Parts arranged within the Workbench. The * Workbench has exactly one active Perspective at a time. The Perspective contains multiple Panels. Each Panel contains * multiple Parts, one of which can be visible at a time. Panels can also contain child panels which are all visible at * the same time are are physically located within the bounds of the parent panel. Each Part is associated with one * PlaceRequest. *

        * Implementations of this interface must be marked with Errai's {@code @Portable} annotation. */ @JsType public interface PerspectiveDefinition { /** * Get the name of the Perspective. * @return The name of the Perspective. */ public String getName(); /** * Set the name of the Perspective. * @param name The name of the Perspective. */ public void setName(final String name); /** * Get the root Panel for this Perspective. The root Panel contains all * child Panels. A Perspective is based on a single root Panel. * @return The root Panel. */ public PanelDefinition getRoot(); ContextDefinition getContextDefinition(); void setContextDefinition(final ContextDefinition contextDefinition); ContextDisplayMode getContextDisplayMode(); void setContextDisplayMode(final ContextDisplayMode contextDisplayMode); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/Position.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import jsinterop.annotations.JsType; import org.jboss.errai.common.client.api.annotations.Portable; /** * Tells a PanelManager implementation where to place a part within a panel. Each PanelManager has its own layout * system, and implements its own unique set of Position objects (for example, the North-South-East-West panel manager * uses compass directions, and the Templated panel manager uses element names). *

        * All implementations of this interface must be marked as {@link Portable}. */ @JsType public interface Position { String getName(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/SplashScreenFilter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import java.util.Collection; import org.jboss.errai.common.client.api.annotations.Portable; /** * Describes the current interception rules for a splash screen, including the user's current preference for whether * or not the screen should be displayed next time one of its interception points is matched. *

        * All implementations of this interface must be marked as {@link Portable}. */ public interface SplashScreenFilter { String getName(); void setName(final String name); boolean displayNextTime(); void setDisplayNextTime(final boolean value); Collection getInterceptionPoints(); void setInterceptionPoints(final Collection places); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/bridge/Notification.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * * */ package org.uberfire.workbench.model.bridge; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsProperty; import jsinterop.annotations.JsType; @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class Notification { @JsProperty(name = "path") public native void setPath(String path); @JsProperty(name = "path") public native String getPath(); @JsProperty(name = "message") public native void setMessage(String message); @JsProperty(name = "message") public native String getMessage(); @JsProperty(name = "severity") public native void setSeverity(String notificationSeverity); @JsProperty(name = "severity") public native String getSeverity(); @JsProperty(name = "type") public native void setType(String type); @JsProperty(name = "type") public native String getType(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/bridge/NotificationSeverity.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * * */ package org.uberfire.workbench.model.bridge; public class NotificationSeverity { public static String INFO = "INFO"; public static String SUCCESS = "SUCCESS"; public static String ERROR = "ERROR"; public static String WARNING = "WARNING"; public static String HINT = "HINT"; } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/bridge/NotificationType.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * * */ package org.uberfire.workbench.model.bridge; public class NotificationType { public static String PROBLEM = "PROBLEM"; public static String ALERT = "ALERT"; } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/impl/ContextDefinitionImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.model.ContextDefinition; @Portable public class ContextDefinitionImpl implements ContextDefinition { private PlaceRequest place; public ContextDefinitionImpl(@MapsTo("place") final PlaceRequest place) { this.place = place; } @Override public PlaceRequest getPlace() { return place; } @Override public void setPlace(final PlaceRequest place) { this.place = place; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/impl/CustomPanelDefinitionImpl.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import java.util.Optional; import com.google.gwt.user.client.ui.HasWidgets; import org.jboss.errai.common.client.dom.HTMLElement; import org.uberfire.workbench.model.CustomPanelDefinition; public class CustomPanelDefinitionImpl extends PanelDefinitionImpl implements CustomPanelDefinition { private HTMLElement htmlElementContainer; private HasWidgets hasWidgetsContainer; private elemental2.dom.HTMLElement elemental2HtmlElementContainer; public CustomPanelDefinitionImpl(String panelType, HasWidgets hasWidgetsContainer) { super(panelType); this.hasWidgetsContainer = hasWidgetsContainer; } public CustomPanelDefinitionImpl(String panelType, HTMLElement htmlElementContainer) { super(panelType); this.htmlElementContainer = htmlElementContainer; } public CustomPanelDefinitionImpl(String panelType, elemental2.dom.HTMLElement htmlElementContainer){ super(panelType); this.elemental2HtmlElementContainer = htmlElementContainer; } @Override public Optional getHtmlElementContainer() { return Optional.ofNullable(htmlElementContainer); } @Override public Optional getHasWidgetsContainer() { return Optional.ofNullable(hasWidgetsContainer); } @Override public Optional getElemental2HtmlElementContainer() { return Optional.ofNullable(elemental2HtmlElementContainer); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PanelDefinitionImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsType; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.CompassPosition; import org.uberfire.workbench.model.ContextDefinition; import org.uberfire.workbench.model.ContextDisplayMode; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PartDefinition; import org.uberfire.workbench.model.Position; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.uberfire.workbench.model.ContextDisplayMode.SHOW; /** * Default implementation of PanelDefinition */ @Portable @JsType public class PanelDefinitionImpl implements PanelDefinition { private final Set parts = new LinkedHashSet<>(); //Ideally this should be a Set but the order of insertion is important private final List children = new ArrayList(); private Integer height = null; private Integer width = null; private Integer minHeight = null; private Integer minWidth = null; private String elementId; private Position position; private String panelType; private boolean isRoot; private ContextDefinition contextDefinition; private ContextDisplayMode contextDisplayMode = SHOW; private PanelDefinition parent = null; @JsIgnore public PanelDefinitionImpl() { this("org.uberfire.client.workbench.panels.impl.MultiTabWorkbenchPanelPresenter"); } @JsIgnore public PanelDefinitionImpl(final String type) { this.panelType = type; } @Override public PanelDefinition getParent() { return parent; } public void setParent(PanelDefinition parent) { if (this.parent != null && parent != null) { throw new IllegalStateException("Can't change parent: this panel still belongs to " + this.parent); } this.parent = parent; } @Override public String getElementId() { return elementId; } @Override public void setElementId(String id) { elementId = id; } @Override public void addPart(final PartDefinition part) { if (part.getParentPanel() != null) { part.getParentPanel().removePart(part); } this.parts.add(part); part.setParentPanel(this); } @Override public PartDefinition addPart(String partSpec) { PartDefinition pd = new PartDefinitionImpl(DefaultPlaceRequest.parse(partSpec)); addPart(pd); return pd; } @Override public boolean removePart(PartDefinition part) { if (this.parts.remove(part)) { part.setParentPanel(null); return true; } return false; } @Override @JsIgnore public Set getParts() { return parts; } @Override @JsIgnore public List getChildren() { return Collections.unmodifiableList(new ArrayList(children)); } @Override public void insertChild(final Position position, final PanelDefinition panel) { if (panel == null) { return; } if (children.contains(panel)) { return; } // parent wiring ((PanelDefinitionImpl) panel).setParent(this); checkPosition(position); panel.setPosition(position); final PanelDefinition existingChild = getChild(position); if (existingChild == null) { children.add(panel); } else { removeChild(position); children.add(panel); panel.insertChild(position, existingChild); } } @Override public void appendChild(final Position position, final PanelDefinition panel) { if (panel == null) { return; } if (children.contains(panel)) { return; } checkPosition(position); panel.setPosition(position); final PanelDefinition existingChild = getChild(position); if (existingChild == null) { // parent wiring ((PanelDefinitionImpl) panel).setParent(this); children.add(panel); } else { existingChild.appendChild(position, panel); } } @Override public void appendChild(final PanelDefinition panel) { if (panel == null) { return; } if (children.contains(panel)) { return; } // parent wiring ((PanelDefinitionImpl) panel).setParent(this); children.add(panel); } @Override public PanelDefinition getChild(final Position position) { for (PanelDefinition child : children) { if (child.getPosition() == position) { return child; } } return null; } @Override public void removeChild(final Position position) { Iterator itr = children.iterator(); while (itr.hasNext()) { final PanelDefinition child = itr.next(); if (child.getPosition() == position) { // parent wiring ((PanelDefinitionImpl) child).setParent(null); itr.remove(); } } } @Override public boolean isRoot() { return isRoot; } public void setRoot(boolean isRoot) { this.isRoot = isRoot; } @Override public String getPanelType() { return panelType; } @Override public void setPanelType(String fqcn) { this.panelType = checkNotNull("fqcn", fqcn); } @Override @JsIgnore public Integer getHeight() { return height; } @Override @JsIgnore public void setHeight(Integer height) { if (height != null) { this.height = height; } } @Override @JsIgnore public Integer getWidth() { return width; } @Override @JsIgnore public void setWidth(Integer width) { if (width != null) { this.width = width; } } @Override @JsIgnore public final Integer getMinHeight() { return minHeight; } @Override @JsIgnore public final void setMinHeight(Integer minHeight) { this.minHeight = minHeight; } @Override @JsIgnore public final Integer getMinWidth() { return minWidth; } @Override @JsIgnore public final void setMinWidth(Integer minWidth) { this.minWidth = minWidth; } @Override public final Position getPosition() { return position; } @Override public void setPosition(final Position position) { this.position = position; } @Override public boolean isMaximized() { return false; } @Override public ContextDefinition getContextDefinition() { return contextDefinition; } @Override public void setContextDefinition(final ContextDefinition contextDefinition) { this.contextDefinition = contextDefinition; } @Override public ContextDisplayMode getContextDisplayMode() { return contextDisplayMode; } @Override public void setContextDisplayMode(final ContextDisplayMode contextDisplayMode) { this.contextDisplayMode = contextDisplayMode; } private void checkPosition(final Position position) { if (position == CompassPosition.ROOT || position == CompassPosition.SELF || position == CompassPosition.NONE) { throw new IllegalArgumentException("Position must be NORTH, SOUTH, EAST or WEST"); } } @Override public String toString() { String fullName = getClass().getName(); String simpleName = fullName.substring(fullName.lastIndexOf('.') + 1); return simpleName + " [id=" + elementId + ", parts=" + parts + ", children=" + children + ", panelType=" + panelType + ", contextDefinition=" + contextDefinition + ", contextDisplayMode=" + contextDisplayMode + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PartDefinitionImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.model.ContextDefinition; import org.uberfire.workbench.model.ContextDisplayMode; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PartDefinition; import static org.uberfire.workbench.model.ContextDisplayMode.SHOW; /** * Default implementation of PartDefinition */ @Portable public class PartDefinitionImpl implements PartDefinition { private PlaceRequest place; private PanelDefinition parentPanel; private ContextDefinition contextDefinition; private ContextDisplayMode contextDisplayMode = SHOW; private boolean selectable = true; public PartDefinitionImpl() { } public PartDefinitionImpl(final PlaceRequest place) { this.place = place; } /** * @return the place */ @Override public PlaceRequest getPlace() { return place; } /** * @param place the place to set */ @Override public void setPlace(final PlaceRequest place) { this.place = place; } /** * @return the parentPanel */ @Override public PanelDefinition getParentPanel() { return parentPanel; } /** * @param parentPanel the parentPanel to set */ @Override public void setParentPanel(final PanelDefinition parentPanel) { if (parentPanel != null && this.parentPanel != null) { throw new IllegalStateException("Can't set parent: this part already belongs to " + this.parentPanel); } this.parentPanel = parentPanel; } @Override public ContextDefinition getContextDefinition() { return contextDefinition; } @Override public void setContextDefinition(final ContextDefinition contextDefinition) { this.contextDefinition = contextDefinition; } @Override public ContextDisplayMode getContextDisplayMode() { return contextDisplayMode; } @Override public void setContextDisplayMode(final ContextDisplayMode contextDisplayMode) { this.contextDisplayMode = contextDisplayMode; } @Override public boolean isSelectable() { return this.selectable; } @Override public void setSelectable(final boolean selectable) { this.selectable = selectable; } @Override public int hashCode() { return this.place.hashCode(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null) { return false; } if (!(o instanceof PartDefinitionImpl)) { return false; } PartDefinitionImpl that = (PartDefinitionImpl) o; return place.equals(that.place); } @Override public String toString() { return "PartDefinitionImpl [place=" + place + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/impl/PerspectiveDefinitionImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.workbench.model.ContextDefinition; import org.uberfire.workbench.model.ContextDisplayMode; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PerspectiveDefinition; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.uberfire.workbench.model.ContextDisplayMode.SHOW; /** * Default implementation of PerspectiveDefinition */ @Portable public class PerspectiveDefinitionImpl implements PerspectiveDefinition { private final PanelDefinition root; private String name; private ContextDefinition contextDefinition; private ContextDisplayMode contextDisplayMode = SHOW; public PerspectiveDefinitionImpl() { this("org.uberfire.client.workbench.panels.impl.MultiTabWorkbenchPanelPresenter"); } public PerspectiveDefinitionImpl(final String panelType) { checkNotNull("type", panelType); PanelDefinitionImpl root = new PanelDefinitionImpl(panelType); root.setRoot(true); this.root = root; } @Override public String getName() { return name; } @Override public void setName(final String name) { this.name = name; } @Override public PanelDefinition getRoot() { return root; } @Override public ContextDefinition getContextDefinition() { return contextDefinition; } @Override public void setContextDefinition(final ContextDefinition contextDefinition) { this.contextDefinition = contextDefinition; } @Override public ContextDisplayMode getContextDisplayMode() { return contextDisplayMode; } @Override public void setContextDisplayMode(final ContextDisplayMode contextDisplayMode) { this.contextDisplayMode = contextDisplayMode; } @Override public String toString() { return "PerspectiveDefinitionImpl [name=" + name + ", contextDefinition=" + contextDefinition + ", contextDisplayMode=" + contextDisplayMode + "]"; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/impl/SplashScreenFilterImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import java.util.ArrayList; import java.util.Collection; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.workbench.model.SplashScreenFilter; /** * Default implementation of SplashScreenFilter */ @Portable public class SplashScreenFilterImpl implements SplashScreenFilter { private String name; private boolean displayNextTime; private Collection interceptionPoints = new ArrayList(); public SplashScreenFilterImpl(@MapsTo("name") final String name, @MapsTo("displayNextTime") final boolean displayNextTime, @MapsTo("interceptionPoints") final Collection interceptionPoints) { this.name = name; this.displayNextTime = displayNextTime; this.interceptionPoints.addAll(interceptionPoints); } @Override public String getName() { return name; } @Override public void setName(final String name) { this.name = name; } @Override public boolean displayNextTime() { return displayNextTime; } @Override public void setDisplayNextTime(final boolean value) { this.displayNextTime = value; } @Override public Collection getInterceptionPoints() { return interceptionPoints; } @Override public void setInterceptionPoints(final Collection places) { interceptionPoints.clear(); interceptionPoints.addAll(places); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/EnabledStateChangeListener.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsFunction; /** * A Listener for changes in a Widget's enabled state */ @JsFunction public interface EnabledStateChangeListener { /** * Called when the enabled state of a Widget changes * @param enabled */ void enabledStateChanged(final boolean enabled); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/HasEnabledStateChangeListeners.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsType; /** * A source of EnabledStateChange actions. */ @JsType public interface HasEnabledStateChangeListeners { /** * Called when the enabled state of a Widget changes * @param listener */ void addEnabledStateChangeListener(final EnabledStateChangeListener listener); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuCustom.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsType; /** * A menu item that provides its own widget. * @param The type of widget the custom menu item provides. */ @JsType public interface MenuCustom extends MenuItem { T build(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuFactory.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import java.util.List; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.security.Resource; import org.uberfire.security.ResourceAction; import org.uberfire.security.ResourceType; import org.uberfire.workbench.model.menu.impl.MenuBuilderImpl; import static org.uberfire.workbench.model.menu.impl.MenuBuilderImpl.MenuType.CONTRIBUTED; import static org.uberfire.workbench.model.menu.impl.MenuBuilderImpl.MenuType.CUSTOM; import static org.uberfire.workbench.model.menu.impl.MenuBuilderImpl.MenuType.REGULAR; import static org.uberfire.workbench.model.menu.impl.MenuBuilderImpl.MenuType.TOP_LEVEL; public final class MenuFactory { private MenuFactory() { } public static MenuBuilder> newTopLevelMenu(final String caption) { return new MenuBuilderImpl(TOP_LEVEL, caption); } public static ContributedMenuBuilder> newContributedMenu(final String caption) { return new MenuBuilderImpl(CONTRIBUTED, caption); } public static MenuBuilder newSimpleItem(final String caption) { return new MenuBuilderImpl(REGULAR, caption); } public static MenuBuilder> newTopLevelCustomMenu(final CustomMenuBuilder builder) { return new MenuBuilderImpl(CUSTOM, builder); } public interface TopLevelMenusBuilder extends Builder { ContributedMenuBuilder> newContributedMenu(final String caption); TerminalMenu> newTopLevelMenu(final MenuItem menu); MenuBuilder> newTopLevelMenu(final String caption); TerminalCustomMenu> newTopLevelCustomMenu(final CustomMenuBuilder builder); } public interface Builder { Menus build(); } public interface ContributedMenuBuilder extends MenuBuilder { ContributedMenuBuilder contributeTo(final String contributionPoint); } public interface MenuBuilder extends SimpleMenuBuilder>, SecurityInfos>, CommandMenu>, PerspectiveMenu>, OrderedMenu> { TerminalMenu custom(final CustomMenuBuilder builder); SubMenusBuilder> submenu(final String caption); SubMenusBuilder> menus(); TerminalMenu withItems(final List items); T endMenu(); } public interface SubMenuBuilder extends SimpleMenuBuilder>, SecurityInfos> { SubMenusBuilder> submenu(final String caption); T endMenu(); } public interface SimpleMenuBuilder { T identifier(final String id); T order(final int order); T position(final MenuPosition position); } public interface SubMenusBuilder { MenuBuilder> menu(final String caption); T endMenus(); } public interface TerminalMenu { T endMenu(); } public interface TerminalCustomMenu { T endMenu(); } public interface SecurityInfos { T withPermission(final ResourceType resourceType); T withPermission(final ResourceType resourceType, final ResourceAction resourceAction); T withPermission(final ResourceType resourceType, final Resource resource, final ResourceAction resourceAction); T withPermission(final Resource resource); T withPermission(final Resource resource, final ResourceAction resourceAction); T withPermission(final String resourceId, final ResourceType resourceType); T withPermission(final String resourceId, final ResourceType resourceType, final ResourceAction resourceAction); T withPermission(final String permission); } public interface CustomMenuBuilder { void push(final CustomMenuBuilder element); MenuItem build(); } public interface CommandMenu { T respondsWith(final Command command); } public interface PerspectiveMenu { T perspective(final String identifier); T place(final PlaceRequest placeRequest); } public interface OrderedMenu { T orderAll(final int order); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuGroup.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import java.util.List; import jsinterop.annotations.JsType; /** * A menu item that has child items nested under it. */ @JsType public interface MenuGroup extends MenuItem { List getItems(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItem.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import java.util.Collections; import java.util.List; import jsinterop.annotations.JsType; import org.uberfire.security.authz.ResourceActionRef; import org.uberfire.security.authz.RuntimeFeatureResource; /** * Meta-data for a Workbench MenuItem including permissions. The default is that * all users have permission to access a MenuItem and that it is enabled. */ @JsType public interface MenuItem extends RuntimeFeatureResource, HasEnabledStateChangeListeners { boolean isEnabled(); void setEnabled(boolean enabled); String getContributionPoint(); String getCaption(); MenuPosition getPosition(); int getOrder(); /** * Get the list of {@link ResourceActionRef} actions this menu item is * restricted to. *

        *

        * The menu item will be available provided all the given actions are * authorized within the current context. *

        */ default List getResourceActions() { return Collections.emptyList(); } /** * Get the list of permission names this menu item is restricted to. *

        *

        * The menu item will be available provided all the given permissions are * authorized within the current context. *

        */ default List getPermissions() { return Collections.emptyList(); } /** * Causes the given {@link MenuVisitor} to visit this menu item and its * children. */ void accept(MenuVisitor visitor); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemCommand.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsType; import org.uberfire.mvp.Command; /** * A menu item that invokes a particular {@link Command} when it is clicked. */ @JsType public interface MenuItemCommand extends MenuItem { /** * @return the command */ public Command getCommand(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPerspective.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsType; import org.uberfire.mvp.PlaceRequest; /** * A menu item that invokes a particular {@link org.uberfire.workbench.model.PerspectiveDefinition} when it is clicked. */ @JsType public interface MenuItemPerspective extends MenuItem { PlaceRequest getPlaceRequest(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuItemPlain.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsType; import org.uberfire.mvp.Command; /** * A menu item that has no children and no specific {@link Command} associated with it. */ @JsType public interface MenuItemPlain extends MenuItem { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuPosition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsType; /** * Defines the menu position on the navbar. */ @JsType public enum MenuPosition { LEFT, RIGHT } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/MenuVisitor.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import jsinterop.annotations.JsMethod; import jsinterop.annotations.JsType; /** * Visitor interface for implementing arbitrary operations over menus. For example, a visitor could filter a menu tree * for items that the current user has permission to see; it could build widgets in a particular view module; it could * simply dump the menu structure to a string. */ @JsType public interface MenuVisitor { /** * Visits the top-level menu container. This is the first method invoked when visiting a complete menu tree. * @param menus the top-level container of the menus that will be visited. * @return true if the visitor would like to continue down the tree and visit all children; false if it wants to * skip this node. Since this is the root node, returning false from this call will result in no more calls * to the visitor. */ boolean visitEnter(Menus menus); /** * Ends the visit of the top-level menu container. This is the last method invoked when visiting a complete menu tree. *

        * Note that this method is not called if {@link #visitEnter(Menus)} returns false. * @param menus the top-level container of the menus that will be visited. */ void visitLeave(Menus menus); /** * Visits a menu group in the tree of menus. A menu group has zero or more MenuItem children. * @param menuGroup the menu group to visit. * @return true if the visitor would like to visit all children of this node; false if it wants to skip this node. A * visitor that returns false from this node will not receive any further calls for this node or its * descendants. In particular, there will be no corresponding {@link #visitLeave(MenuGroup)} call for this * node. */ @JsMethod(name = "visitEnterGroup") boolean visitEnter(MenuGroup menuGroup); /** * Visits a menu group in the tree of menus. All descendants of the given menu group have been visited before this method is called. *

        * Note that this method is not called for a MenuGroup where the {@link #visitEnter(MenuGroup)} method returned false. * @param menuGroup the menu group to leave. */ @JsMethod(name = "visitLeaveGroup") void visitLeave(MenuGroup menuGroup); /** * Visits a plain menu item in the tree. * @param menuItemPlain the plain menu item to visit. */ void visit(MenuItemPlain menuItemPlain); /** * Visits a menu item that has an associated command. * @param menuItemCommand the command menu item to visit. */ @JsMethod(name = "visitCommand") void visit(MenuItemCommand menuItemCommand); /** * Visits a menu item that has an associated perspective. * @param menuItemPerspective the command menu item to visit. */ @JsMethod(name = "visitPerspective") void visit(MenuItemPerspective menuItemPerspective); /** * Visits a custom menu item in the menu tree. * @param menuCustom the custom (application provides the widget) menu item to visit. */ @JsMethod(name = "visitCustom") void visit(MenuCustom menuCustom); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/Menus.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; import java.util.List; import java.util.Map; import jsinterop.annotations.JsType; /** * Menus that includes permission */ @JsType public interface Menus { /** * Returns the items in this collection of menus, in the order they should appear in the user interface. */ public List getItems(); @Deprecated public Map getItemsMap(); /** * Causes the given {@link MenuVisitor} to visit this menu, then each item in turn (they will pass the visitor to * their descendants). The menu items will be visited via an pre-order traversal (parents are visited before their * children). Top-level menu items are visited in the same order as they are returned from {@link #getItems()}. */ public void accept(MenuVisitor visitor); /** * Defines the order on what these menus will be inserted. */ public int getOrder(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/BaseMenuCustom.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu.impl; import org.uberfire.workbench.model.menu.EnabledStateChangeListener; import org.uberfire.workbench.model.menu.MenuCustom; import org.uberfire.workbench.model.menu.MenuPosition; import org.uberfire.workbench.model.menu.MenuVisitor; public abstract class BaseMenuCustom implements MenuCustom { private final String contributionPoint; private final String caption; private final MenuPosition position; private boolean enabled; protected BaseMenuCustom() { this(null, null, null, true); } protected BaseMenuCustom(boolean enabled) { this(null, null, null, enabled); } protected BaseMenuCustom(final String contributionPoint) { this(contributionPoint, null, null, true); } protected BaseMenuCustom(final String contributionPoint, final String caption) { this(contributionPoint, caption, null, true); } public BaseMenuCustom(final String contributionPoint, final String caption, final MenuPosition position) { this(contributionPoint, caption, position, true); } public BaseMenuCustom(final String contributionPoint, final String caption, final MenuPosition position, final boolean enabled) { this.contributionPoint = contributionPoint; this.caption = caption; this.position = position; this.enabled = enabled; } @Override public String getIdentifier() { if (contributionPoint != null) { return getClass().getName() + "#" + contributionPoint + "#" + caption; } return getClass().getName() + "#" + caption; } @Override public boolean isEnabled() { return enabled; } @Override public void setEnabled(boolean enabled) { this.enabled = enabled; } @Override public String getContributionPoint() { return contributionPoint; } @Override public String getCaption() { return caption; } @Override public MenuPosition getPosition() { return position; } @Override public int getOrder() { return 0; } @Override public void accept(final MenuVisitor visitor) { visitor.visit(this); } @Override public void addEnabledStateChangeListener(final EnabledStateChangeListener listener) { } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/BaseMenuVisitor.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu.impl; import org.uberfire.workbench.model.menu.MenuCustom; import org.uberfire.workbench.model.menu.MenuGroup; import org.uberfire.workbench.model.menu.MenuItemCommand; import org.uberfire.workbench.model.menu.MenuItemPerspective; import org.uberfire.workbench.model.menu.MenuItemPlain; import org.uberfire.workbench.model.menu.MenuVisitor; import org.uberfire.workbench.model.menu.Menus; public abstract class BaseMenuVisitor implements MenuVisitor { @Override public boolean visitEnter(Menus menus) { return true; } @Override public void visitLeave(Menus menus) { } @Override public boolean visitEnter(MenuGroup menuGroup) { return true; } @Override public void visitLeave(MenuGroup menuGroup) { } @Override public void visit(MenuItemPlain menuItemPlain) { } @Override public void visit(MenuItemCommand menuItemCommand) { } @Override public void visit(MenuItemPerspective menuItemPerspective) { } @Override public void visit(MenuCustom menuCustom) { } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenuGroup.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu.impl; import java.util.ArrayList; import java.util.List; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsType; import org.uberfire.security.Resource; import org.uberfire.security.authz.ResourceActionRef; import org.uberfire.workbench.model.menu.EnabledStateChangeListener; import org.uberfire.workbench.model.menu.MenuGroup; import org.uberfire.workbench.model.menu.MenuItem; import org.uberfire.workbench.model.menu.MenuPosition; import org.uberfire.workbench.model.menu.MenuVisitor; import static org.uberfire.plugin.PluginUtil.ensureIterable; @JsType public class DefaultMenuGroup implements MenuGroup { private final List enabledStateChangeListeners = new ArrayList(); private final List menuItems; private final String contributionPoint; private final String caption; private final MenuPosition position; private final int order; private boolean isEnabled = true; private List resourceActionRefs; private List permissionNames; @JsIgnore public DefaultMenuGroup(List menuItems, List resourceActionRefs, List permissionNames, String contributionPoint, String caption, MenuPosition position, int order) { this.menuItems = menuItems; this.resourceActionRefs = resourceActionRefs; this.permissionNames = permissionNames; this.contributionPoint = contributionPoint; this.caption = caption; this.position = position; this.order = order; } @JsIgnore @Override public List getItems() { return menuItems; } @Override public String getContributionPoint() { return contributionPoint; } @Override public String getCaption() { return caption; } @Override public MenuPosition getPosition() { return position; } @Override public int getOrder() { return order; } @Override public boolean isEnabled() { return isEnabled; } @Override public void setEnabled(final boolean enabled) { this.isEnabled = enabled; notifyListeners(enabled); } @JsIgnore @Override public void addEnabledStateChangeListener(final EnabledStateChangeListener listener) { enabledStateChangeListeners.add(listener); } @Override public void accept(MenuVisitor visitor) { if (visitor.visitEnter(this)) { for (MenuItem child : ensureIterable(getItems())) { child.accept(visitor); } visitor.visitLeave(this); } } private void notifyListeners(final boolean enabled) { for (final EnabledStateChangeListener listener : enabledStateChangeListeners) { listener.enabledStateChanged(enabled); } } @Override public String getIdentifier() { if (contributionPoint != null) { return getClass().getName() + "#" + contributionPoint + "#" + caption; } return getClass().getName() + "#" + caption; } @JsIgnore @Override public List getResourceActions() { return resourceActionRefs; } @JsIgnore @Override public List getPermissions() { return permissionNames; } @JsIgnore @Override public List getDependencies() { return menuItems; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/DefaultMenus.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu.impl; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import jsinterop.annotations.JsIgnore; import jsinterop.annotations.JsType; import org.uberfire.workbench.model.menu.MenuItem; import org.uberfire.workbench.model.menu.MenuVisitor; import org.uberfire.workbench.model.menu.Menus; @JsType public class DefaultMenus implements Menus { private final List menuItems; private final int order; @JsIgnore public DefaultMenus(List menuItems, int order) { this.menuItems = menuItems; this.order = order; } @JsIgnore @Override public List getItems() { return Collections.unmodifiableList(menuItems); } @Override public void accept(MenuVisitor visitor) { if (visitor.visitEnter(this)) { for (MenuItem item : menuItems) { item.accept(visitor); } visitor.visitLeave(this); } } @JsIgnore @Override public Map getItemsMap() { return new HashMap() { { for (final MenuItem menuItem : menuItems) { put(menuItem, menuItem); } } }; } @Override public int getOrder() { return order; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/menu/impl/MenuBuilderImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu.impl; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Stack; import org.uberfire.mvp.Command; import org.uberfire.mvp.PlaceRequest; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.security.Resource; import org.uberfire.security.ResourceAction; import org.uberfire.security.ResourceRef; import org.uberfire.security.ResourceType; import org.uberfire.security.authz.ResourceActionRef; import org.uberfire.workbench.model.ActivityResourceType; import org.uberfire.workbench.model.menu.EnabledStateChangeListener; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.MenuItem; import org.uberfire.workbench.model.menu.MenuItemCommand; import org.uberfire.workbench.model.menu.MenuItemPerspective; import org.uberfire.workbench.model.menu.MenuItemPlain; import org.uberfire.workbench.model.menu.MenuPosition; import org.uberfire.workbench.model.menu.MenuVisitor; import org.uberfire.workbench.model.menu.Menus; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotEmpty; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * */ public final class MenuBuilderImpl implements MenuFactory.MenuBuilder, MenuFactory.ContributedMenuBuilder, MenuFactory.TopLevelMenusBuilder, MenuFactory.SubMenuBuilder, MenuFactory.SubMenusBuilder, MenuFactory.TerminalMenu, MenuFactory.TerminalCustomMenu { final List menuItems = new ArrayList(); final Stack context = new Stack(); int order = 0; public MenuBuilderImpl(final MenuType menuType, final String caption) { final CurrentContext currentContext = new CurrentContext(); currentContext.caption = checkNotEmpty("caption", caption); currentContext.menuType = checkNotNull("menuType", menuType); context.push(currentContext); } public MenuBuilderImpl(final MenuType menuType, final MenuFactory.CustomMenuBuilder builder) { context.push(builder); } @Override public MenuBuilderImpl newContributedMenu(final String caption) { final CurrentContext currentContext = new CurrentContext(); currentContext.caption = checkNotEmpty("caption", caption); currentContext.menuType = MenuType.CONTRIBUTED; context.push(currentContext); return this; } @Override public MenuBuilderImpl newTopLevelMenu(final MenuItem menu) { final CurrentContext currentContext = new CurrentContext(); currentContext.menu = checkNotNull("menu", menu); context.push(currentContext); return this; } @Override public MenuBuilderImpl newTopLevelMenu(final String caption) { final CurrentContext currentContext = new CurrentContext(); currentContext.caption = checkNotEmpty("caption", caption); currentContext.menuType = MenuType.TOP_LEVEL; context.push(currentContext); return this; } @Override public MenuFactory.TerminalCustomMenu newTopLevelCustomMenu(final MenuFactory.CustomMenuBuilder builder) { context.push(builder); return this; } @Override public MenuBuilderImpl menu(final String caption) { final CurrentContext currentContext = new CurrentContext(); currentContext.caption = checkNotEmpty("caption", caption); currentContext.menuType = MenuType.REGULAR; context.push(currentContext); return this; } @Override public MenuBuilderImpl menus() { ((CurrentContext) context.peek()).menuType = MenuType.GROUP; return this; } @Override public MenuFactory.TerminalMenu custom(MenuFactory.CustomMenuBuilder builder) { context.push(builder); return this; } @Override public MenuBuilderImpl submenu(final String caption) { final CurrentContext currentContext = new CurrentContext(); currentContext.caption = checkNotEmpty("caption", caption); currentContext.menuType = MenuType.GROUP; context.push(currentContext); return this; } @Override public MenuBuilderImpl contributeTo(final String contributionPoint) { ((CurrentContext) context.peek()).contributionPoint = checkNotEmpty("contributionPoint", contributionPoint); return this; } @Override public MenuBuilderImpl withItems(final List items) { ((CurrentContext) context.peek()).menuItems = new ArrayList(checkNotEmpty("items", items)); return this; } @Override public MenuBuilderImpl respondsWith(final Command command) { ((CurrentContext) context.peek()).command = checkNotNull("command", command); return this; } @Override public MenuBuilderImpl perspective(final String identifier) { checkNotNull("perspective", identifier); ((CurrentContext) context.peek()).placeRequest = new DefaultPlaceRequest(identifier); return this; } @Override public MenuBuilderImpl place(final PlaceRequest place) { ((CurrentContext) context.peek()).placeRequest = checkNotNull("place", place); return this; } @Override public MenuBuilderImpl order(final int order) { ((CurrentContext) context.peek()).order = order; return this; } @Override public MenuBuilderImpl position(final MenuPosition position) { ((CurrentContext) context.peek()).position = checkNotNull("position", position); return this; } @Override public MenuBuilderImpl identifier(final String id) { ((CurrentContext) context.peek()).identifier = checkNotEmpty("identifier", id); return this; } @Override public MenuBuilderImpl withPermission(ResourceType resourceType) { ResourceRef resource = new ResourceRef(null, resourceType); ResourceActionRef ref = new ResourceActionRef(resource); ((CurrentContext) context.peek()).resourceActionRefs.add(ref); return this; } @Override public MenuBuilderImpl withPermission(ResourceType resourceType, ResourceAction resourceAction) { ResourceActionRef ref = new ResourceActionRef(resourceType, resourceAction); ((CurrentContext) context.peek()).resourceActionRefs.add(ref); return this; } @Override public MenuBuilderImpl withPermission(ResourceType resourceType, Resource resource, ResourceAction resourceAction) { if (resource == null) { return withPermission(resourceType, resourceAction); } else { return withPermission(resource, resourceAction); } } @Override public MenuBuilderImpl withPermission(Resource resource) { ResourceActionRef ref = new ResourceActionRef(resource); ((CurrentContext) context.peek()).resourceActionRefs.add(ref); return this; } @Override public Object withPermission(String resourceId, ResourceType resourceType) { ResourceRef resource = new ResourceRef(resourceId, resourceType); ResourceActionRef ref = new ResourceActionRef(resource); ((CurrentContext) context.peek()).resourceActionRefs.add(ref); return this; } @Override public Object withPermission(String resourceId, ResourceType resourceType, ResourceAction resourceAction) { ResourceRef resource = new ResourceRef(resourceId, resourceType); ResourceActionRef ref = new ResourceActionRef(resource, resourceAction); ((CurrentContext) context.peek()).resourceActionRefs.add(ref); return this; } @Override public MenuBuilderImpl withPermission(Resource resource, ResourceAction resourceAction) { ResourceActionRef ref = new ResourceActionRef(resource, resourceAction); ((CurrentContext) context.peek()).resourceActionRefs.add(ref); return this; } @Override public MenuBuilderImpl withPermission(String permission) { ((CurrentContext) context.peek()).permissionNames.add(permission); return this; } @Override public MenuBuilderImpl endMenus() { return this; } @Override public MenuBuilderImpl endMenu() { if (context.size() == 1) { menuItems.add(context.pop().build()); } else { final MenuFactory.CustomMenuBuilder active = context.pop(); context.peek().push(active); } return this; } @Override public MenuBuilderImpl orderAll(final int order) { this.order = order; return this; } @Override public Menus build() { context.clear(); return new DefaultMenus(menuItems, order); } public enum MenuType { TOP_LEVEL, CONTRIBUTED, REGULAR, GROUP, CUSTOM } private static class CurrentContext implements MenuFactory.CustomMenuBuilder { MenuItem menu = null; int order = 0; MenuType menuType = MenuType.REGULAR; String caption = null; MenuPosition position = MenuPosition.LEFT; String contributionPoint = null; Command command = null; PlaceRequest placeRequest = null; String identifier = null; List resourceActionRefs = new ArrayList<>(); List permissionNames = new ArrayList<>(); List menuItems = new ArrayList(); Stack menuRawItems = new Stack(); @Override public void push(MenuFactory.CustomMenuBuilder element) { menuRawItems.push(element); } @Override public MenuItem build() { if (menu != null) { return menu; } if (menuItems.size() > 0 || menuRawItems.size() > 0) { if (menuRawItems.size() > 0) { for (final MenuFactory.CustomMenuBuilder current : menuRawItems) { menuItems.add(current.build()); } } return new DefaultMenuGroup(menuItems, resourceActionRefs, permissionNames, contributionPoint, caption, position, order); } else if (command != null) { return new MenuItemCommand() { private final List enabledStateChangeListeners = new ArrayList(); private boolean isEnabled = true; @Override public String getIdentifier() { if (identifier != null) { return identifier; } if (contributionPoint != null) { return getClass().getName() + "#" + contributionPoint + "#" + caption; } return getClass().getName() + "#" + caption; } @Override public List getResourceActions() { return resourceActionRefs; } @Override public List getPermissions() { return permissionNames; } @Override public Command getCommand() { return command; } @Override public String getContributionPoint() { return contributionPoint; } @Override public String getCaption() { return caption; } @Override public MenuPosition getPosition() { return position; } @Override public int getOrder() { return order; } @Override public boolean isEnabled() { return isEnabled; } @Override public void setEnabled(final boolean enabled) { this.isEnabled = enabled; notifyListeners(enabled); } @Override public void addEnabledStateChangeListener(final EnabledStateChangeListener listener) { enabledStateChangeListeners.add(listener); } @Override public void accept(MenuVisitor visitor) { visitor.visit(this); } private void notifyListeners(final boolean enabled) { for (final EnabledStateChangeListener listener : enabledStateChangeListeners) { listener.enabledStateChanged(enabled); } } }; } else if (placeRequest != null) { return new MenuItemPerspective() { private final List enabledStateChangeListeners = new ArrayList(); private boolean isEnabled = true; @Override public PlaceRequest getPlaceRequest() { return placeRequest; } @Override public String getIdentifier() { if (identifier != null) { return identifier; } if (contributionPoint != null) { return getClass().getName() + "#" + contributionPoint + "#" + caption; } return getClass().getName() + "#" + caption; } @Override public List getResourceActions() { return resourceActionRefs; } @Override public List getPermissions() { return permissionNames; } @Override public List getDependencies() { ResourceRef ref = new ResourceRef(placeRequest.getIdentifier(), ActivityResourceType.PERSPECTIVE); return Collections.singletonList(ref); } @Override public String getContributionPoint() { return contributionPoint; } @Override public String getCaption() { return caption; } @Override public MenuPosition getPosition() { return position; } @Override public int getOrder() { return order; } @Override public boolean isEnabled() { return isEnabled; } @Override public void setEnabled(final boolean enabled) { this.isEnabled = enabled; notifyListeners(enabled); } @Override public void addEnabledStateChangeListener(final EnabledStateChangeListener listener) { enabledStateChangeListeners.add(listener); } @Override public void accept(MenuVisitor visitor) { visitor.visit(this); } private void notifyListeners(final boolean enabled) { for (final EnabledStateChangeListener listener : enabledStateChangeListeners) { listener.enabledStateChanged(enabled); } } }; } return new MenuItemPlain() { private final List enabledStateChangeListeners = new ArrayList(); private boolean isEnabled = true; @Override public String getIdentifier() { if (identifier != null) { return identifier; } if (contributionPoint != null) { return getClass().getName() + "#" + contributionPoint + "#" + caption; } return getClass().getName() + "#" + caption; } @Override public List getResourceActions() { return resourceActionRefs; } @Override public List getPermissions() { return permissionNames; } @Override public String getContributionPoint() { return contributionPoint; } @Override public String getCaption() { return caption; } @Override public MenuPosition getPosition() { return position; } @Override public int getOrder() { return order; } @Override public boolean isEnabled() { return isEnabled; } @Override public void setEnabled(final boolean enabled) { this.isEnabled = enabled; notifyListeners(enabled); } @Override public void addEnabledStateChangeListener(final EnabledStateChangeListener listener) { enabledStateChangeListeners.add(listener); } @Override public void accept(MenuVisitor visitor) { visitor.visit(this); } private void notifyListeners(final boolean enabled) { for (final EnabledStateChangeListener listener : enabledStateChangeListeners) { listener.enabledStateChanged(enabled); } } }; } } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/IconType.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar; public enum IconType { ADJUST, ALIGN_CENTER, ALIGN_JUSTIFY, ALIGN_LEFT, ALIGN_RIGHT, AMBULANCE, ANGLE_DOWN, ANGLE_LEFT, ANGLE_RIGHT, ANGLE_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ASTERISK, BACKWARD, BAN_CIRCLE, BAR_CHART, BARCODE, BEAKER, BEER, BELL, BELL_ALT, BOLD, BOLT, BOOK, BOOKMARK, BOOKMARK_EMPTY, BRIEFCASE, BUILDING, BULLHORN, CALENDAR, CAMERA, CAMERA_RETRO, CARET_DOWN, CARET_LEFT, CARET_RIGHT, CARET_UP, CERTIFICATE, CHECK, CHECK_EMPTY, CHEVRON_DOWN, CHEVRON_LEFT, CHEVRON_RIGHT, CHEVRON_UP, CIRCLE_ARROW_DOWN, CIRCLE_ARROW_LEFT, CIRCLE_ARROW_RIGHT, CIRCLE_ARROW_UP, CIRCLE, CIRCLE_BLANK, CLOUD, CLOUD_DOWNLOAD, CLOUD_UPLOAD, COFFEE, COG, COGS, COLUMNS, COMMENT, COMMENT_ALT, COMMENTS, COMMENTS_ALT, COPY, CREDIT_CARD, CUT, DASHBOARD, DESKTOP, DOUBLE_ANGLE_DOWN, DOUBLE_ANGLE_LEFT, DOUBLE_ANGLE_RIGHT, DOUBLE_ANGLE_UP, DOWNLOAD, DOWNLOAD_ALT, EDIT, EJECT, ENVELOPE, ENVELOPE_ALT, EXCHANGE, EXCLAMATION_SIGN, EXTERNAL_LINK, EYE_CLOSE, EYE_OPEN, FACEBOOK, FACEBOOK_SIGN, FACETIME_VIDEO, FAST_BACKWARD, FAST_FORWARD, FIGHTER_JET, FILE, FILE_ALT, FILM, FILTER, FIRE, FLAG, FOLDER_CLOSE, FOLDER_CLOSE_ALT, FOLDER_OPEN, FOLDER_OPEN_ALT, FONT, FOOD, FORWARD, FULLSCREEN, GIFT, GITHUB, GITHUB_ALT, GITHUB_SIGN, GLASS, GLOBE, GOOGLE_PLUS, GOOGLE_PLUS_SIGN, GROUP, H_SIGN, HAND_DOWN, HAND_LEFT, HAND_RIGHT, HAND_UP, HDD, HEADPHONES, HEART, HEART_EMPTY, HOME, HOSPITAL, INBOX, INDENT_LEFT, INDENT_RIGHT, INFO_SIGN, ITALIC, KEY, LAPTOP, LEAF, LEGAL, LEMON, LIGHTBULB, LINK, LINKEDIN, LINKEDIN_SIGN, LIST, LIST_ALT, LIST_OL, LIST_UL, LOCK, MAGIC, MAGNET, MAP_MARKER, MEDKIT, MINUS, MINUS_SIGN, MOBILE_PHONE, MONEY, MOVE, MUSIC, OFF, OK, OK_CIRCLE, OK_SIGN, PAPER_CLIP, PASTE, PAUSE, PENCIL, PHONE, PHONE_SIGN, PICTURE, PINTEREST, PINTEREST_SIGN, PLANE, PLAY, PLAY_CIRCLE, PLUS, PLUS_SIGN, PLUS_SIGN_ALT, PRINT, PUSHPIN, QRCODE, QUESTION_SIGN, QUOTE_LEFT, QUOTE_RIGHT, RANDOM, REFRESH, REMOVE, REMOVE_CIRCLE, REMOVE_SIGN, REORDER, REPEAT, REPLY, RESIZE_FULL, RESIZE_HORIZONTAL, RESIZE_SMALL, RESIZE_VERTICAL, RETWEET, ROAD, RSS, SAVE, SCREENSHOT, SEARCH, SHARE, SHARE_ALT, SHOPPING_CART, SIGN_BLANK, SIGNAL, SIGNIN, SIGNOUT, SITEMAP, SORT, SORT_DOWN, SORT_UP, SPINNER, STAR, STAR_EMPTY, STAR_HALF, STEP_BACKWARD, STEP_FORWARD, STETHOSCOPE, STOP, STRIKETHROUGH, SUITCASE, TABLE, TABLET, TAG, TAGS, TASKS, TEXT_HEIGHT, TEXT_WIDTH, TH, TH_LARGE, TH_LIST, THUMBS_DOWN, THUMBS_UP, TIME, TINT, TRASH, TROPHY, TRUCK, TWITTER, TWITTER_SIGN, UMBRELLA, UNDERLINE, UNDO, UNLOCK, UPLOAD, UPLOAD_ALT, USER, USER_MD, VOLUME_DOWN, VOLUME_OFF, VOLUME_UP, WARNING_SIGN, WRENCH, ZOOM_IN, ZOOM_OUT; } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBar.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar; import java.util.List; import jsinterop.annotations.JsType; import org.uberfire.security.authz.RuntimeFeatureResource; /** * Meta-data for a Workbench Tool Bar including permissions */ @JsType public interface ToolBar extends RuntimeFeatureResource { void addItem(final ToolBarItem item); List getItems(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarIcon.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar; import jsinterop.annotations.JsType; /** * */ @JsType public interface ToolBarIcon { } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarItem.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar; import jsinterop.annotations.JsType; import org.uberfire.mvp.Command; import org.uberfire.security.authz.RuntimeFeatureResource; /** * Meta-data for a Workbench Tool Bar Item including permissions. The default is * that all users have permission to access a Tool BarItem Item and that it is * enabled. */ @JsType public interface ToolBarItem extends RuntimeFeatureResource { /** * @return the caption */ String getTooltip(); /** * @return the toolbar icon information */ ToolBarIcon getIcon(); /** * @return is the Tool Bar Item enabled */ boolean isEnabled(); /** * @param enabled the enabled to set */ void setEnabled(boolean enabled); /** * @return The command associated with the Tool Bar Item */ Command getCommand(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarTypeIcon.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar; public interface ToolBarTypeIcon extends ToolBarIcon { IconType getType(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/ToolBarUrlIcon.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar; public interface ToolBarUrlIcon extends ToolBarIcon { /** * @return The relative URL for the image for the ToolBarItem. Images must * be within the application WAR, i.e. not an external location. */ String getUrl(); } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/impl/DefaultToolBar.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar.impl; import java.util.ArrayList; import java.util.List; import org.uberfire.workbench.model.toolbar.ToolBar; import org.uberfire.workbench.model.toolbar.ToolBarItem; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotEmpty; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * Default implementation of ToolBar */ public class DefaultToolBar implements ToolBar { private final String id; private final List items; public DefaultToolBar(final String id) { this(id, new ArrayList()); } public DefaultToolBar(final String id, final List items) { this.id = checkNotEmpty("id", id); this.items = checkNotNull("items", items); } @Override public String getIdentifier() { return id; } @Override public void addItem(final ToolBarItem item) { this.items.add(checkNotNull("item", item)); } @Override public List getItems() { return this.items; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/model/toolbar/impl/DefaultToolBarItem.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.toolbar.impl; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.toolbar.IconType; import org.uberfire.workbench.model.toolbar.ToolBarIcon; import org.uberfire.workbench.model.toolbar.ToolBarItem; import org.uberfire.workbench.model.toolbar.ToolBarTypeIcon; import org.uberfire.workbench.model.toolbar.ToolBarUrlIcon; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * Default implementation of ToolBarItem */ public class DefaultToolBarItem implements ToolBarItem { private final ToolBarIcon icon; private final String tooltip; private final Command command; private boolean isEnabled = true; public DefaultToolBarItem(final String url, final String tooltip, final Command command) { this.tooltip = checkNotNull("tooltip", tooltip); this.command = checkNotNull("command", command); checkNotNull("url", url); this.icon = new ToolBarUrlIcon() { @Override public String getUrl() { return url; } }; } public DefaultToolBarItem(final IconType iconType, final String tooltip, final Command command) { this.tooltip = checkNotNull("tooltip", tooltip); this.command = checkNotNull("command", command); checkNotNull("iconType", iconType); this.icon = new ToolBarTypeIcon() { @Override public IconType getType() { return iconType; } }; } @Override public String getIdentifier() { return tooltip; } @Override public String getTooltip() { return this.tooltip; } @Override public ToolBarIcon getIcon() { return icon; } @Override public boolean isEnabled() { return this.isEnabled; } @Override public void setEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } @Override public Command getCommand() { return this.command; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/type/AnyResourceTypeDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.type; import org.uberfire.backend.vfs.Path; import org.uberfire.workbench.category.Category; import org.uberfire.workbench.category.Others; public class AnyResourceTypeDefinition implements ResourceTypeDefinition { private Category category; public AnyResourceTypeDefinition() { } public AnyResourceTypeDefinition(final Category category) { this.category = category; } @Override public String getShortName() { return "any"; } @Override public String getDescription() { return "Others"; } @Override public String getPrefix() { return ""; } @Override public String getSuffix() { return ""; } @Override public int getPriority() { return Integer.MIN_VALUE; } @Override public String getSimpleWildcardPattern() { return "*"; } @Override public boolean accept(final Path path) { return true; } @Override public Category getCategory() { return this.category; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/type/DotResourceTypeDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.type; import org.uberfire.backend.vfs.Path; import org.uberfire.workbench.category.Category; import org.uberfire.workbench.category.Others; public class DotResourceTypeDefinition implements ResourceTypeDefinition { private Category category; public DotResourceTypeDefinition() { } public DotResourceTypeDefinition(final Category category) { this.category = category; } @Override public Category getCategory() { return this.category; } @Override public String getShortName() { return "meta data"; } @Override public String getDescription() { return "Dot file"; } @Override public String getPrefix() { return "."; } @Override public String getSuffix() { return ""; } @Override public int getPriority() { return Integer.MAX_VALUE; } @Override public String getSimpleWildcardPattern() { return ".*"; } @Override public boolean accept(final Path path) { return path.getFileName().startsWith(getPrefix()); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/type/FileNameUtil.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.type; import org.uberfire.backend.vfs.Path; public final class FileNameUtil { public static String removeExtension(final Path path, final ResourceTypeDefinition type) { if (path == null) { return null; } final String fileName = path.getFileName(); if (type == null) { return fileName; } return removeExtension(path, type.getSuffix()); } public static String removeExtension(final Path path, final String extension) { if (path == null) { return null; } final String fileName = path.getFileName(); return removeExtension(fileName, extension); } public static String removeExtension(final String fileName, final String extension) { if (fileName == null) { return null; } if (extension == null || extension.isEmpty()) { return fileName; } final int index = indexOfExtension(fileName, extension); if (index == -1) { return fileName; } else { return fileName.substring(0, index); } } private static int indexOfExtension(final String fileName, final String extension) { if (fileName == null) { return -1; } final String suffix = (extension == null ? "" : extension); final int extensionPos = fileName.lastIndexOf("." + suffix); return extensionPos; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/type/ResourceTypeDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.type; import jsinterop.annotations.JsType; import org.uberfire.backend.vfs.Path; import org.uberfire.workbench.category.Category; import org.uberfire.workbench.category.Undefined; import org.uberfire.workbench.diff.DiffMode; /** * Definition of a Resource Type */ @JsType public interface ResourceTypeDefinition { /** * A short name of the resource type * @return the short name */ public String getShortName(); /** * A description of the resource type * @return the description */ public String getDescription(); /** * Resource prefix * @return the prefix */ public String getPrefix(); /** * Resource suffix * @return the prefix */ public String getSuffix(); /** * Defines the resource priority in terms of resource resolution * @return the priority */ public int getPriority(); /** * A simple (and maybe not very accurate) wildcard pattern to search for * this type of resource. * This is only used in order to optimize index and search. * @return the wildcard pattern */ public String getSimpleWildcardPattern(); /** * Indicates if the current parameter path matched the current resource type * @return true if matches, otherwise false */ boolean accept(final Path path); /** * Defines the category for each resource. If no category is defined, {@link Undefined} should be returned * @return the resource category */ Category getCategory(); /** * Defines how the diff of this resource type should be presented. * @return the resource diff mode */ default DiffMode getDiffMode() { return DiffMode.TEXTUAL; } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workbench/type/TextResourceTypeDefinition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.type; import javax.enterprise.inject.Default; import org.uberfire.backend.vfs.Path; import org.uberfire.workbench.annotations.VisibleAsset; import org.uberfire.workbench.category.Category; import org.uberfire.workbench.category.Others; @Default @VisibleAsset public class TextResourceTypeDefinition implements ResourceTypeDefinition { private Category category; public TextResourceTypeDefinition() { } public TextResourceTypeDefinition(final Others category) { this.category = category; } @Override public Category getCategory() { return this.category; } @Override public String getShortName() { return "text"; } @Override public String getDescription() { return "Text file"; } @Override public String getPrefix() { return ""; } @Override public String getSuffix() { return "txt"; } @Override public int getPriority() { return 0; } @Override public String getSimpleWildcardPattern() { return "*.txt"; } @Override public boolean accept(final Path path) { return path.getFileName().endsWith("." + getSuffix()); } } ================================================ FILE: uberfire-api/src/main/java/org/uberfire/workspace/WorkspaceContext.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workspace; /** * This context is used to store the active workspace for the thread that uses that is using it. */ public class WorkspaceContext { private WorkspaceContext() { } private static ThreadLocal workspace = new ThreadLocal<>(); public static void set(String workspace) { WorkspaceContext.workspace.set(workspace); } public static String get() { return workspace.get(); } } ================================================ FILE: uberfire-api/src/main/resources/META-INF/ErraiApp.properties ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. ================================================ FILE: uberfire-api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: uberfire-api/src/main/resources/org/uberfire/UberfireAPI.gwt.xml ================================================ ================================================ FILE: uberfire-api/src/main/resources/org/uberfire/jre/org/uberfire/util/URIUtil.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.util; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.ScriptInjector; import com.google.gwt.http.client.URL; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.TextResource; /** * GWT client-side implementation of URIUtil which relies on URI.js. */ public final class URIUtil { private static final Resources RESOURCES = GWT.create(Resources.class); static { ScriptInjector.fromString(RESOURCES.uriDotJs().getText()).inject(); } public static String encode(String content) { return URL.encode(content); } public static String decode(String content) { return URL.decode(content); } public static String encodeQueryString(String content) { return URL.encodeQueryString(content); } public native static boolean isValid(final String uri) /*-{ var components = URI.parse(uri); if (typeof components.errors !== 'undefined' && components.errors.length > 0) { return false; } if (components.reference != "absolute") { return false; } return true; }-*/; interface Resources extends ClientBundle { @Source("uri.min.js") TextResource uriDotJs(); } } ================================================ FILE: uberfire-api/src/test/java/NaughtyClassInDefaultPackage.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.uberfire.debug.Debug; /** * This class is used for testing the handling of classes in the default package for various methods in {@link Debug}. */ public class NaughtyClassInDefaultPackage { } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/backend/vfs/PathFactoryTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.nio.file.Paths; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class PathFactoryTest { @Test public void lockTest() { Path path = mock(Path.class); when(path.toURI()).thenReturn("default://main@myteam/dora/src/main/resources/com/myteam/dora/sample.drl"); assertEquals("default://locks@system/system/myteam/main/dora/src/main/resources/com/myteam/dora/sample.drl.ulock", PathFactory.newLock(path).toURI()); Path lockPath = PathFactory.newLockPath(path); Path extractedPath = PathFactory.fromLock(lockPath); assertEquals(path.toURI(), extractedPath.toURI()); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/backend/vfs/impl/ObservablePathImplTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs.impl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.vfs.ObservablePath; import org.uberfire.backend.vfs.Path; import org.uberfire.mvp.ParameterizedCommand; import org.uberfire.mvp.impl.PathPlaceRequest; import org.uberfire.rpc.impl.SessionInfoImpl; import org.uberfire.workbench.events.ResourceBatchChangesEvent; import org.uberfire.workbench.events.ResourceChange; import org.uberfire.workbench.events.ResourceCopied; import org.uberfire.workbench.events.ResourceCopiedEvent; import org.uberfire.workbench.events.ResourceDeleted; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamed; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdated; import org.uberfire.workbench.events.ResourceUpdatedEvent; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class ObservablePathImplTest { @Spy @InjectMocks private ObservablePathImpl observablePathImpl; @Mock private PathPlaceRequest pathPlaceRequest; @Mock private Path destinationPath; @Mock private ParameterizedCommand onDelete; @Mock private ParameterizedCommand onUpdate; @Mock private ParameterizedCommand onRename; @Mock private ParameterizedCommand onCopy; private static final User identityUser = new UserImpl("userName"); private static final String MESSAGE = "test message", ASSET_PATH = "default://project/package/Asset.java", OBSERVE_SESSION_ID = "observeSession", RESOURCE_SESSION_ID = "resourceSession"; @Before public void setup() { observablePathImpl.onConcurrentDelete(onDelete); observablePathImpl.onConcurrentUpdate(onUpdate); observablePathImpl.onConcurrentRename(onRename); observablePathImpl.onConcurrentCopy(onCopy); observablePathImpl.sessionInfo = new SessionInfoImpl(OBSERVE_SESSION_ID, identityUser); } @Test public void testResourceDeleteEvent() { doReturn(createPath()).when(pathPlaceRequest).getPath(); observablePathImpl.onResourceDeleted(new ResourceDeletedEvent(pathPlaceRequest.getPath(), MESSAGE, createSessionInfo())); verify(onDelete).execute(any()); verify(observablePathImpl).executeConcurrentDeleteCommand(pathPlaceRequest.getPath(), RESOURCE_SESSION_ID, identityUser); } @Test public void testResourceUpdateEvent() { doReturn(createPath()).when(pathPlaceRequest).getPath(); observablePathImpl.onResourceUpdated(new ResourceUpdatedEvent(pathPlaceRequest.getPath(), MESSAGE, createSessionInfo())); verify(onUpdate).execute(any()); verify(observablePathImpl).executeConcurrentUpdateCommand(pathPlaceRequest.getPath(), RESOURCE_SESSION_ID, identityUser); } @Test public void testResourceRenameEvent() { doReturn(createPath()).when(pathPlaceRequest).getPath(); observablePathImpl.onResourceRenamed(new ResourceRenamedEvent(pathPlaceRequest.getPath(), destinationPath, MESSAGE, createSessionInfo())); verify(onRename).execute(any()); verify(observablePathImpl).executeConcurrentRenameCommand(pathPlaceRequest.getPath(), destinationPath, RESOURCE_SESSION_ID, identityUser); } @Test public void testResourceCopyEvent() { doReturn(createPath()).when(pathPlaceRequest).getPath(); observablePathImpl.onResourceCopied(new ResourceCopiedEvent(pathPlaceRequest.getPath(), destinationPath, MESSAGE, createSessionInfo())); verify(onCopy).execute(any()); verify(observablePathImpl).executeConcurrentCopyCommand(pathPlaceRequest.getPath(), destinationPath, RESOURCE_SESSION_ID, identityUser); } @Test public void testResourceBatchEvent() { doReturn(createPath()).when(pathPlaceRequest).getPath(); final Path path = pathPlaceRequest.getPath(); final Map> batchEvents = new HashMap>() { { put(path, new ArrayList() {{ add(new ResourceCopied(destinationPath, "copied event")); add(new ResourceDeleted("deleted event")); add(new ResourceRenamed(destinationPath, "renamed event")); add(new ResourceUpdated("updated event")); }}); } }; observablePathImpl.onResourceBatchEvent( new ResourceBatchChangesEvent(batchEvents, MESSAGE, createSessionInfo()) ); verify(onCopy).execute(any()); verify(onDelete).execute(any()); verify(onRename).execute(any()); verify(onUpdate).execute(any()); verify(observablePathImpl).executeConcurrentCopyCommand(pathPlaceRequest.getPath(), destinationPath, RESOURCE_SESSION_ID, identityUser); verify(observablePathImpl).executeConcurrentDeleteCommand(pathPlaceRequest.getPath(), RESOURCE_SESSION_ID, identityUser); verify(observablePathImpl).executeConcurrentRenameCommand(pathPlaceRequest.getPath(), destinationPath, RESOURCE_SESSION_ID, identityUser); verify(observablePathImpl).executeConcurrentUpdateCommand(destinationPath, RESOURCE_SESSION_ID, identityUser); } private ObservablePath createPath() { final ObservablePath path = mock(ObservablePath.class); observablePathImpl.wrap(path); return path; } private SessionInfoImpl createSessionInfo() { return new SessionInfoImpl("resourceSession", identityUser); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/debug/DebugTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.debug; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.Test; import static org.junit.Assert.*; public class DebugTest { @Test public void testAbbreviatedName() { assertEquals("ju.List", Debug.abbreviatedName(List.class)); } @Test public void testMemorableNumber() { assertEquals("badodyre", Debug.toMemorableString(56385664)); } @Test public void testMemorableWithNegativeNumber() { assertEquals("d", Debug.toMemorableString(-1)); } @Test public void testMemorableWithZero() { assertEquals("b", Debug.toMemorableString(0)); } @Test public void testObjectId() { Map m = new HashMap(); assertEquals(Debug.abbreviatedName(m.getClass()) + "@" + Debug.toMemorableString(System.identityHashCode(m)), Debug.objectId(m)); } @Test public void testShortNameWithInnerClass() { assertEquals("Map$Entry", Debug.shortName(Map.Entry.class)); } @Test public void testShortNameInDefaultPackage() throws Exception { assertEquals("NaughtyClassInDefaultPackage", Debug.shortName(Class.forName("NaughtyClassInDefaultPackage"))); } @Test public void testAbbreviatedNameInDefaultPackage() throws Exception { assertEquals("NaughtyClassInDefaultPackage", Debug.abbreviatedName(Class.forName("NaughtyClassInDefaultPackage"))); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/mvp/impl/ConditionalPlaceRequestTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp.impl; import org.junit.Test; import org.uberfire.mvp.PlaceRequest; import static org.junit.Assert.*; public class ConditionalPlaceRequestTest { @Test public void conditionalTestTruePredicate() { DefaultPlaceRequest other = new DefaultPlaceRequest("other"); ConditionalPlaceRequest dora = (ConditionalPlaceRequest) new ConditionalPlaceRequest("dora").when(p -> true) .orElse(other); assertEquals(dora, dora.resolveConditionalPlaceRequest()); } @Test public void conditionalTestFalsePredicate() { DefaultPlaceRequest other = new DefaultPlaceRequest("other"); ConditionalPlaceRequest dora = (ConditionalPlaceRequest) new ConditionalPlaceRequest("dora").when(p -> false) .orElse(other); assertEquals(other, dora.resolveConditionalPlaceRequest()); } @Test public void incompleteConditionalShouldReturnDefaultPlaceRequest() { ConditionalPlaceRequest dora = new ConditionalPlaceRequest("dora"); assertEquals("dora", dora.resolveConditionalPlaceRequest().getIdentifier()); } @Test public void incompleteConditionalWithNullsShouldReturnDefaultPlaceRequest() { ConditionalPlaceRequest dora = (ConditionalPlaceRequest) new ConditionalPlaceRequest("dora").when(null).orElse(null); assertEquals("dora", dora.resolveConditionalPlaceRequest().getIdentifier()); } @Test public void conditionalTestChainingPredicate() { DefaultPlaceRequest my = new DefaultPlaceRequest("my"); ConditionalPlaceRequest bento = (ConditionalPlaceRequest) new ConditionalPlaceRequest("bento").when(p -> false) .orElse(my); ConditionalPlaceRequest dora = (ConditionalPlaceRequest) new ConditionalPlaceRequest("dora").when(p -> false) .orElse(bento); assertEquals(my, dora.resolveConditionalPlaceRequest()); } @Test public void conditionalTestChainingPredicateReturningConditional() { DefaultPlaceRequest my = new DefaultPlaceRequest("my"); ConditionalPlaceRequest bento = (ConditionalPlaceRequest) new ConditionalPlaceRequest("bento").when(p -> true) .orElse(my); ConditionalPlaceRequest dora = (ConditionalPlaceRequest) new ConditionalPlaceRequest("dora").when(p -> false) .orElse(bento); assertEquals("bento", dora.resolveConditionalPlaceRequest().getIdentifier()); } @Test public void defaultPlaceRequestEqualsToConditionalPlaceRequest() { final DefaultPlaceRequest defaultPlaceRequest = new DefaultPlaceRequest("my"); final PlaceRequest conditionalPlaceRequest = new ConditionalPlaceRequest("my").when(p -> true).orElse(new DefaultPlaceRequest("other")); equals(defaultPlaceRequest, conditionalPlaceRequest); } @Test public void defaultPlaceRequestNotEqualsToConditionalPlaceRequest() { final DefaultPlaceRequest defaultPlaceRequest = new DefaultPlaceRequest("my"); final PlaceRequest conditionalPlaceRequest = new ConditionalPlaceRequest("my").when(p -> false).orElse(new DefaultPlaceRequest("other")); notEquals(defaultPlaceRequest, conditionalPlaceRequest); } @Test public void defaultPlaceRequestEqualsToIncompleteConditionalPlaceRequest() { final DefaultPlaceRequest defaultPlaceRequest = new DefaultPlaceRequest("my"); final PlaceRequest conditionalPlaceRequest = new ConditionalPlaceRequest("my"); equals(defaultPlaceRequest, conditionalPlaceRequest); } @Test public void trueEvaluatedConditionalPlaceRequestEqualsToAnotherTrueEvaluatedConditionalPlaceRequest() { final PlaceRequest conditionalPlaceRequest1 = new ConditionalPlaceRequest("place1").when(p -> true).orElse(new DefaultPlaceRequest("place2")); final PlaceRequest conditionalPlaceRequest2 = new ConditionalPlaceRequest("place1").when(p -> true).orElse(new DefaultPlaceRequest("place3")); equals(conditionalPlaceRequest1, conditionalPlaceRequest2); } @Test public void falseEvaluatedConditionalPlaceRequestEqualsToAnotherFalseEvaluatedConditionalPlaceRequest() { final PlaceRequest conditionalPlaceRequest1 = new ConditionalPlaceRequest("place1").when(p -> false).orElse(new DefaultPlaceRequest("place2")); final PlaceRequest conditionalPlaceRequest2 = new ConditionalPlaceRequest("place3").when(p -> false).orElse(new DefaultPlaceRequest("place2")); equals(conditionalPlaceRequest1, conditionalPlaceRequest2); } @Test public void trueEvaluatedConditionalPlaceRequestEqualsToAnotherFalseEvaluatedConditionalPlaceRequest() { final PlaceRequest conditionalPlaceRequest1 = new ConditionalPlaceRequest("place1").when(p -> true).orElse(new DefaultPlaceRequest("place2")); final PlaceRequest conditionalPlaceRequest2 = new ConditionalPlaceRequest("place3").when(p -> false).orElse(new DefaultPlaceRequest("place1")); equals(conditionalPlaceRequest1, conditionalPlaceRequest2); } @Test public void falseEvaluatedConditionalPlaceRequestEqualsToAnotherTrueEvaluatedConditionalPlaceRequest() { final PlaceRequest conditionalPlaceRequest1 = new ConditionalPlaceRequest("place1").when(p -> false).orElse(new DefaultPlaceRequest("place2")); final PlaceRequest conditionalPlaceRequest2 = new ConditionalPlaceRequest("place2").when(p -> true).orElse(new DefaultPlaceRequest("place3")); equals(conditionalPlaceRequest1, conditionalPlaceRequest2); } private void equals(final PlaceRequest placeRequest1, final PlaceRequest placeRequest2) { assertTrue(placeRequest1.equals(placeRequest2)); assertTrue(placeRequest2.equals(placeRequest1)); assertEquals(placeRequest1.hashCode(), placeRequest2.hashCode()); } private void notEquals(final PlaceRequest placeRequest1, final PlaceRequest placeRequest2) { assertFalse(placeRequest1.equals(placeRequest2)); assertFalse(placeRequest2.equals(placeRequest1)); assertNotEquals(placeRequest1.hashCode(), placeRequest2.hashCode()); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/mvp/impl/PathPlaceRequestTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.mvp.impl; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.vfs.ObservablePath; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class PathPlaceRequestTest { @Spy private PathPlaceRequest pathPlaceRequest; @Test public void testPreDestroy() { final ObservablePath path = mock(ObservablePath.class); doReturn(path).when(pathPlaceRequest).getPath(); pathPlaceRequest.preDestroy(); verify(path).dispose(); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/security/ResourceRefTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security; import java.util.Arrays; import org.junit.Test; import static org.junit.Assert.*; public class ResourceRefTest { @Test public void testDependencies() { ResourceRef dep1 = new ResourceRef("dep1", () -> "type"); ResourceRef ref = new ResourceRef("id", () -> "type", Arrays.asList(dep1)); assertNotNull(ref.getDependencies()); assertEquals(ref.getDependencies().size(), 1); assertEquals(ref.getDependencies().get(0), dep1); } @Test public void testEmptyDependencies() { ResourceRef ref = new ResourceRef("id", () -> "type"); assertNotNull(ref.getIdentifier()); assertNotNull(ref.getResourceType()); assertNotNull(ref.getDependencies()); assertEquals(ref.getIdentifier(), "id"); assertEquals(ref.getResourceType().getName(), "type"); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/spaces/SpacesAPITest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.spaces; import org.junit.Test; import static org.junit.Assert.assertEquals; public class SpacesAPITest { @Test public void resolveSpacePathTest() { final String spacePath = SpacesAPI.resolveSpacePath(SpacesAPI.Scheme.DEFAULT, "MySpace"); assertEquals("default://MySpace/", spacePath); } @Test public void resolveConfigFileSystemPathTest() { final String configFSPath = SpacesAPI.resolveConfigFileSystemPath(SpacesAPI.Scheme.DEFAULT, "MySpace"); assertEquals("default://MySpace/.config/config", configFSPath); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/workbench/category/CategoryTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.workbench.category; import java.util.Arrays; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import static org.junit.Assert.*; @RunWith(Parameterized.class) public class CategoryTest { @Parameterized.Parameters public static Collection data() { return Arrays.asList(new Object[][]{ // Should be equal {null, null, true}, {"", "", true}, {"a", "a", true}, {"A", "a", true}, {"a", "A", true}, // Should NOT be equal {null, "", false}, {"", null, false}, {null, "a", false}, {"a", null, false}, {"", "a", false}, {"a", "", false}, {"a", null, false}, {"a", "b", false}, {"a", "B", false}, }); } private String cat1Name, cat2Name; private boolean shouldBeEqual; public CategoryTest(String cat1Name, String cat2name, boolean shouldBeEqual) { this.cat1Name = cat1Name; this.cat2Name = cat2name; this.shouldBeEqual = shouldBeEqual; } @Test public void test() { Category c1 = new Category() { @Override public String getName() { return cat1Name; } }; Category c2 = new Category() { @Override public String getName() { return cat2Name; } }; assertEquals(shouldBeEqual, c1.equals(c2)); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/workbench/model/TestWorkbenchModel.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model; import org.junit.Test; import org.uberfire.mvp.impl.DefaultPlaceRequest; import org.uberfire.workbench.model.impl.PanelDefinitionImpl; import org.uberfire.workbench.model.impl.PartDefinitionImpl; import org.uberfire.workbench.model.impl.PerspectiveDefinitionImpl; import static org.junit.Assert.*; /** * Test panel hierarchy constraints. */ public class TestWorkbenchModel { @Test public void testPanelHierarchyInsert() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl("what.ever.panel.PresenterClass"); perspective.setName("perspective"); PanelDefinition westPanel = new PanelDefinitionImpl("what.ever.panel.PresenterClass"); PanelDefinition eastPanel = new PanelDefinitionImpl("what.ever.panel.PresenterClass"); PartDefinition part1 = new PartDefinitionImpl(new DefaultPlaceRequest("one")); PartDefinition part2 = new PartDefinitionImpl(new DefaultPlaceRequest("two")); perspective.getRoot().insertChild(CompassPosition.WEST, westPanel); perspective.getRoot().insertChild(CompassPosition.EAST, eastPanel); westPanel.addPart(part1); eastPanel.addPart(part2); assertTrue(part1.getParentPanel() == westPanel); assertTrue(westPanel.getParent() == perspective.getRoot()); // TODO: panel equality? assertTrue(part2.getParentPanel() == eastPanel); assertTrue(eastPanel.getParent() == perspective.getRoot()); assertTrue(perspective.getRoot().getParent() == null); } @Test public void testPanelHierarchyAppend() { PerspectiveDefinition perspective = new PerspectiveDefinitionImpl("what.ever.panel.PresenterClass"); perspective.setName("perspective"); PanelDefinition westPanel = new PanelDefinitionImpl("what.ever.panel.PresenterClass"); PanelDefinition eastPanel = new PanelDefinitionImpl("what.ever.panel.PresenterClass"); PartDefinition part1 = new PartDefinitionImpl(new DefaultPlaceRequest("one")); PartDefinition part2 = new PartDefinitionImpl(new DefaultPlaceRequest("two")); perspective.getRoot().appendChild(CompassPosition.WEST, westPanel); perspective.getRoot().appendChild(CompassPosition.EAST, eastPanel); westPanel.addPart(part1); eastPanel.addPart(part2); assertTrue(part1.getParentPanel() == westPanel); assertTrue(westPanel.getParent() == perspective.getRoot()); // TODO: panel equality? assertTrue(part2.getParentPanel() == eastPanel); assertTrue(eastPanel.getParent() == perspective.getRoot()); assertTrue(perspective.getRoot().getParent() == null); } /** * Parent traversal {@link PanelDefinition#getParent()} does yield IllegalStateException when the panel is not * part of a hierarchy. There might be two reasons for this: Either the implicit parent/child wiring is broken * or the explicit perspective setup is not yet completed. */ @Test(expected = IllegalStateException.class) public void testDetachedPanels() { PanelDefinition westPanel = new PanelDefinitionImpl("what.ever.panel.PresenterClass"); PartDefinition part1 = new PartDefinitionImpl(new DefaultPlaceRequest("one")); westPanel.addPart(part1); assertTrue(part1.getParentPanel() == westPanel); westPanel.getParent(); // does blow up } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/workbench/model/impl/PanelDefinitionImplTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import org.junit.Before; import org.junit.Test; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.model.PartDefinition; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class PanelDefinitionImplTest { private PanelDefinitionImpl panelDefinition; private PanelDefinitionImpl otherPanel; private PartDefinition part; private PlaceRequest placeRequest; private PanelDefinitionImpl parent; @Before public void setUp() throws Exception { panelDefinition = new PanelDefinitionImpl(); otherPanel = new PanelDefinitionImpl(); parent = new PanelDefinitionImpl(); placeRequest = mock(PlaceRequest.class); part = new PartDefinitionImpl(placeRequest); } @Test(expected = IllegalStateException.class) public void settingTwoDifferentParentsShouldThrowException() throws Exception { panelDefinition.setParent(otherPanel); panelDefinition.setParent(parent); } @Test public void addPartTest() throws Exception { assertFalse(panelDefinition.getParts().contains(part)); panelDefinition.addPart(part); assertTrue(panelDefinition.getParts().contains(part)); } @Test public void addPartToADifferentPanelChangePanel() throws Exception { assertFalse(panelDefinition.getParts().contains(part)); panelDefinition.addPart(part); assertTrue(panelDefinition.getParts().contains(part)); otherPanel.addPart(part); assertTrue(otherPanel.getParts().contains(part)); assertEquals(otherPanel, part.getParentPanel()); assertFalse(panelDefinition.getParts().contains(part)); } @Test public void addPartTwiceShouldWork() throws Exception { assertFalse(panelDefinition.getParts().contains(part)); panelDefinition.addPart(part); panelDefinition.addPart(part); assertTrue(panelDefinition.getParts().contains(part)); } @Test public void partShouldNotBePresentAfterRemoval() throws Exception { panelDefinition.addPart(part); assertNotNull(part.getParentPanel()); assertTrue(panelDefinition.getParts().contains(part)); panelDefinition.removePart(part); assertNull(part.getParentPanel()); assertFalse(panelDefinition.getParts().contains(part)); } @Test public void removeNonexistentPartShouldDoNothingAndReturnFalse() throws Exception { boolean result = panelDefinition.removePart(part); assertEquals(false, result); } @Test public void widthShouldNotRevertOnceSet() throws Exception { assertNull(panelDefinition.getWidth()); panelDefinition.setWidth(1234); panelDefinition.setWidth(null); assertEquals((Integer) 1234, panelDefinition.getWidth()); } @Test public void heightShouldNotRevertOnceSet() throws Exception { assertNull(panelDefinition.getHeight()); panelDefinition.setHeight(1234); panelDefinition.setHeight(null); assertEquals((Integer) 1234, panelDefinition.getHeight()); } @Test public void appendChildShouldAddPanelToChildren() { panelDefinition.appendChild(otherPanel); assertTrue(panelDefinition.getChildren().contains(otherPanel)); assertEquals(panelDefinition, otherPanel.getParent()); } @Test public void appendChildToPanelTwiceShouldWork() { panelDefinition.appendChild(otherPanel); assertTrue(panelDefinition.getChildren().contains(otherPanel)); panelDefinition.appendChild(otherPanel); assertTrue(panelDefinition.getChildren().contains(otherPanel)); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/workbench/model/impl/PartDefinitionImplTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.impl; import java.util.HashSet; import org.junit.Before; import org.junit.Test; import org.uberfire.mvp.PlaceRequest; import org.uberfire.workbench.model.PanelDefinition; import org.uberfire.workbench.model.PartDefinition; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class PartDefinitionImplTest { private PartDefinitionImpl part; private PanelDefinition parent; private PanelDefinition anotherParent; @Before public void setUp() throws Exception { PlaceRequest placeRequest = mock(PlaceRequest.class); part = new PartDefinitionImpl(placeRequest); parent = new PanelDefinitionImpl(); anotherParent = new PanelDefinitionImpl(); } @Test(expected = IllegalStateException.class) public void defineParentPanelWithOldParent() throws Exception { PanelDefinitionImpl parentMock = createParentMock(); part.setParentPanel(parentMock); part.setParentPanel(anotherParent); } @Test(expected = IllegalStateException.class) public void defineParentPanelWithOldParentWithoutPart() throws Exception { parent = createParentMock(); part.setParentPanel(parent); when(parent.getParts()).thenReturn(new HashSet()); PanelDefinitionImpl anotherParent = createParentMock(); part.setParentPanel(anotherParent); } private PanelDefinitionImpl createParentMock() { PanelDefinitionImpl parentMock = mock(PanelDefinitionImpl.class); HashSet mockSet = new HashSet(); mockSet.add(part); when(parentMock.getParts()).thenReturn(mockSet); return parentMock; } @Test public void defineParentPanel() throws Exception { PanelDefinitionImpl parentMock = createParentMock(); part.setParentPanel(parentMock); assertEquals(parentMock, part.getParentPanel()); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/workbench/model/menu/TestMenuSyntax.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu; /** * */ public class TestMenuSyntax { public static Object main(final String... args) { return MenuFactory .newContributedMenu("x") .contributeTo("xx") .submenu("xx") .menu("cc") .respondsWith(null) .endMenu() .endMenus() .endMenu(). newTopLevelMenu("") .submenu("") .menu("xx") .respondsWith(null) .endMenu() .menu("x") .submenu("xxx") .menu("xx") .respondsWith(null) .endMenu() .endMenus() .submenu("xxx") .menu("xx") .respondsWith(null) .endMenu() .endMenus() .endMenu() .endMenus() .endMenu() .newTopLevelMenu("x") .respondsWith(null) .endMenu() .newTopLevelMenu("x") .submenu("x") .menu("x") .respondsWith(null) .endMenu() .endMenus() .endMenu() .newTopLevelMenu("xx") .respondsWith(null) .endMenu() .newTopLevelMenu("xx") .withItems(null) .endMenu() .newContributedMenu("x") .contributeTo("xx") .submenu("xx") .menu("cc") .respondsWith(null) .endMenu() .endMenus() .endMenu() .build(); } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/workbench/model/menu/impl/TestBehavior.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.model.menu.impl; import org.junit.Test; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.menu.MenuGroup; import org.uberfire.workbench.model.menu.MenuItem; import org.uberfire.workbench.model.menu.MenuItemCommand; import org.uberfire.workbench.model.menu.MenuPosition; import org.uberfire.workbench.model.menu.Menus; import static org.assertj.core.api.Assertions.assertThat; import static org.uberfire.workbench.model.menu.MenuFactory.newTopLevelMenu; public class TestBehavior { private static Command DUMMY = new Command() { @Override public void execute() { } }; @Test public void testSimpleMenu() { final Menus menus = newTopLevelMenu("File") .position(MenuPosition.RIGHT) .menus() .menu("Save") .order(2) .respondsWith(DUMMY) .endMenu() .menu("Close") .respondsWith(DUMMY) .endMenu() .endMenus() .endMenu().build(); assertThat(menus).isNotNull(); assertThat(menus.getItems()).isNotNull().hasSize(1); assertThat(menus.getItems().get(0)).isNotNull(); assertThat(menus.getItems().get(0)).isInstanceOf(MenuGroup.class); assertThat(menus.getItems().get(0).getPosition()).isEqualTo(MenuPosition.RIGHT); assertThat(menus.getItems().get(0).getCaption()).isEqualTo("File"); assertThat(((MenuGroup) menus.getItems().get(0)).getItems()).hasSize(2); { final MenuItem menuItem = ((MenuGroup) menus.getItems().get(0)).getItems().get(0); assertThat(menuItem).isNotNull(); assertThat(menuItem.getCaption()).isEqualTo("Save"); assertThat(menuItem.getOrder()).isEqualTo(2); } { final MenuItem menuItem = ((MenuGroup) menus.getItems().get(0)).getItems().get(1); assertThat(menuItem).isNotNull(); assertThat(menuItem.getCaption()).isEqualTo("Close"); } } @Test public void testSimpleNestedMenu() { final Menus menus = newTopLevelMenu("File") .menus() .menu("Operations") .menus() .menu("Save") .respondsWith(DUMMY) .endMenu() .menu("Close") .respondsWith(DUMMY) .endMenu() .endMenus() .endMenu() .endMenus() .endMenu() .newTopLevelMenu("Explore") .respondsWith(DUMMY) .endMenu() .build(); assertThat(menus).isNotNull(); assertThat(menus.getItems()).isNotNull().hasSize(2); { assertThat(menus.getItems().get(0)).isNotNull(); assertThat(menus.getItems().get(0)).isInstanceOf(MenuGroup.class); assertThat(menus.getItems().get(0).getCaption()).isEqualTo("File"); assertThat(((MenuGroup) menus.getItems().get(0)).getItems()).hasSize(1); { final MenuItem menuItem = ((MenuGroup) menus.getItems().get(0)).getItems().get(0); assertThat(menuItem).isNotNull(); assertThat(menuItem.getCaption()).isEqualTo("Operations"); assertThat(menuItem).isInstanceOf(MenuGroup.class); { final MenuItem subMenuItem = ((MenuGroup) menuItem).getItems().get(0); assertThat(subMenuItem).isNotNull(); assertThat(subMenuItem.getCaption()).isEqualTo("Save"); } { final MenuItem subMenuItem = ((MenuGroup) menuItem).getItems().get(1); assertThat(subMenuItem).isNotNull(); assertThat(subMenuItem.getCaption()).isEqualTo("Close"); } } assertThat(menus.getItems().get(1)).isNotNull(); assertThat(menus.getItems().get(1)).isInstanceOf(MenuItemCommand.class); assertThat(menus.getItems().get(1).getCaption()).isEqualTo("Explore"); } } } ================================================ FILE: uberfire-api/src/test/java/org/uberfire/workbench/type/FileNameUtilTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.type; import org.junit.Test; import org.uberfire.backend.vfs.Path; import static org.junit.Assert.assertNull; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.uberfire.workbench.type.FileNameUtil.removeExtension; import static org.junit.Assert.assertEquals; public class FileNameUtilTest { @Test public void removeExtensionFromFileNameTest() { assertNull(removeExtension((String) null, ".java")); assertEquals("file.java", removeExtension("file.java", null)); assertEquals("file.java", removeExtension("file.java", "")); assertEquals("file", removeExtension("file.java", "java")); } @Test public void removeExtensionFromPathTest() { final Path path = mock(Path.class); doReturn("file.java").when(path).getFileName(); assertNull(removeExtension((Path) null, ".java")); assertEquals("file.java", removeExtension(path, (String) null)); assertEquals("file.java", removeExtension(path, "")); assertEquals("file", removeExtension(path, "java")); } @Test public void removeResourceTypeDefinitionSuffixFromPathTest() { final Path path = mock(Path.class); doReturn("file.java").when(path).getFileName(); final ResourceTypeDefinition resourceTypeDefinition = mock(ResourceTypeDefinition.class); doReturn("java").when(resourceTypeDefinition).getSuffix(); assertNull(removeExtension((Path) null, ".java")); assertEquals("file", removeExtension(path, resourceTypeDefinition)); } } ================================================ FILE: uberfire-backend/.gitignore ================================================ /target /local # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject /*.ipr /*.iws /*.iml # Repository wide ignore mac DS_Store files .DS_Store ================================================ FILE: uberfire-backend/pom.xml ================================================ 4.0.0 org.uberfire uberfire-parent 7.75.0-SNAPSHOT ../pom.xml uberfire-backend pom UberFire Backend uberfire-backend-api uberfire-backend-server uberfire-backend-cdi ================================================ FILE: uberfire-backend/uberfire-backend-api/.gitignore ================================================ /target /local # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject /*.ipr /*.iws /*.iml # Repository wide ignore mac DS_Store files .DS_Store ================================================ FILE: uberfire-backend/uberfire-backend-api/pom.xml ================================================ 4.0.0 org.uberfire uberfire-backend 7.75.0-SNAPSHOT uberfire-backend-api jar UberFire Backend API UberFire Backend API org.uberfire uberfire-nio2-model org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-api org.uberfire uberfire-security-api org.uberfire uberfire-preferences-api org.jboss.errai errai-bus org.jboss.errai errai-common ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/authz/AuthorizationPolicyStorage.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.authz; import org.jboss.errai.security.shared.api.Group; import org.uberfire.security.authz.AuthorizationPolicy; /** * Provides methods to manipulate the AuthorizationPolicy instance stored into the Uberfire's virtual file system. */ public interface AuthorizationPolicyStorage { /** * Retrieves the current {@link AuthorizationPolicy} instance from the backend storage. * @return The stored {@link AuthorizationPolicy} instance or null if no policy exists. */ AuthorizationPolicy loadPolicy(); /** * Overwrites the content of the {@link AuthorizationPolicy} instance stored in the backend * by the contents of the instance passed as a parameter. * @param policy The authorization policy to store */ void savePolicy(AuthorizationPolicy policy); /** * Deletes the group from {@link AuthorizationPolicy} instance stored in the backend * @param policy The authorization policy to store * @param group Group instance */ void deletePolicyByGroup(Group group, AuthorizationPolicy policy); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/authz/AuthorizationService.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.authz; import org.jboss.errai.bus.server.annotations.Remote; import org.jboss.errai.security.shared.api.Group; import org.uberfire.security.authz.AuthorizationPolicy; /** * Provides methods to manipulate the AuthorizationPolicy instance stored in the Uberfire's virtual file system. */ @Remote public interface AuthorizationService { /** * Retrieves the current {@link AuthorizationPolicy} instance from the backend storage. * @return The stored {@link AuthorizationPolicy} instance */ AuthorizationPolicy loadPolicy(); /** * Overwrites the content of the {@link AuthorizationPolicy} instance stored in the backend * by the contents of the instance passed as a parameter. * @param policy The authorization policy to store */ void savePolicy(AuthorizationPolicy policy); /** * Deletes the group from {@link AuthorizationPolicy} instance stored in the backend * @param policy The authorization policy to store * @param group Group instance */ void deletePolicyByGroup(Group group , AuthorizationPolicy policy); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/authz/FileSystemResourceType.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.authz; import org.uberfire.security.ResourceType; /** * The file system resource type definition. */ public class FileSystemResourceType implements ResourceType { @Override public String getName() { return "filesystem"; } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/cdi/workspace/Workspace.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.cdi.workspace; /** * Represents a workspace. Every WorkspaceScoped bean instance has a relationship with a workspace. Workspaces right now * has a one-to-one relationship with a user, so I can't exists more than a workspace per user. */ public interface Workspace { /** * Returns the workspace name. At this moment is the username. * @return the workspace name. */ String getName(); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/events/AuthorizationPolicyDeployedEvent.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.events; import org.uberfire.security.authz.AuthorizationPolicy; /** * Event fired just after the deployment of the security policy. See backend implementation * AuthorizationPolicyDeployer. */ public class AuthorizationPolicyDeployedEvent { private AuthorizationPolicy policy; public AuthorizationPolicyDeployedEvent() { } public AuthorizationPolicyDeployedEvent(AuthorizationPolicy policy) { this.policy = policy; } public AuthorizationPolicy getPolicy() { return policy; } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/events/AuthorizationPolicySavedEvent.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.events; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.commons.clusterapi.Clustered; import org.uberfire.security.authz.AuthorizationPolicy; /** * Event fired just after the security policy is saved. See * {@link AuthorizationPolicyStorage#savePolicy(AuthorizationPolicy)} */ @Portable @Clustered public class AuthorizationPolicySavedEvent { private AuthorizationPolicy policy; public AuthorizationPolicySavedEvent() { } public AuthorizationPolicySavedEvent(@MapsTo("policy") AuthorizationPolicy policy) { this.policy = policy; } public AuthorizationPolicy getPolicy() { return policy; } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/fs/FileSystemService.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.fs; import org.jboss.errai.bus.server.annotations.Remote; @Remote public interface FileSystemService { Boolean isGitDefaultFileSystem(); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/PluginProcessor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.plugin; /** * A simple marker to keep track of all plugins processors. */ public interface PluginProcessor { /** * Checks if a plugin file has the valid extension * @param fileName the file name of the plugin */ static boolean isAValidPluginFileExtension(String fileName) { for (PluginProcessorType type : PluginProcessorType.values()) { if (fileName.endsWith(type.getExtension())) { return true; } } return false; } /** * Checks if this processor should process a given plugin * @param pluginName the name of the plugin, must not be null. */ boolean shouldProcess(String pluginName); /** * Removes all plugins from this processor. */ void removeAll(); /** * Processes a deployed plugin and optionally notifies clients * @param pluginName the name of the plugin, must not be null. * @param pluginDeploymentDir the directory to deploy plugin contents to, must not be null. * @param notifyClients trigger a event after plugin processing */ void process(String pluginName, String pluginDeploymentDir, boolean notifyClients); /** * Checks if a plugin with the given name is registered. * @param pluginName the name of the plugin, must not be null. * @return true if registered, otherwise false. */ boolean isRegistered(String pluginName); enum PluginProcessorType { GWT("nocache.js", false), PERSPECTIVE_EDITOR("layout.json", true), HTML_TEMPLATE(".html", true), JS(".js", true); private String extension; private boolean isRuntimePlugin; PluginProcessorType(String extension, boolean isRuntimePlugin) { this.extension = extension; this.isRuntimePlugin = isRuntimePlugin; } public String getExtension() { return extension; } public boolean isRuntimePlugin() { return isRuntimePlugin; } } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePlugin.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.plugin; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class RuntimePlugin { private PluginProcessor.PluginProcessorType type; private String pluginName; private String pluginContent; public RuntimePlugin() { } public RuntimePlugin(PluginProcessor.PluginProcessorType type, String pluginName, String pluginContent) { this.type = type; this.pluginName = pluginName; this.pluginContent = pluginContent; } public PluginProcessor.PluginProcessorType getType() { return type; } public String getPluginContent() { return pluginContent; } public String getPluginName() { return pluginName; } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginProcessor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.plugin; import java.util.Collection; /** * A simple marker to keep track of all runtime plugins processors. */ public interface RuntimePluginProcessor extends PluginProcessor { /** * Returns all available runtime plugins */ Collection getAvailableRuntimePlugins(); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/plugin/RuntimePluginService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.plugin; import java.util.Collection; import java.util.List; import org.jboss.errai.bus.server.annotations.Remote; @Remote public interface RuntimePluginService { Collection listFrameworksContent(); Collection listPluginsContent(); String getTemplateContent(final String url); String getRuntimePluginTemplateContent(String url); List getRuntimePlugins(); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/vfs/BasicFileAttributes.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.util.Date; public interface BasicFileAttributes { Date lastModifiedTime(); Date lastAccessTime(); Date creationTime(); boolean isRegularFile(); boolean isDirectory(); long size(); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/vfs/DirectoryStream.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import org.uberfire.java.nio.IOException; public interface DirectoryStream extends Iterable { public static interface Filter { boolean accept(T entry) throws IOException; } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/vfs/FileSystemFactory.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.jboss.errai.common.client.api.annotations.Portable; import static org.uberfire.backend.vfs.PathFactory.newPath; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * */ public final class FileSystemFactory { private FileSystemFactory() { } public static FileSystem newFS(final Map roots, final Set supportedViews) { return new FileSystemImpl(roots, supportedViews); } @Portable public static class FileSystemImpl implements FileSystem { private List rootDirectories = null; private Set supportedViews = null; public FileSystemImpl() { } public FileSystemImpl(final Map roots, final Set supportedViews) { checkNotNull("roots", roots); this.rootDirectories = new ArrayList(roots.size()); for (final Map.Entry entry : roots.entrySet()) { this.rootDirectories.add(newPath(entry.getValue(), entry.getKey())); } this.supportedViews = new HashSet(checkNotNull("supportedViews", supportedViews)); } @Override public List getRootDirectories() { return rootDirectories; } @Override public Set supportedFileAttributeViews() { return supportedViews; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); if (rootDirectories != null) { for (final Path rootDirectory : rootDirectories) { sb.append(rootDirectory.toString()); } } return sb.toString(); } } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/vfs/VFSLockService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.util.List; import org.jboss.errai.bus.server.annotations.Remote; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.backend.vfs.impl.LockResult; import org.uberfire.java.nio.IOException; /** * Provides methods to manage locks in UberFire's virtual file system. */ @Remote public interface VFSLockService { /** * Creates a lock file for the specified {@link Path}, to be held by the * currently authenticated user. If successful, this method associates the * created lock with the user's HTTP session so locks can automatically be * released when the session ends, expires or is destroyed. * @param path the path of the file or directory to lock. * @return the {@link LockResult}, indicating success or failure and * containing the last read {@link LockInfo}. * @throws IllegalArgumentException If the provided path is invalid or null. * @throws IOException If a lock file can't be written or an existing lock can't be * read. */ LockResult acquireLock(Path path) throws IllegalArgumentException, IOException; /** * Deletes the lock file for the specified {@link Path}. The requesting user * needs to own the lock for this operation to succeed. * @param path the path of the file or directory currently assumed locked. * @return the {@link LockResult}, indicating success or failure and * containing the last read {@link LockInfo}. * @throws IllegalArgumentException If the provided path is invalid or null. * @throws IOException If a lock file can't be deleted or an existing lock can't be * read. */ LockResult releaseLock(Path path) throws IllegalArgumentException, IOException; /** * Deletes the lock file for the specified {@link Path} even if the requesting * user does not own the lock. * @param path the path of the file or directory currently assumed locked. * @return the {@link LockResult}, indicating success or failure and * containing the last read {@link LockInfo}. * @throws IllegalArgumentException If the provided path is invalid or null. * @throws IOException If a lock file can't be deleted or an existing lock can't be * read. */ LockResult forceReleaseLock(Path path) throws IllegalArgumentException, IOException; /** * Retrieves the lock information for the specified {@link Path}. * @param path the path of the file or directory. * @return the {@link LockInfo} for the provided {@link Path}. * @throws IllegalArgumentException If the provided path is invalid or null. * @throws IOException If a lock file can't be read. */ LockInfo retrieveLockInfo(Path path) throws IllegalArgumentException, IOException; /** * Retrieves all locks for children (files or directories) of the provided * path. * @param path the path of the directory. * @param excludeOwnedLocks filters the resulting list so it doesn't contain locks owned * by the currently authenticated user. * @return the list of {@link LockInfo}s for children of the provided path * that are currently locked, or an empty list if no such locks * exist. * @throws IllegalArgumentException If the provided path is invalid or null. * @throws IOException If a lock file can't be read. */ List retrieveLockInfos(Path path, boolean excludeOwnedLocks) throws IllegalArgumentException, IOException; } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/vfs/VFSService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.util.Map; import org.jboss.errai.bus.server.annotations.Remote; import org.jboss.errai.common.client.api.interceptor.InterceptedCall; import org.uberfire.backend.vfs.impl.VFSCacheInterceptor; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.AtomicMoveNotSupportedException; import org.uberfire.java.nio.file.DirectoryNotEmptyException; import org.uberfire.java.nio.file.FileAlreadyExistsException; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import org.uberfire.java.nio.file.NoSuchFileException; import org.uberfire.java.nio.file.NotDirectoryException; import org.uberfire.java.nio.file.ProviderNotFoundException; @Remote public interface VFSService { Path get(String uri); DirectoryStream newDirectoryStream(final Path dir) throws IllegalArgumentException, NotDirectoryException, IOException; DirectoryStream newDirectoryStream(final Path dir, final DirectoryStream.Filter filter) throws IllegalArgumentException, NotDirectoryException, IOException; Path createDirectory(final Path dir) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException; Path createDirectories(final Path dir) throws UnsupportedOperationException, FileAlreadyExistsException, IOException; Path createDirectory(final Path dir, final Map attrs) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException; Path createDirectories(final Path dir, final Map attrs) throws UnsupportedOperationException, FileAlreadyExistsException, IOException; @InterceptedCall(VFSCacheInterceptor.class) Map readAttributes(final Path path) throws UnsupportedOperationException, IllegalArgumentException, IOException; void setAttributes(final Path path, final Map attrs) throws IllegalArgumentException, FileSystemAlreadyExistsException, ProviderNotFoundException; void delete(final Path path) throws IllegalArgumentException, NoSuchFileException, DirectoryNotEmptyException, IOException; boolean deleteIfExists(final Path path) throws IllegalArgumentException, DirectoryNotEmptyException, IOException; Path copy(final Path source, final Path target) throws UnsupportedOperationException, FileAlreadyExistsException, DirectoryNotEmptyException, IOException; Path move(final Path source, final Path target) throws UnsupportedOperationException, FileAlreadyExistsException, DirectoryNotEmptyException, AtomicMoveNotSupportedException, IOException; String readAllString(final Path path) throws IllegalArgumentException, NoSuchFileException, IOException; Path write(final Path path, final String content) throws IllegalArgumentException, IOException, UnsupportedOperationException; Path write(final Path path, final String content, final Map attrs) throws IllegalArgumentException, IOException, UnsupportedOperationException; boolean isRegularFile(final String uri); boolean isRegularFile(final Path path); boolean isDirectory(final String uri); boolean isDirectory(final Path path); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/vfs/impl/DirectoryStreamImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs.impl; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.jboss.errai.common.client.api.annotations.MapsTo; import org.jboss.errai.common.client.api.annotations.Portable; import org.uberfire.backend.vfs.DirectoryStream; import org.uberfire.backend.vfs.Path; @Portable public class DirectoryStreamImpl implements DirectoryStream { private List content; public DirectoryStreamImpl(@MapsTo("content") final List content) { this.content = new ArrayList(content); } @Override public Iterator iterator() { return new Iterator() { private int i = 0; @Override public boolean hasNext() { return i < content.size(); } @Override public Path next() { if (i < content.size()) { final Path result = content.get(i); i++; return result; } else { throw new NoSuchElementException(); } } @Override public void remove() { throw new UnsupportedOperationException(); } }; } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/backend/vfs/impl/VFSCacheInterceptor.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs.impl; import org.jboss.errai.bus.client.api.interceptor.RpcInterceptor; import org.jboss.errai.common.client.api.interceptor.RemoteCallContext; import org.uberfire.backend.vfs.PathFactory; public class VFSCacheInterceptor implements RpcInterceptor { @Override public void aroundInvoke(final RemoteCallContext context) { final Object o = context.getParameters()[0]; if (o instanceof PathFactory.PathImpl && ((PathFactory.PathImpl) o).getAttributes().size() > 0) { context.setResult(((PathFactory.PathImpl) o).getAttributes()); return; } context.proceed(); } } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/java/org/uberfire/workbench/services/WorkbenchServices.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.workbench.services; import java.util.Map; import java.util.Set; import org.jboss.errai.bus.server.annotations.Remote; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.SplashScreenFilter; /** * Workbench services */ @Remote public interface WorkbenchServices { void save(String perspectiveId, final PerspectiveDefinition perspective); void save(final SplashScreenFilter splashFilter); Set loadPerspectives(); PerspectiveDefinition loadPerspective(final String perspectiveId); void removePerspectiveState(final String perspectiveId); void removePerspectiveStates(); SplashScreenFilter loadSplashScreenFilter(final String filterName); Map loadDefaultEditorsMap(); void saveDefaultEditors(Map properties); boolean isWorkbenchOnCluster(); } ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/resources/META-INF/ErraiApp.properties ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ErraiApp.properties # # Do not remove, even if empty! # # This is a marker file. When it is detected inside a JAR or at the # top of any classpath, the subdirectories are scanned for deployable # components. As such, all Errai application modules in a project # should contain an ErraiApp.properties at the root of all classpaths # that you wish to be scanned. # # There are also some configuration options that can be set in this # file, although it is rarely necessary. See the documentation at # https://docs.jboss.org/author/display/ERRAI/ErraiApp.properties # for details. errai.marshalling.serializableTypes=org.uberfire.java.nio.IOException \ org.uberfire.java.nio.file.AccessDeniedException \ org.uberfire.java.nio.file.AtomicMoveNotSupportedException \ org.uberfire.java.nio.file.ClosedWatchServiceException \ org.uberfire.java.nio.file.DirectoryNotEmptyException \ org.uberfire.java.nio.file.FileAlreadyExistsException \ org.uberfire.java.nio.file.FileSystemAlreadyExistsException \ org.uberfire.java.nio.file.FileSystemException \ org.uberfire.java.nio.file.FileSystemNotFoundException \ org.uberfire.java.nio.file.InvalidPathException \ org.uberfire.java.nio.file.NoSuchFileException \ org.uberfire.java.nio.file.NotDirectoryException \ org.uberfire.java.nio.file.NotLinkException \ org.uberfire.java.nio.file.PatternSyntaxException \ org.uberfire.java.nio.file.ProviderNotFoundException ================================================ FILE: uberfire-backend/uberfire-backend-api/src/main/resources/org/uberfire/UberfireBackend.gwt.xml ================================================ ================================================ FILE: uberfire-backend/uberfire-backend-api/src/test/java/org/uberfire/backend/vfs/PathTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.vfs; import java.util.HashMap; import java.util.Map; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.uberfire.backend.vfs.PathFactory.newPath; public class PathTest { @Test public void generalState() { { final Path path = newPath("resource", "scheme://path/to/some/resource"); assertThat(path).isEqualTo(path); assertThat(path).isEqualTo(newPath("resource", "scheme://path/to/some/resource")); assertThat(path.hashCode()).isEqualTo(newPath("resource", "scheme://path/to/some/resource").hashCode()); assertThat(path.hashCode()).isEqualTo(path.hashCode()); } { final Path path = newPath("resource", "scheme://different/path/to/some/resource"); assertThat(path.equals(newPath("resource", "scheme://path/to/some/resource"))).isFalse(); assertThat(path.hashCode()).isNotEqualTo(newPath("resource", "scheme://path/to/some/resource").hashCode()); } { final Path path = newPath("resource", "scheme://different/path/to/some/resource"); assertThat(path.equals("something")).isFalse(); assertThat(path.equals(null)).isFalse(); } } @Test public void checkNPE() { final Map hashMap = new HashMap<>(); final Path path = newPath("defaultPackage", "default://guvnor-jcr2vfs-migration/defaultPackage/"); hashMap.put(path, "content"); assertThat(hashMap.get(path)).isEqualTo("content"); assertThat(hashMap.get(newPath("defaultPackage", "default://guvnor-jcr2vfs-migration/defaultPackage/"))).isEqualTo("content"); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/.gitignore ================================================ /target /local # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject /*.ipr /*.iws /*.iml # Repository wide ignore mac DS_Store files .DS_Store ================================================ FILE: uberfire-backend/uberfire-backend-cdi/pom.xml ================================================ 4.0.0 org.uberfire uberfire-backend 7.75.0-SNAPSHOT uberfire-backend-cdi jar UberFire Backend CDI Extensions UberFire Backend CDI Extensions jakarta.enterprise jakarta.enterprise.cdi-api provided jakarta.inject jakarta.inject-api provided jakarta.ws.rs jakarta.ws.rs-api provided jakarta.annotation jakarta.annotation-api provided jakarta.interceptor jakarta.interceptor-api provided jakarta.servlet jakarta.servlet-api provided org.uberfire uberfire-api org.uberfire uberfire-backend-api org.uberfire uberfire-commons javax.annotation javax.annotation-api org.uberfire uberfire-io org.uberfire uberfire-nio2-model com.google.guava guava xalan xalan xalan serializer org.jboss.errai errai-common org.jboss.errai errai-security-server org.kie.soup kie-soup-commons org.uberfire uberfire-backend-server provided jakarta.ejb jakarta.ejb-api provided jakarta.el jakarta.el-api test ch.qos.logback logback-classic test org.slf4j slf4j-api provided org.uberfire uberfire-preferences-api provided org.uberfire uberfire-preferences-backend provided org.uberfire uberfire-preferences-processors provided org.jboss.weld.se weld-se-core test org.jboss.arquillian.junit arquillian-junit-core test org.jboss.arquillian.junit arquillian-junit-container test org.jboss.arquillian.container arquillian-container-test-api test org.jboss.arquillian.container arquillian-weld-se-embedded-1.1 test org.jboss.shrinkwrap shrinkwrap-api test org.uberfire uberfire-nio2-jgit test io.netty netty-all org.uberfire uberfire-nio2-fs test org.jboss.errai errai-bus test org.jboss.errai errai-cdi-jboss test ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/AlternativeStarterBean.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi; import javax.annotation.PostConstruct; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.services.cdi.Startable; @Singleton @Startup public class AlternativeStarterBean { private static final Logger logger = LoggerFactory.getLogger(AlternativeStarterBean.class); private static final String EJB_METHOD = "ejb"; private static final String START_METHOD = System.getProperty("org.uberfire.start.method", "cdi"); @Inject private Instance startableBeans; @PostConstruct public void configure() { if (EJB_METHOD.equals(START_METHOD)) { logger.debug("Starting all beans defined as startable..."); if (!startableBeans.isUnsatisfied()) { for (Startable startableBean : startableBeans) { startableBean.start(); } } logger.info("All startable beans properly started"); } } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/SystemConfigProducer.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.net.URI; 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.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.event.Observes; import javax.enterprise.inject.Any; import javax.enterprise.inject.Default; import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.AfterDeploymentValidation; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.Extension; import javax.enterprise.inject.spi.InjectionPoint; import javax.enterprise.inject.spi.InjectionTarget; import javax.enterprise.inject.spi.ProcessAnnotatedType; import javax.enterprise.inject.spi.ProcessBean; import javax.enterprise.inject.spi.ProcessProducer; import javax.enterprise.inject.spi.WithAnnotations; import javax.enterprise.util.AnnotationLiteral; import javax.inject.Named; import javax.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.commons.lifecycle.PriorityDisposableRegistry; import org.uberfire.commons.services.cdi.Startable; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; import org.uberfire.commons.services.cdi.Veto; import org.uberfire.io.IOService; import org.uberfire.io.impl.IOServiceNio2WrapperImpl; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.base.FileSystemState; import org.uberfire.java.nio.file.FileStore; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import org.uberfire.java.nio.file.InvalidPathException; import org.uberfire.java.nio.file.LockableFileSystem; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.PathMatcher; import org.uberfire.java.nio.file.PatternSyntaxException; import org.uberfire.java.nio.file.WatchService; import org.uberfire.java.nio.file.attribute.UserPrincipalLookupService; import org.uberfire.java.nio.file.spi.FileSystemProvider; import org.uberfire.spaces.Space; import org.uberfire.spaces.SpacesAPI; public class SystemConfigProducer implements Extension { private static final Logger logger = LoggerFactory.getLogger(SystemConfigProducer.class); private static final String CDI_METHOD = "cdi"; private static final String START_METHOD = System.getProperty("org.uberfire.start.method", "cdi"); protected static final String SYSTEM = "system"; private final List startupEagerBeans = new LinkedList<>(); private final List startupBootstrapBeans = new LinkedList<>(); private final Comparator priorityComparator = (o1, o2) -> o1.priority - o2.priority; private boolean systemFSNotExists = true; private boolean pluginsFSNotExists = true; private boolean perspectivesFSNotExists = true; private boolean datasetsFSNotExists = true; private boolean navigationFSNotExists = true; private boolean ioStrategyBeanNotFound = true; public void processSystemFSProducer(@Observes ProcessProducer pp) { if (pp.getAnnotatedMember().getJavaMember().getName().equals("systemFS")) { systemFSNotExists = false; } } public void processPluginsFSProducer(@Observes ProcessProducer pp) { if (pp.getAnnotatedMember().getJavaMember().getName().equals("pluginsFS")) { pluginsFSNotExists = false; } } public void processPerspectivesFSProducer(@Observes ProcessProducer pp) { if (pp.getAnnotatedMember().getJavaMember().getName().equals("perspectivesFS")) { perspectivesFSNotExists = false; } } public void processDatasetsFSProducer(@Observes ProcessProducer pp) { if (pp.getAnnotatedMember().getJavaMember().getName().equals("datasetsFS")) { datasetsFSNotExists = false; } } public void processNavigationFSProducer(@Observes ProcessProducer pp) { if (pp.getAnnotatedMember().getJavaMember().getName().equals("navigationFS")) { navigationFSNotExists = false; } } public void processIOServiceProducer(@Observes ProcessProducer pp) { if (pp.getAnnotatedMember().getJavaMember().getName().equals("ioStrategy")) { ioStrategyBeanNotFound = false; } } public void processBean(@Observes final ProcessBean event) { if (event.getBean().getName() != null && event.getBean().getName().equals("systemFS")) { systemFSNotExists = false; } else if (event.getBean().getName() != null && event.getBean().getName().equals("pluginsFS")) { pluginsFSNotExists = false; } else if (event.getBean().getName() != null && event.getBean().getName().equals("perspectivesFS")) { perspectivesFSNotExists = false; } else if (event.getBean().getName() != null && event.getBean().getName().equals("datasetsFS")) { datasetsFSNotExists = false; } else if (event.getBean().getName() != null && event.getBean().getName().equals("navigationFS")) { navigationFSNotExists = false; } else if (event.getBean().getName() != null && event.getBean().getName().equals("ioStrategy")) { ioStrategyBeanNotFound = false; } if (event.getAnnotated().isAnnotationPresent(Startup.class) && (event.getAnnotated().isAnnotationPresent(ApplicationScoped.class) || event.getAnnotated().isAnnotationPresent(Singleton.class))) { final Startup startupAnnotation = event.getAnnotated().getAnnotation(Startup.class); final StartupType type = startupAnnotation.value(); final int priority = startupAnnotation.priority(); final Bean bean = event.getBean(); switch (type) { case EAGER: startupEagerBeans.add(new OrderedBean(bean, priority)); break; case BOOTSTRAP: startupBootstrapBeans.add(new OrderedBean(bean, priority)); break; } } else if (event.getAnnotated().isAnnotationPresent(Named.class) && (event.getAnnotated().isAnnotationPresent(ApplicationScoped.class) || event.getAnnotated().isAnnotationPresent(Singleton.class))) { final Named namedAnnotation = event.getAnnotated().getAnnotation(Named.class); if (namedAnnotation.value().endsWith("-startable")) { final Bean bean = event.getBean(); startupBootstrapBeans.add(new OrderedBean(bean, 10)); } } } public void afterDeploymentValidation(final @Observes AfterDeploymentValidation event, final BeanManager manager) { if (CDI_METHOD.equalsIgnoreCase(START_METHOD)) { //Force execution of Bootstrap bean's @PostConstruct methods first runPostConstruct(manager, startupBootstrapBeans); //Followed by execution of remaining Eager bean's @PostConstruct methods runPostConstruct(manager, startupEagerBeans); } } private void runPostConstruct(final BeanManager manager, final List orderedBeans) { //Sort first, by priority Collections.sort(orderedBeans, priorityComparator); for (OrderedBean ob : orderedBeans) { // the call to toString() is a cheat to force the bean to be initialized final Bean bean = ob.bean; manager.getReference(bean, bean.getBeanClass(), manager.createCreationalContext(bean)).toString(); } } void processAnnotatedType(@Observes @WithAnnotations(Veto.class) ProcessAnnotatedType pat) { pat.veto(); } void afterBeanDiscovery(@Observes final AfterBeanDiscovery abd, final BeanManager bm) { if (systemFSNotExists) { buildSystemFS(abd, bm); } if (ioStrategyBeanNotFound) { buildIOStrategy(abd, bm); } if (perspectivesFSNotExists) { buildPerspectivesFS(abd, bm); } if (datasetsFSNotExists) { buildDatasetsFS(abd, bm); } if (navigationFSNotExists) { buildNavigationFS(abd, bm); } if (pluginsFSNotExists) { buildPluginsFS(abd, bm); } if (!CDI_METHOD.equalsIgnoreCase(START_METHOD)) { buildStartableBean(abd, bm); } } void buildPluginsFS(final AfterBeanDiscovery abd, final BeanManager bm) { final InjectionTarget it = bm.createInjectionTarget(bm.createAnnotatedType(DummyFileSystem.class)); abd.addBean(createFileSystemBean(bm, it, SpacesAPI.DEFAULT_SPACE, "ioStrategy", "pluginsFS", "plugins")); } void buildPerspectivesFS(final AfterBeanDiscovery abd, final BeanManager bm) { final InjectionTarget it = bm.createInjectionTarget(bm.createAnnotatedType(DummyFileSystem.class)); abd.addBean(createFileSystemBean(bm, it, SpacesAPI.DASHBUILDER_SPACE, "ioStrategy", "perspectivesFS", "perspectives")); } void buildDatasetsFS(final AfterBeanDiscovery abd, final BeanManager bm) { final InjectionTarget it = bm.createInjectionTarget(bm.createAnnotatedType(DummyFileSystem.class)); abd.addBean(createFileSystemBean(bm, it, SpacesAPI.DASHBUILDER_SPACE, "ioStrategy", "datasetsFS", "datasets")); } void buildNavigationFS(final AfterBeanDiscovery abd, final BeanManager bm) { final InjectionTarget it = bm.createInjectionTarget(bm.createAnnotatedType(DummyFileSystem.class)); abd.addBean(createFileSystemBean(bm, it, SpacesAPI.DASHBUILDER_SPACE, "ioStrategy", "navigationFS", "navigation")); } void buildSystemFS(final AfterBeanDiscovery abd, final BeanManager bm) { final InjectionTarget it = bm.createInjectionTarget(bm.createAnnotatedType(DummyFileSystem.class)); abd.addBean(createFileSystemBean(bm, it, SpacesAPI.DEFAULT_SPACE, "configIO", "systemFS", SYSTEM)); } Bean createFileSystemBean(final BeanManager bm, final InjectionTarget it, final Space space, String ioService, String beanName, String fsName) { return new Bean() { @Override public Class getBeanClass() { return FileSystem.class; } @Override public Set getInjectionPoints() { return it.getInjectionPoints(); } @Override public String getName() { return beanName; } @Override public Set getQualifiers() { return new HashSet() {{ add(new AnnotationLiteral() { }); add(new AnnotationLiteral() { }); add(new NamedLiteral(beanName)); }}; } @Override public Class getScope() { return ApplicationScoped.class; } @Override public Set> getStereotypes() { return Collections.emptySet(); } @Override public Set getTypes() { return new HashSet() {{ add(FileSystem.class); add(LockableFileSystem.class); add(Object.class); }}; } @Override public boolean isAlternative() { return false; } @Override public boolean isNullable() { return false; } @Override public FileSystem create(CreationalContext ctx) { final SpacesAPI spaces = getSpaces(bm); final Bean bean = (Bean) bm.getBeans(ioService).iterator().next(); final CreationalContext _ctx = bm.createCreationalContext(bean); final IOService ioService = (IOService) bm.getReference(bean, IOService.class, _ctx); FileSystem fs; URI uri = resolveFSURI(spaces, space, fsName); try { fs = ioService.newFileSystem( uri, new HashMap() {{ put("init", Boolean.TRUE); put("internal", Boolean.TRUE); }}); } catch (FileSystemAlreadyExistsException e) { fs = ioService.getFileSystem(uri); } PriorityDisposableRegistry.register(beanName, fs); return fs; } @Override public void destroy(final FileSystem instance, final CreationalContext ctx) { try { instance.dispose(); PriorityDisposableRegistry.unregister(beanName); } catch (final Exception ex) { logger.warn(ex.getMessage(), ex); } ctx.release(); } }; } URI resolveFSURI(SpacesAPI spaces, Space space, String fsName) { return spaces.resolveFileSystemURI(SpacesAPI.Scheme.DEFAULT, space, fsName); } SpacesAPI getSpaces(BeanManager bm) { final Bean spacesBean = (Bean) bm.getBeans(SpacesAPI.class).iterator().next(); final CreationalContext spacesCtx = bm.createCreationalContext(spacesBean); return (SpacesAPI) bm.getReference(spacesBean, SpacesAPI.class, spacesCtx); } private void buildIOStrategy(final AfterBeanDiscovery abd, final BeanManager bm) { final InjectionTarget it = bm.createInjectionTarget(bm.createAnnotatedType(IOServiceNio2WrapperImpl.class)); abd.addBean(new Bean() { @Override public Class getBeanClass() { return IOService.class; } @Override public Set getInjectionPoints() { return it.getInjectionPoints(); } @Override public String getName() { return "ioStrategy"; } @Override public Set getQualifiers() { return new HashSet() {{ add(new AnnotationLiteral() { }); add(new AnnotationLiteral() { }); add(new NamedLiteral("ioStrategy")); }}; } @Override public Class getScope() { return ApplicationScoped.class; } @Override public Set> getStereotypes() { return Collections.emptySet(); } @Override public Set getTypes() { return new HashSet() {{ add(IOService.class); add(Object.class); }}; } @Override public boolean isAlternative() { return false; } @Override public boolean isNullable() { return false; } @Override public IOService create(CreationalContext ctx) { return new IOServiceNio2WrapperImpl(); } @Override public void destroy(final IOService instance, final CreationalContext ctx) { ctx.release(); } }); } private T getBean(BeanManager bm, Class clazz) { final Bean bean = (Bean) bm.getBeans(clazz).iterator().next(); return getBeanReference(bm, clazz, bean); } private T getBean(BeanManager bm, Class clazz, Annotation qualifier) { final Bean bean = (Bean) bm.getBeans(clazz, qualifier).iterator().next(); return getBeanReference(bm, clazz, bean); } private T getBeanReference(BeanManager bm, Class clazz, Bean bean) { final CreationalContext creationalContext = bm.createCreationalContext(bean); return (T) bm.getReference(bean, clazz, creationalContext); } private void buildStartableBean(final AfterBeanDiscovery abd, final BeanManager bm) { abd.addBean(new Bean() { @Override public Class getBeanClass() { return Startable.class; } @Override public Set getInjectionPoints() { return Collections.emptySet(); } @Override public String getName() { return "startablebean"; } @Override public Set getQualifiers() { return new HashSet() {{ add(new AnnotationLiteral() { }); add(new AnnotationLiteral() { }); }}; } @Override public Class getScope() { return ApplicationScoped.class; } @Override public Set> getStereotypes() { return Collections.emptySet(); } @Override public Set getTypes() { return new HashSet() {{ add(Startable.class); add(Object.class); }}; } @Override public boolean isAlternative() { return false; } @Override public boolean isNullable() { return false; } @Override public Startable create(CreationalContext ctx) { return new Startable() { @Override public int hashCode() { return super.hashCode(); } @Override public void start() { //Force execution of Bootstrap bean's @PostConstruct methods first runPostConstruct(bm, startupBootstrapBeans); //Followed by execution of remaining Eager bean's @PostConstruct methods runPostConstruct(bm, startupEagerBeans); } }; } @Override public void destroy(final Startable instance, final CreationalContext ctx) { ctx.release(); } }); } public static class DummyFileSystem implements FileSystem { private FileSystemState state = FileSystemState.NORMAL; @Override public FileSystemProvider provider() { return null; } @Override public boolean isOpen() { return false; } @Override public boolean isReadOnly() { return false; } @Override public String getSeparator() { return null; } @Override public Iterable getRootDirectories() { return null; } @Override public Iterable getFileStores() { return null; } @Override public Set supportedFileAttributeViews() { return null; } @Override public Path getPath(String first, String... more) throws InvalidPathException { return null; } @Override public PathMatcher getPathMatcher(String syntaxAndPattern) throws IllegalArgumentException, PatternSyntaxException, UnsupportedOperationException { return null; } @Override public UserPrincipalLookupService getUserPrincipalLookupService() throws UnsupportedOperationException { return null; } @Override public WatchService newWatchService() throws UnsupportedOperationException, IOException { return null; } @Override public String getName() { return "DummyFileSystem"; } @Override public void close() throws IOException { } @Override public void dispose() { } } private class OrderedBean { Bean bean; int priority; private OrderedBean(final Bean bean, final int priority) { this.bean = bean; this.priority = priority; } } public class NamedLiteral extends AnnotationLiteral implements Named { private final String value; public NamedLiteral(String value) { this.value = value; } @Override public String value() { return value; } } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/model/WorkspaceImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi.model; import org.uberfire.backend.cdi.workspace.Workspace; public class WorkspaceImpl implements Workspace { private final String name; public WorkspaceImpl(String name) { this.name = name; } @Override public String getName() { return this.name; } @Override public boolean equals(final Object obj) { if (obj instanceof WorkspaceImpl) { return this.getName() == ((WorkspaceImpl) obj).getName() || this.getName().equals(((WorkspaceImpl) obj).getName()); } else { return super.equals(obj); } } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = ~~result; return result; } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceExecutorService.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.backend.server.cdi.workspace; import java.util.Collection; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.enterprise.inject.Vetoed; import org.uberfire.workspace.WorkspaceContext; @Vetoed public class WorkspaceExecutorService implements ExecutorService { private WorkspaceNameResolver workspaceNameResolver; private ExecutorService executorService; public WorkspaceExecutorService() { } public WorkspaceExecutorService(WorkspaceNameResolver workspaceNameResolver, ExecutorService executorService) { this.workspaceNameResolver = workspaceNameResolver; this.executorService = executorService; } private String getWorkspaceName() { return this.getWorkspaceNameResolver().getWorkspaceName(); } @Override public void shutdown() { getExecutorService().shutdown(); } @Override public List shutdownNow() { return getExecutorService().shutdownNow(); } @Override public boolean isShutdown() { return getExecutorService().isShutdown(); } @Override public boolean isTerminated() { return getExecutorService().isTerminated(); } @Override public boolean awaitTermination(final long l, final TimeUnit timeUnit) throws InterruptedException { return getExecutorService().awaitTermination(l, timeUnit); } @Override public Future submit(final Callable callable) { return getExecutorService().submit(this.generateCallable(callable)); } @Override public Future submit(final Runnable runnable, final T t) { return getExecutorService().submit(this.generateRunnable(runnable), t); } @Override public Future submit(final Runnable runnable) { return getExecutorService().submit(this.generateRunnable(runnable)); } @Override public List> invokeAll(final Collection> collection) throws InterruptedException { return getExecutorService().invokeAll(collection); } @Override public List> invokeAll(final Collection> collection, final long l, final TimeUnit timeUnit) throws InterruptedException { return getExecutorService().invokeAll(collection, l, timeUnit); } @Override public T invokeAny(final Collection> collection) throws InterruptedException, ExecutionException { return getExecutorService().invokeAny(collection); } @Override public T invokeAny(final Collection> collection, final long l, final TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException { return getExecutorService().invokeAny(collection, l, timeUnit); } @Override public void execute(final Runnable runnable) { getExecutorService().execute(this.generateRunnable(runnable)); } private Runnable generateRunnable(final Runnable runnable) { String workspace = getWorkspaceName(); return () -> { WorkspaceContext.set(workspace); runnable.run(); }; } private Callable generateCallable(final Callable callable) { String workspace = getWorkspaceName(); return () -> { WorkspaceContext.set(workspace); return callable.call(); }; } private ExecutorService getExecutorService() { return executorService; } private WorkspaceNameResolver getWorkspaceNameResolver() { return this.workspaceNameResolver; } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceExecutorServiceProducer.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.backend.server.cdi.workspace; import java.util.concurrent.ExecutorService; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.enterprise.inject.Specializes; import javax.inject.Inject; import org.uberfire.commons.concurrent.ExecutorServiceProducer; import org.uberfire.commons.concurrent.Managed; public class WorkspaceExecutorServiceProducer extends ExecutorServiceProducer { private WorkspaceNameResolver workspaceNameResolver; @Inject public WorkspaceExecutorServiceProducer(WorkspaceNameResolver workspaceNameResolver) { this.workspaceNameResolver = workspaceNameResolver; } @Produces @ApplicationScoped @Managed @Specializes @Override public ExecutorService produceExecutorService() { return new WorkspaceExecutorService(workspaceNameResolver, this.getManagedExecutorService()); } protected WorkspaceNameResolver getWorkspaceNameResolver() { return workspaceNameResolver; } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceManager.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi.workspace; import java.util.NoSuchElementException; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.cdi.workspace.Workspace; import org.uberfire.backend.server.cdi.model.WorkspaceImpl; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; /** * Contains every workspace created in the application and the beans for those workspaces. * Beans are stored into a cache, with size and time expiration. */ @ApplicationScoped public class WorkspaceManager { private Logger logger = LoggerFactory.getLogger(WorkspaceManager.class); private WorkspaceManagerPreferences preferences; private ConcurrentHashMap> workspaces; public WorkspaceManager() { } @Inject public WorkspaceManager(WorkspaceManagerPreferences workspaceManagerPreferences) { this.preferences = workspaceManagerPreferences; } @PostConstruct public void initialize() { this.workspaces = new ConcurrentHashMap<>(); } /** * Returns a workspace, but if it does not exists, it creates a new one. * * @param name The name of the workspace. * @return The existent or the new workspace. */ public Workspace getOrCreateWorkspace(String name) { checkNotNull("name", name); Workspace workspace = new WorkspaceImpl(name); workspaces.computeIfAbsent(new WorkspaceImpl(name), w -> this.createCache()); return this.getWorkspace(name); } protected synchronized Cache createCache() { preferences.load(); final Cache cache = CacheBuilder.newBuilder() .maximumSize(preferences.getCacheMaximumSize()) .expireAfterAccess(preferences.getCacheExpirationTime(), TimeUnit.valueOf(preferences.getCacheExpirationUnit())) .removalListener(removalNotification -> { if (logger.isDebugEnabled()) { logger.debug("[{},{}] {}", removalNotification.getKey().toString(), removalNotification.getValue().toString(), removalNotification.getCause().toString()); } }) .build(); return cache; } /** * Returns a workspace. If the workspace does ont exists it throws {@link NoSuchElementException} * * @param name Workspace name * @return The workspace object */ public Workspace getWorkspace(String name) { checkNotNull("name", name); Optional optionalWorkspace = this.workspaces.keySet() .stream() .filter(w -> name.equals(w.getName())) .findAny(); return optionalWorkspace .orElseThrow(() -> new NoSuchElementException(String.format("Workspace <<%s>> not found", name))); } /** * Returns a bean based on a workspace and a bean name. If the bean does not exist, returns null * * @param workspace The workspace name. * @param beanName The bean name for that workspace. * @return the bean instance */ public T getBean(Workspace workspace, String beanName) { checkNotNull("workspace", workspace); checkNotNull("beanName", beanName); return (T) this.workspaces.get(workspace).getIfPresent(beanName); } /** * Put a bean instance into a Workspace. * * @param workspace The workspace to store beans * @param beanName The bean name * @param instance The bean instance */ public void putBean(Workspace workspace, String beanName, T instance) { try { checkNotNull("beanName", beanName); this.workspaces.get(workspace).get(beanName, () -> instance); } catch (ExecutionException e) { logger.error("An error ocurred trying to store bean <<{}>>", instance.getClass().getSimpleName(), e); } } /** * Deletes a workspace and its beans * * @param workspace the workspace to delete */ public void delete(final Workspace workspace) { this.workspaces.remove(workspace); } /** * Returns the workspace count * * @return the number of workspaces */ public int getWorkspaceCount() { return this.workspaces.size(); } /** * Return the beans count for a workspace * * @param workspace The workspace to count beans * @return The number of beans for a workspace */ public long getBeansCount(final Workspace workspace) { return this.workspaces.get(workspace).size(); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceManagerPreferences.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi.workspace; import java.util.concurrent.TimeUnit; import org.uberfire.preferences.shared.annotations.Property; import org.uberfire.preferences.shared.annotations.WorkbenchPreference; import org.uberfire.preferences.shared.bean.BasePreference; @WorkbenchPreference(identifier = "WorkspaceManagerPreferences", bundleKey = "WorkspaceManagerPreferences.Label") public class WorkspaceManagerPreferences implements BasePreference { @Property(bundleKey = "WorkspaceManagerPreferences.CacheMaximumSize") private int cacheMaximumSize; @Property(bundleKey = "WorkspaceManagerPreferences.CacheExpirationTime") private int cacheExpirationTime; @Property(bundleKey = "WorkspaceManagerPreferences.CacheExpirationUnit") private String cacheExpirationUnit; public WorkspaceManagerPreferences() { } @Override public WorkspaceManagerPreferences defaultValue(final WorkspaceManagerPreferences defaultValue) { defaultValue.cacheMaximumSize = 50; defaultValue.cacheExpirationTime = 30; defaultValue.cacheExpirationUnit = TimeUnit.MINUTES.toString(); return defaultValue; } public int getCacheMaximumSize() { return cacheMaximumSize; } public void setCacheMaximumSize(final int cacheMaximumSize) { this.cacheMaximumSize = cacheMaximumSize; } public int getCacheExpirationTime() { return cacheExpirationTime; } public void setCacheExpirationTime(final int cacheExpirationTime) { this.cacheExpirationTime = cacheExpirationTime; } public String getCacheExpirationUnit() { return this.cacheExpirationUnit; } public void setCacheExpirationUnit(final String cacheExpirationUnit) { this.cacheExpirationUnit = cacheExpirationUnit; } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceNameResolver.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.backend.server.cdi.workspace; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import org.uberfire.rpc.SessionInfo; import org.uberfire.workspace.WorkspaceContext; /** * Resolves Workspace name. At this moment the workspace name is based on usernames, so exists a workspace * per user. If there is no user session found the workspace name is called "global". This situation could happen during * some Server Side executions. */ @ApplicationScoped public class WorkspaceNameResolver { public static final String GLOBAL_WORKSPACE_NAME = "global"; private BeanManager beanManager; public WorkspaceNameResolver() { } @Inject public WorkspaceNameResolver(BeanManager beanManager) { this.beanManager = beanManager; } /** * Resolves the workspace name based on the user session. If not session detected returns "global". * @return the workspace name or "global". */ public String getWorkspaceName() { try { SessionInfo sessionInfo = getSessionInfo(); return sessionInfo.getIdentity().getIdentifier(); } catch (Exception e) { String name = WorkspaceContext.get(); if (name == null || name.isEmpty()) { return GLOBAL_WORKSPACE_NAME; } else { return name; } } } protected SessionInfo getSessionInfo() { final Bean bean = (Bean) this.beanManager.getBeans(SessionInfo.class).iterator().next(); final CreationalContext creationalContext = this.beanManager.createCreationalContext(bean); return (SessionInfo) this.beanManager.getReference(bean, SessionInfo.class, creationalContext); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceScopeContext.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi.workspace; import java.lang.annotation.Annotation; import javax.enterprise.context.spi.Context; import javax.enterprise.context.spi.Contextual; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.cdi.workspace.Workspace; /** * Workspace context. * Uses {@link WorkspaceManager} to create beans. Those beans must be annotated with * {@link WorkspaceScoped} annotation. Every bean has only one instance per workspace. */ public class WorkspaceScopeContext implements Context { private static Logger logger = LoggerFactory.getLogger(WorkspaceScopeContext.class); private final BeanManager beanManager; private WorkspaceNameResolver resolver; public WorkspaceScopeContext(BeanManager beanManager) { this.beanManager = beanManager; this.resolver = new WorkspaceNameResolver(beanManager); } @Override public Class getScope() { return WorkspaceScoped.class; } @Override public T get(final Contextual contextual, final CreationalContext creationalContext) { Bean bean = getBean(contextual); Workspace workspace = this.getWorkspaceManager().getOrCreateWorkspace(getWorkspaceName()); final T instance = getWorkspaceManager().getBean(workspace, bean.getBeanClass().getCanonicalName()); if (instance == null) { if (logger.isTraceEnabled()) { logger.trace("Creating Bean <<{}>> with creational context for workspace <<{}>>", bean.getBeanClass(), workspace.getName()); } final T created = bean.create(creationalContext); this.getWorkspaceManager().putBean(workspace, bean.getBeanClass().getCanonicalName(), created); return created; } else { if (logger.isTraceEnabled()) { logger.trace("Bean <<{}>> found for workspace <<{}>>", bean.getBeanClass(), workspace.getName()); } return instance; } } @Override public T get(final Contextual contextual) { Bean bean = getBean(contextual); Workspace workspace = this.getWorkspaceManager().getOrCreateWorkspace(getWorkspaceName()); if (logger.isTraceEnabled()) { logger.trace("Getting Bean <<{}>> for workspace <<{}>>", bean.getBeanClass(), workspace.getName()); } return this.getWorkspaceManager().getBean(workspace, bean.getBeanClass().getCanonicalName()); } private String getWorkspaceName() { return resolver.getWorkspaceName(); } @Override public boolean isActive() { return true; } private Bean getBean(final Contextual contextual) { return (Bean) contextual; } protected WorkspaceManager getWorkspaceManager() { return this.getBean(WorkspaceManager.class); } protected T getBean(Class clazz) { final Bean bean = (Bean) this.beanManager.getBeans(clazz).iterator().next(); final CreationalContext creationalContext = this.beanManager.createCreationalContext(bean); return (T) this.beanManager.getReference(bean, clazz, creationalContext); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceScoped.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi.workspace; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.enterprise.context.NormalScope; import javax.interceptor.InterceptorBinding; /** * Like @ApplicationScoped, this bean is going to have a single instance but * instead of living for the duration of the application it lives for the duration of the workspace and its cache. * So you can have two instances of the same bean in different workspaces at the same time. This bean is going to expire * depending on cache configuration. Check {@link WorkspaceManager}. */ @Documented @NormalScope @InterceptorBinding @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface WorkspaceScoped { } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/java/org/uberfire/backend/server/cdi/workspace/WorkspaceScopedExtension.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi.workspace; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.BeforeBeanDiscovery; import javax.enterprise.inject.spi.Extension; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Workspace Scoped CDI Extension to add WorkspaceScoped behavior into Uberfire */ public class WorkspaceScopedExtension implements Extension { private Logger logger = LoggerFactory.getLogger(WorkspaceScopedExtension.class); public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) { if (logger.isDebugEnabled()) { logger.debug("Before bean discovery, adding WosrkspaceScoped"); } bbd.addScope(WorkspaceScoped.class, true, false); } public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager beanManager) { if (logger.isDebugEnabled()) { logger.debug("After bean discovery, adding WorkspaceScopeContext"); } abd.addContext(new WorkspaceScopeContext(beanManager)); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/resources/META-INF/ErraiApp.properties ================================================ # # Copyright 2017 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension ================================================ org.uberfire.backend.server.cdi.SystemConfigProducer org.uberfire.backend.server.cdi.workspace.WorkspaceScopedExtension ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/java/org/uberfire/backend/server/cdi/SessionBasedBean.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi; import java.io.Serializable; import javax.ejb.Stateless; import javax.inject.Inject; @Stateless public class SessionBasedBean implements Serializable { @Inject private WorkspaceBuilderService service; public void build(String gav) { service.build(gav); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/java/org/uberfire/backend/server/cdi/SystemConfigProducerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi; import java.net.URI; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.InjectionTarget; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.spaces.SpacesAPIImpl; import org.uberfire.commons.lifecycle.PriorityDisposableRegistry; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.spaces.Space; import org.uberfire.spaces.SpacesAPI; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class SystemConfigProducerTest { SystemConfigProducer producer; BeanManager bm; Bean ioServiceBean; Set> configIOBeans = new HashSet<>(); IOService ioServiceMock; FileSystem fs; @Before public void setUp() throws Exception { producer = new SystemConfigProducer() { @Override SpacesAPI getSpaces(BeanManager bm) { return new SpacesAPIImpl(); } }; bm = mock(BeanManager.class); ioServiceBean = mock(Bean.class); configIOBeans.add(ioServiceBean); ioServiceMock = mock(IOService.class); fs = mock(FileSystem.class); } @Test public void systemConfigFSShouldUseGITasScheme() { SpacesAPI spacesAPI = mock(SpacesAPI.class); producer.resolveFSURI(spacesAPI, SpacesAPI.DEFAULT_SPACE, SystemConfigProducer.SYSTEM); verify(spacesAPI).resolveFileSystemURI(SpacesAPI.Scheme.DEFAULT, SpacesAPI.DEFAULT_SPACE, SystemConfigProducer.SYSTEM); } @Test public void createAndDestroyFSShouldRegisterUnregisterOnPriorityDisposableRegistry() { when(bm.getBeans("configIO")).thenReturn(configIOBeans); when(bm.getReference(eq(ioServiceBean), eq(IOService.class), any())) .thenReturn(ioServiceMock); when(ioServiceMock.newFileSystem(any(), any())) .thenReturn(fs); final Bean fileSystemBean = producer.createFileSystemBean(bm, mock(InjectionTarget.class), mock(Space.class), "configIO", "systemFS", SystemConfigProducer.SYSTEM); assertNull(PriorityDisposableRegistry.get("systemFS")); fileSystemBean.create(mock(CreationalContext.class)); assertNotNull(PriorityDisposableRegistry.get("systemFS")); fileSystemBean.destroy(fs, mock(CreationalContext.class)); assertNull(PriorityDisposableRegistry.get("systemFS")); } @Test public void systemFSShouldUseConfigIO() { SystemConfigProducer producerSpy = spy(producer); when(bm.createInjectionTarget(any())).thenReturn(mock(InjectionTarget.class)); producerSpy.buildSystemFS(mock(AfterBeanDiscovery.class), bm); verify(producerSpy).createFileSystemBean(eq(bm), any(), any(), eq("configIO"), eq("systemFS"), eq(SystemConfigProducer.SYSTEM)); } @Test public void pluginFSShouldUseIOStrategy() { SystemConfigProducer producerSpy = spy(producer); when(bm.createInjectionTarget(any())).thenReturn(mock(InjectionTarget.class)); producerSpy.buildPluginsFS(mock(AfterBeanDiscovery.class), bm); verify(producerSpy).createFileSystemBean(eq(bm), any(), any(), eq("ioStrategy"), eq("pluginsFS"), eq("plugins")); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/java/org/uberfire/backend/server/cdi/WorkspaceBuilderService.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi; import java.io.Serializable; /** * Just for testing purposes */ public interface WorkspaceBuilderService extends Serializable { void build(String gav); } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/java/org/uberfire/backend/server/cdi/WorkspaceBuilderServiceImpl.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi; import javax.inject.Inject; import org.jboss.errai.bus.server.annotations.Service; import org.slf4j.Logger; import org.uberfire.backend.server.cdi.workspace.WorkspaceScoped; /** * Just for testing purposes */ @Service @WorkspaceScoped public class WorkspaceBuilderServiceImpl implements WorkspaceBuilderService { //private Logger logger = LoggerFactory.getLogger( WorkspaceBuilderServiceImpl.class ); private Logger logger; public WorkspaceBuilderServiceImpl() { } @Inject public WorkspaceBuilderServiceImpl(Logger logger) { this.logger = logger; } @Override public void build(String gav) { try { logger.info("Building {} ...", gav); logger.info("Thread name: " + Thread.currentThread().getName()); Thread.currentThread().sleep(5000l); logger.info("Building finished {}", gav); } catch (InterruptedException e) { e.printStackTrace(); } } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/java/org/uberfire/backend/server/cdi/WorkspaceBuilderServiceTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.Extension; import javax.enterprise.inject.spi.InjectionPoint; import javax.inject.Inject; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.cdi.model.WorkspaceImpl; import org.uberfire.backend.server.cdi.workspace.WorkspaceManager; import org.uberfire.backend.server.cdi.workspace.WorkspaceScopedExtension; import org.uberfire.java.nio.fs.jgit.JGitFileSystemProvider; import org.uberfire.rpc.SessionInfo; import org.uberfire.rpc.impl.SessionInfoImpl; import static org.junit.Assert.*; @RunWith(Arquillian.class) public class WorkspaceBuilderServiceTest { @Deployment public static JavaArchive createDeployment() { System.setProperty("errai.marshalling.force_static_marshallers", Boolean.toString(true)); return ShrinkWrap.create(JavaArchive.class) .addPackages(true, "org.uberfire.preferences") .addPackages(true, "org.uberfire.backend.server.spaces") .addPackages(true, "org.uberfire.mvp") .addPackages(true, "org.uberfire.commons") .addPackages(true, "org.uberfire.backend.java") .addPackages(true, "org.uberfire.backend.server.cdi") .addPackages(true, "org.uberfire.backend.server.cluster") .addPackages(true, "org.uberfire.backend.server.io") .addPackages(true, "org.uberfire.java.nio.fs.jgit") .addClass(JGitFileSystemProvider.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") .addAsResource("META-INF/ErraiApp.properties", "ErraiApp.properties") .addAsManifestResource("META-INF/services/org.uberfire.java.nio.file.spi.FileSystemProvider", "services/org.uberfire.java.nio.file.spi.FileSystemProvider") .addAsServiceProvider(Extension.class, WorkspaceScopedExtension.class); } @Inject private WorkspaceManager workspaceManager; @Inject SessionBasedBean bean; @Inject WorkspaceBuilderService workspaceBuilderService; @Produces protected Logger createLogger(InjectionPoint injectionPoint) { return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getSimpleName()); } @Produces protected SessionInfo createSessionInfo(InjectionPoint injectionPoint) { return new SessionInfoImpl(new UserImpl(Thread.currentThread().getName())); } @Before public void setUp() { } @Test public void testConcurrentWorkspaceBeans() { String THREAD_NAME_2 = "ray vaughan"; String THREAD_NAME_1 = "hendrix"; CountDownLatch latch = new CountDownLatch(2); Thread thread1 = createThread(bean, "a:b:c", latch); Thread thread2 = createThread(bean, "d:e:f", latch); thread1.setName(THREAD_NAME_1); thread2.setName(THREAD_NAME_2); thread1.start(); thread2.start(); try { latch.await(7000, TimeUnit.SECONDS); final WorkspaceImpl workspace1 = (WorkspaceImpl) workspaceManager.getWorkspace(THREAD_NAME_1); assertEquals(1, workspaceManager.getBeansCount(workspace1)); final WorkspaceImpl workspace2 = (WorkspaceImpl) workspaceManager.getWorkspace(THREAD_NAME_2); assertEquals(1, workspaceManager.getBeansCount(workspace2)); assertEquals(2, workspaceManager.getWorkspaceCount()); } catch (InterruptedException e) { fail(); } } private Thread createThread(final SessionBasedBean bean, final String gav, final CountDownLatch latch) { return new Thread(() -> { bean.build(gav); latch.countDown(); }); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/java/org/uberfire/backend/server/cdi/workspace/WorkspaceManagerTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.cdi.workspace; import java.util.NoSuchElementException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.cdi.workspace.Workspace; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class WorkspaceManagerTest { @Mock private WorkspaceManagerPreferences preferences; private WorkspaceManager workspaceManager; @Before public void setUp() { when(preferences.getCacheExpirationTime()).thenReturn(10); when(preferences.getCacheExpirationUnit()).thenReturn("MINUTES"); when(preferences.getCacheMaximumSize()).thenReturn(3); this.workspaceManager = new WorkspaceManager(preferences); this.workspaceManager.initialize(); } @Test public void testWorkspaceNotFound() { assertThatThrownBy(() -> workspaceManager.getWorkspace("none")) .isInstanceOf(NoSuchElementException.class) .hasMessage("Workspace <> not found"); } @Test public void testCreateWorkspace() { final Workspace workspace = this.workspaceManager.getOrCreateWorkspace("hendrix"); assertEquals("hendrix", workspace.getName()); } @Test public void testWorkspaceCount() { this.workspaceManager.getOrCreateWorkspace("hendrix"); assertEquals(1, this.workspaceManager.getWorkspaceCount()); } @Test public void testDeleteWorkspace() { final Workspace workspace = this.workspaceManager.getOrCreateWorkspace("hendrix"); assertEquals(1, this.workspaceManager.getWorkspaceCount()); this.workspaceManager.delete(workspace); assertEquals(0, this.workspaceManager.getWorkspaceCount()); } @Test public void testStoreBeansWithCacheSizeEviction() { final Workspace workspace = this.workspaceManager.getOrCreateWorkspace("hendrix"); this.workspaceManager.putBean(workspace, "a", new Object()); this.workspaceManager.putBean(workspace, "b", new Object()); this.workspaceManager.putBean(workspace, "c", new Object()); this.workspaceManager.putBean(workspace, "d", new Object()); this.workspaceManager.putBean(workspace, "e", new Object()); assertEquals(3, this.workspaceManager.getBeansCount(workspace)); } @Test public void testGetBeanDoesNotExists() { final Workspace workspace = this.workspaceManager.getOrCreateWorkspace("hendrix"); assertNull(this.workspaceManager.getBean(workspace, "a")); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/java/org/uberfire/backend/server/cdi/workspace/WorkspaceNameResolverTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.uberfire.backend.server.cdi.workspace; import javax.enterprise.inject.spi.BeanManager; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.rpc.SessionInfo; import org.uberfire.workspace.WorkspaceContext; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class WorkspaceNameResolverTest { private WorkspaceNameResolver resolver; private BeanManager beanManager; @Before public void setUp() { WorkspaceContext.set(null); beanManager = mock(BeanManager.class); resolver = Mockito.spy(new WorkspaceNameResolver(beanManager)); } @Test public void testGlobalWorkspaceName() { String name = this.resolver.getWorkspaceName(); assertEquals(WorkspaceNameResolver.GLOBAL_WORKSPACE_NAME, name); } @Test public void testContextWorkspaceName() { final String user = "hendrix"; WorkspaceContext.set(user); String name = this.resolver.getWorkspaceName(); assertEquals(user, name); } @Test public void testUserInfoWorkspaceName() { final String user = "clapton"; SessionInfo sessionInfo = mock(SessionInfo.class); when(sessionInfo.getIdentity()).thenReturn(new UserImpl(user)); doReturn(sessionInfo).when(this.resolver).getSessionInfo(); String name = this.resolver.getWorkspaceName(); assertEquals(user, name); } } ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/resources/META-INF/ErraiApp.properties ================================================ # # Copyright 2017 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/resources/META-INF/services/org.uberfire.java.nio.file.spi.FileSystemProvider ================================================ # # Copyright 2017 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # org.uberfire.java.nio.fs.jgit.JGitFileSystemProvider org.uberfire.java.nio.fs.file.SimpleFileSystemProvider ================================================ FILE: uberfire-backend/uberfire-backend-cdi/src/test/resources/logback.xml ================================================ %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n ================================================ FILE: uberfire-backend/uberfire-backend-server/.gitignore ================================================ /target /local # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject /*.ipr /*.iws /*.iml # Repository wide ignore mac DS_Store files .DS_Store ================================================ FILE: uberfire-backend/uberfire-backend-server/pom.xml ================================================ 4.0.0 org.uberfire uberfire-backend 7.75.0-SNAPSHOT uberfire-backend-server jar UberFire Backend Server UberFire Backend Server org.uberfire uberfire-api org.uberfire uberfire-backend-api org.uberfire uberfire-structure-api org.uberfire uberfire-security-api org.uberfire uberfire-nio2-model jakarta.servlet jakarta.servlet-api provided jakarta.ws.rs jakarta.ws.rs-api provided org.uberfire uberfire-ssh-api org.uberfire uberfire-server org.ocpsoft.prettytime prettytime org.jdom jdom org.uberfire uberfire-io org.uberfire uberfire-commons org.kie.soup kie-soup-commons org.uberfire uberfire-nio2-api org.wildfly.security wildfly-elytron provided com.thoughtworks.xstream xstream jakarta.enterprise jakarta.enterprise.cdi-api provided org.jboss.errai errai-bus org.jboss.errai errai-cdi-server org.jboss.errai errai-marshalling org.jboss.errai errai-security-server org.jasypt jasypt xerces xercesImpl jakarta.ejb jakarta.ejb-api provided com.google.guava guava commons-io commons-io org.apache.commons commons-lang3 org.slf4j slf4j-api org.uberfire uberfire-testing-utils test org.uberfire uberfire-nio2-jgit test io.netty netty-all org.uberfire uberfire-nio2-fs test org.powermock powermock-module-junit4 test org.powermock powermock-api-mockito2 test org.slf4j slf4j-simple test ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/IOWatchServiceAllImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.concurrent.ExecutorService; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.uberfire.backend.server.io.watch.AbstractIOWatchService; import org.uberfire.commons.concurrent.Managed; import org.uberfire.commons.concurrent.Unmanaged; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.workbench.events.ResourceAddedEvent; import org.uberfire.workbench.events.ResourceBatchChangesEvent; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdatedEvent; @ApplicationScoped public class IOWatchServiceAllImpl extends AbstractIOWatchService { public IOWatchServiceAllImpl() { } @Inject public IOWatchServiceAllImpl(Event resourceBatchChanges, Event resourceUpdatedEvent, Event resourceRenamedEvent, Event resourceDeletedEvent, Event resourceAddedEvent, @Unmanaged ExecutorService executorService) { super(resourceBatchChanges, resourceUpdatedEvent, resourceRenamedEvent, resourceDeletedEvent, resourceAddedEvent, executorService); } @Override public boolean doFilter(WatchEvent event) { return false; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/IOWatchServiceNonDotImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.concurrent.ExecutorService; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.uberfire.backend.server.io.watch.AbstractIOWatchService; import org.uberfire.commons.concurrent.Unmanaged; import org.uberfire.java.nio.base.WatchContext; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.StandardWatchEventKind; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.workbench.events.ResourceAddedEvent; import org.uberfire.workbench.events.ResourceBatchChangesEvent; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdatedEvent; @ApplicationScoped public class IOWatchServiceNonDotImpl extends AbstractIOWatchService { public IOWatchServiceNonDotImpl() { } @Inject public IOWatchServiceNonDotImpl(Event resourceBatchChanges, Event resourceUpdatedEvent, Event resourceRenamedEvent, Event resourceDeletedEvent, Event resourceAddedEvent, @Unmanaged ExecutorService executorService) { super(resourceBatchChanges, resourceUpdatedEvent, resourceRenamedEvent, resourceDeletedEvent, resourceAddedEvent, executorService); } @Override public boolean doFilter(WatchEvent object) { final WatchContext context = (WatchContext) object.context(); if (object.kind().equals(StandardWatchEventKind.ENTRY_MODIFY)) { if (shouldFilter(context.getOldPath())) { return true; } } else if (object.kind().equals(StandardWatchEventKind.ENTRY_CREATE)) { if (shouldFilter(context.getPath())) { return true; } } else if (object.kind().equals(StandardWatchEventKind.ENTRY_RENAME)) { if (shouldFilter(context.getOldPath())) { return true; } } else if (object.kind().equals(StandardWatchEventKind.ENTRY_DELETE)) { if (shouldFilter(context.getOldPath())) { return true; } } return false; } boolean shouldFilter(Path path) { return path != null && path.getFileName() != null && path.getFileName().toString().startsWith("."); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/LockCleanupSessionListener.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.Set; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.io.ConfigIOServiceProducer; import org.uberfire.backend.server.util.Paths; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.NoSuchFileException; import org.uberfire.java.nio.file.Path; /** * Releases locks on session end. */ @WebListener public class LockCleanupSessionListener implements HttpSessionListener { private static final Logger logger = LoggerFactory.getLogger(LockCleanupSessionListener.class); @Override public void sessionCreated(HttpSessionEvent se) { } @Override public void sessionDestroyed(HttpSessionEvent se) { final ConfigIOServiceProducer ioServiceProducer = ConfigIOServiceProducer.getInstance(); final IOService ioService = ioServiceProducer.configIOService(); final FileSystem fileSystem = ioServiceProducer.configFileSystem(); @SuppressWarnings("unchecked") final Set locks = (Set) se.getSession() .getAttribute(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME); if (locks != null) { try { ioService.startBatch(fileSystem); for (LockInfo lock : locks) { try { final Path lockPath = Paths.convert(PathFactory.newLock(lock.getFile())); // Lock could have change ownership due to a forced lock release if (ioService.readAllString(lockPath).equals(lock.lockedBy())) { ioService.delete(lockPath); } } catch (NoSuchFileException e) { // Logging this with a lower level as it can happen when a user triggers // a forced lock release or when the locked file itself was deleted. logger.debug("Problem when releasing lock on session end (lock no longer exists): " + lock, e); } catch (Throwable t) { logger.warn("Problem when releasing lock on session end: " + lock, t); } } } finally { ioService.endBatch(); } } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/LockClientNotifier.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import javax.inject.Named; import org.uberfire.backend.server.util.Paths; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.io.IOService; import org.uberfire.java.nio.base.WatchContext; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.StandardWatchEventKind; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.java.nio.file.WatchKey; import org.uberfire.java.nio.file.WatchService; import org.uberfire.java.nio.file.api.FileSystemUtils; /** * Observes the creation and deletion of locks and notifies all connected * clients of the corresponding lock status changes. */ @ApplicationScoped @Startup public class LockClientNotifier { @Inject @Named("systemFS") private FileSystem fs; @Inject @Named("configIO") private IOService ioService; @Inject private Event lockEvent; private WatchService ws; private ExecutorService executorService = Executors.newSingleThreadExecutor(); private volatile boolean active = true; @PostConstruct private void init() { if (FileSystemUtils.isGitDefaultFileSystem()) { ws = fs.newWatchService(); executorService.submit(new Runnable() { @Override public void run() { observeAndNotifyClients(); } }); } } @PreDestroy private void shutdown() { executorService.shutdown(); active = false; if (ws != null) { ws.close(); } } private void observeAndNotifyClients() { while (active) { try { final WatchKey wk; try { wk = ws.take(); } catch (final Exception ex) { break; } final List> events = wk.pollEvents(); for (final WatchEvent event : events) { final boolean created = event.kind().equals(StandardWatchEventKind.ENTRY_CREATE); final boolean deleted = event.kind().equals(StandardWatchEventKind.ENTRY_DELETE); final WatchContext context = (WatchContext) event.context(); final Path path = (created) ? context.getPath() : context.getOldPath(); if (path != null && path.getFileName().toString().endsWith(PathFactory.LOCK_FILE_EXTENSION)) { final org.uberfire.backend.vfs.Path vfsLockPath = Paths.convert(path); final org.uberfire.backend.vfs.Path vfsPath = PathFactory.fromLock(vfsLockPath); if (created) { final String lockedBy = ioService.readAllString(path); lockEvent.fire(new LockInfo(true, lockedBy, vfsPath, vfsLockPath)); } else if (deleted) { lockEvent.fire(new LockInfo(false, null, vfsPath, vfsLockPath)); } } } if (!wk.reset()) { break; } } catch (final Exception ignored) { } } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/UserServicesBackendImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.ArrayList; import java.util.Collection; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import org.uberfire.backend.server.util.TextUtil; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Path; @ApplicationScoped public class UserServicesBackendImpl { @Inject @Named("configIO") private IOService ioService; @Inject @Named("systemFS") private FileSystem fileSystem; public Path buildPath(final String _userName, final String serviceType) { final String resultUserName = TextUtil.normalizeUserName(_userName); return fileSystem.getPath(resultUserName + "-uf-user", serviceType); } public Path buildPath(final String _userName, final String serviceType, final String relativePath) { final String resultUserName = TextUtil.normalizeUserName(_userName); if (relativePath != null && !"".equals(relativePath)) { return fileSystem.getPath(resultUserName + "-uf-user", serviceType, relativePath); } else { return fileSystem.getPath(resultUserName + "-uf-user", serviceType); } } public Collection getAllUsersData(final String serviceType, final String relativePath) { final Collection result = new ArrayList(); for (final Path path : fileSystem.getRootDirectories()) { final Path _path; if (relativePath != null && !"".equals(relativePath)) { _path = path.resolve(serviceType).resolve(relativePath); } else { _path = path.resolve(serviceType); } if (ioService.exists(_path)) { result.add(_path); } } return result; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/UserServicesImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.jboss.errai.security.shared.service.AuthenticationService; import org.uberfire.java.nio.file.Path; @ApplicationScoped public class UserServicesImpl { @Inject private AuthenticationService authService; @Inject private UserServicesBackendImpl userServicesBackend; public Path buildPath(final String serviceType) { return userServicesBackend.buildPath(authService.getUser().getIdentifier(), serviceType); } public Path buildPath(final String serviceType, final String relativePath) { return userServicesBackend.buildPath(authService.getUser().getIdentifier(), serviceType, relativePath); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/VFSLockServiceImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.inject.Named; import javax.servlet.http.HttpSession; import org.jboss.errai.bus.server.annotations.Service; import org.jboss.errai.bus.server.api.RpcContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.util.Paths; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.backend.vfs.VFSLockService; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.backend.vfs.impl.LockResult; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.DirectoryStream.Filter; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.NoSuchFileException; import org.uberfire.rpc.SessionInfo; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamedEvent; /** * Errai RPC endpoint exposing a {@link VFSLockService}. */ @Service @ApplicationScoped public class VFSLockServiceImpl implements VFSLockService { public static final String LOCK_SESSION_ATTRIBUTE_NAME = "uf-locks"; private static final Logger logger = LoggerFactory.getLogger(VFSLockServiceImpl.class); @Inject @Named("configIO") private IOService ioService; @Inject @Named("systemFS") private FileSystem fileSystem; @Inject private SessionInfo sessionInfo; @Override public LockResult acquireLock(final Path path) throws IllegalArgumentException, IOException, UnsupportedOperationException { try { ioService.startBatch(fileSystem); final String userId = sessionInfo.getIdentity().getIdentifier(); final LockInfo lockInfo = retrieveLockInfo(path); final LockResult result; if (lockInfo.isLocked() && !lockInfo.lockedBy().equals(userId)) { result = LockResult.failed(lockInfo); } else { ioService.write(Paths.convert(lockInfo.getLock()), userId); result = LockResult.acquired(path, userId); updateSession(result.getLockInfo()); } return result; } finally { ioService.endBatch(); } } @Override public LockResult releaseLock(final Path path) throws IllegalArgumentException, IOException { return releaseLock(path, false); } @Override public LockResult forceReleaseLock(final Path path) throws IllegalArgumentException, IOException { final String userId = sessionInfo.getIdentity().getIdentifier(); logger.info("User " + userId + " forced a lock release of: " + path.toURI()); return releaseLock(path, true); } private LockResult releaseLock(final Path path, final boolean force) throws IllegalArgumentException, IOException { try { ioService.startBatch(fileSystem); final LockInfo lockInfo = retrieveLockInfo(path); final LockResult result; if (lockInfo.isLocked()) { if (sessionInfo.getIdentity().getIdentifier().equals(lockInfo.lockedBy()) || force) { ioService.delete(Paths.convert(lockInfo.getLock())); updateSession(lockInfo, true); result = LockResult.released(path); } else { logger.error("Client requested to release a lock it doesn't hold: " + path.toURI()); throw new IOException("Not allowed"); } } else { result = LockResult.failed(lockInfo); } return result; } finally { ioService.endBatch(); } } @Override public LockInfo retrieveLockInfo(Path path) throws IllegalArgumentException, IOException { final Path vfsLock = PathFactory.newLock(path); final org.uberfire.java.nio.file.Path realLock = Paths.convert(vfsLock); if (ioService.exists(realLock)) { try { final String lockedBy = ioService.readAllString(realLock); return new LockInfo(true, lockedBy, path, vfsLock); } catch (NoSuchFileException nsfe) { // We want to avoid starting a batch (to ensure cluster-wide consistent reads) here since // this method is invoked very frequently. Therefore it's possible that the lock file // was deleted after the check to exists but before readAllString was invoked. There's // no need for special exception handling as it simply means that file is no longer locked. } } return new LockInfo(false, null, path, vfsLock); } @Override public List retrieveLockInfos(Path path, boolean excludeOwnedLocks) throws IllegalArgumentException, IOException { if (!Files.isDirectory(Paths.convert(path))) { return Collections.emptyList(); } final Path lockPath = PathFactory.newLockPath(path); final List locks = new ArrayList(); retrieveLocks(ioService.get(URI.create(lockPath.toURI())), locks); final List lockInfos = new LinkedList(); for (Path lock : locks) { final LockInfo lockInfo = retrieveLockInfo(PathFactory.fromLock(lock)); if (!excludeOwnedLocks || !sessionInfo.getIdentity().getIdentifier().equals(lockInfo.lockedBy())) { if (Files.exists(Paths.convert(lockInfo.getFile()))) { lockInfos.add(lockInfo); } } } return lockInfos; } private void retrieveLocks(final org.uberfire.java.nio.file.Path path, final List accu) { if (!Files.exists(path)) { return; } Filter filter = new Filter() { @Override public boolean accept(final org.uberfire.java.nio.file.Path entry) throws org.uberfire.java.nio.IOException { if (Paths.convert(entry).toURI().endsWith(PathFactory.LOCK_FILE_EXTENSION)) { accu.add(Paths.convert(entry)); } else if (Files.isDirectory(entry)) { retrieveLocks(ioService.get(entry.toUri()), accu); } return true; } }; Iterator it = ioService.newDirectoryStream(path, filter).iterator(); while (it.hasNext()) { it.next(); } } /** * Updates the user's session to track all currently held locks so we can * release locks on session expiry. * @param lockInfo the lock to update * @param remove true to remove the lock, false to add it */ private void updateSession(final LockInfo lockInfo, boolean remove) { final HttpSession session = RpcContext.getHttpSession(); if (session != null) { @SuppressWarnings("unchecked") Set locks = (Set) session.getAttribute(LOCK_SESSION_ATTRIBUTE_NAME); if (remove) { if (locks != null) { locks.remove(lockInfo); } } else { if (locks == null) { locks = new HashSet(); } locks.add(lockInfo); session.setAttribute(LOCK_SESSION_ATTRIBUTE_NAME, locks); } } } private void updateSession(final LockInfo lockInfo) { updateSession(lockInfo, false); } @SuppressWarnings("unused") private void onResourceDeleted(@Observes ResourceDeletedEvent res) { maybeDeleteLock(res.getPath()); } @SuppressWarnings("unused") private void onResourceRenamed(@Observes ResourceRenamedEvent res) { maybeDeleteLock(res.getPath()); } private void maybeDeleteLock(final Path path) { try { ioService.startBatch(fileSystem); final LockInfo lockInfo = retrieveLockInfo(path); if (lockInfo.isLocked()) { ioService.delete(Paths.convert(lockInfo.getLock())); } } finally { ioService.endBatch(); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/VFSServicesServerImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.net.URI; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.backend.server.util.Paths; import org.uberfire.backend.vfs.DirectoryStream; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.VFSService; import org.uberfire.backend.vfs.impl.DirectoryStreamImpl; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.AtomicMoveNotSupportedException; import org.uberfire.java.nio.file.DirectoryNotEmptyException; import org.uberfire.java.nio.file.FileAlreadyExistsException; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.NoSuchFileException; import org.uberfire.java.nio.file.NotDirectoryException; import org.uberfire.java.nio.file.ProviderNotFoundException; import org.uberfire.java.nio.file.attribute.FileTime; @Service @ApplicationScoped public class VFSServicesServerImpl implements VFSService { private final IOService ioService; // CDI Proxy. protected VFSServicesServerImpl() { this(null); } @Inject public VFSServicesServerImpl(final @Named("ioStrategy") IOService ioService) { this.ioService = ioService; } @Override public Path get(final String uri) { return Paths.convert(ioService.get(URI.create(uri))); } @Override public DirectoryStream newDirectoryStream(final Path dir) throws IllegalArgumentException, NotDirectoryException, IOException { final Iterator content = ioService.newDirectoryStream(Paths.convert(dir)).iterator(); return newDirectoryStream(content); } @Override public DirectoryStream newDirectoryStream(final Path dir, final DirectoryStream.Filter filter) throws IllegalArgumentException, NotDirectoryException, IOException { final Iterator content = ioService.newDirectoryStream(Paths.convert(dir), path -> filter.accept(Paths.convert(path))).iterator(); return newDirectoryStream(content); } @Override public Path createDirectory(final Path dir) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { return Paths.convert(ioService.createDirectory(Paths.convert(dir))); } @Override public Path createDirectories(final Path dir) throws UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { return Paths.convert(ioService.createDirectories(Paths.convert(dir))); } @Override public Path createDirectory(final Path dir, final Map attrs) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { return Paths.convert(ioService.createDirectory(Paths.convert(dir), attrs)); } @Override public Path createDirectories(final Path dir, final Map attrs) throws UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { return Paths.convert(ioService.createDirectories(Paths.convert(dir), attrs)); } @Override public Map readAttributes(final Path path) throws UnsupportedOperationException, IllegalArgumentException, IOException { final Map attributes = new HashMap(ioService.readAttributes(Paths.convert(path))); final Object _lastModifiedTime = attributes.get("lastModifiedTime"); if (_lastModifiedTime != null) { attributes.put("lastModifiedTime", new Date(((FileTime) _lastModifiedTime).toMillis())); } final Object _lastAccessTime = attributes.get("lastAccessTime"); if (_lastAccessTime != null) { attributes.put("lastAccessTime", new Date(((FileTime) _lastAccessTime).toMillis())); } final Object _creationTime = attributes.get("creationTime"); if (_creationTime != null) { attributes.put("creationTime", new Date(((FileTime) _creationTime).toMillis())); } return attributes; } @Override public void setAttributes(final Path path, final Map attrs) throws IllegalArgumentException, FileSystemAlreadyExistsException, ProviderNotFoundException { ioService.setAttributes(Paths.convert(path), attrs); } @Override public void delete(final Path path) throws IllegalArgumentException, NoSuchFileException, DirectoryNotEmptyException, IOException { ioService.delete(Paths.convert(path)); } @Override public boolean deleteIfExists(final Path path) throws IllegalArgumentException, DirectoryNotEmptyException, IOException { return ioService.deleteIfExists(Paths.convert(path)); } @Override public Path copy(final Path source, final Path target) throws UnsupportedOperationException, FileAlreadyExistsException, DirectoryNotEmptyException, IOException { return Paths.convert(ioService.copy(Paths.convert(source), Paths.convert(target))); } @Override public Path move(final Path source, final Path target) throws UnsupportedOperationException, FileAlreadyExistsException, DirectoryNotEmptyException, AtomicMoveNotSupportedException, IOException { return Paths.convert(ioService.move(Paths.convert(source), Paths.convert(target))); } @Override public String readAllString(final Path path) throws IllegalArgumentException, NoSuchFileException, IOException { return ioService.readAllString(Paths.convert(path)); } @Override public Path write(final Path path, final String content) throws IllegalArgumentException, IOException, UnsupportedOperationException { return Paths.convert(ioService.write(Paths.convert(path), content)); } @Override public Path write(final Path path, final String content, final Map attrs) throws IllegalArgumentException, IOException, UnsupportedOperationException { return Paths.convert(ioService.write(Paths.convert(path), content, attrs)); } @Override public boolean isRegularFile(final String uri) { return Files.isRegularFile(ioService.get(URI.create(uri))); } @Override public boolean isRegularFile(final Path path) { return Files.isRegularFile(Paths.convert(path)); } @Override public boolean isDirectory(final String uri) { return Files.isDirectory(ioService.get(URI.create(uri))); } @Override public boolean isDirectory(final Path path) { return Files.isDirectory(Paths.convert(path)); } private DirectoryStream newDirectoryStream(final Iterator iterator) { final List content = new LinkedList(); while (iterator.hasNext()) { content.add(Paths.convert(iterator.next())); } return new DirectoryStreamImpl(content); } private DirectoryStream.Filter convert(final DirectoryStream.Filter filter) { return new DirectoryStream.Filter() { @Override public boolean accept(final org.uberfire.java.nio.file.Path entry) throws IOException { return filter.accept(Paths.convert(entry)); } }; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/WebAppListener.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.mvp.Command; /** * It captures the webapp startup/destroy events and notifies the interested parties. */ @WebListener public class WebAppListener implements ServletContextListener { private static final Logger logger = LoggerFactory.getLogger(WebAppListener.class); private static List onStartupCommandList = new ArrayList<>(); private static List onDestroyCommandList = new ArrayList<>(); private static boolean initialized = false; private static boolean destroyed = false; public synchronized static void registerOnStartupCommand(Command command) { if (initialized) { command.execute(); } else { onStartupCommandList.add(command); } } public synchronized static void registerOnDestroyCommand(Command command) { if (destroyed) { command.execute(); } else { onDestroyCommandList.add(command); } } private synchronized static void setRootDir(String rootDir) { initialized = true; WebAppSettings.get().setRootDir(rootDir); logger.info("Root directory = " + rootDir); notifyCallbacks(onStartupCommandList); } private synchronized static void resetRootDir() { destroyed = true; WebAppSettings.get().setRootDir(null); notifyCallbacks(onDestroyCommandList); } private static void notifyCallbacks(List commandList) { for (Command command : commandList) { command.execute(); } } @Override public void contextInitialized(ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext(); String rootDir = servletContext.getRealPath("/"); setRootDir(rootDir); } @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { resetRootDir(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/WebAppSettings.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import org.apache.commons.lang3.StringUtils; /** * It holds some settings regarding the WebApp execution context like, for instance, the home directory where the * webapp has been deployed. */ public class WebAppSettings { private static WebAppSettings instance = null; String separator = FileSystems.getDefault().getSeparator(); private String rootDir = null; private WebAppSettings() { } public static WebAppSettings get() { if (instance == null) { instance = new WebAppSettings(); } return instance; } /** * Format a directory according to the file system separator */ protected String formatDirectory(String dir) { String result = StringUtils.replace(dir, "\\", separator); result = StringUtils.replace(result, "/", separator); // Remove the latest separator if (result.endsWith(separator)) { result = result.substring(0, dir.length() - 1); } return result; } /** * Retrieve the webapp's root directory => The directory where the container deploys the WAR content. * @return An absolute path. */ public String getRootDir() { return rootDir; } /** * Overwrites the webapp's root directory. *

        *

        This method is only intended to be called at bootstrap time by the * {@link WebAppListener}. Changing the root directory may cause the webapp to severely fail.

        */ public void setRootDir(String dir) { this.rootDir = dir != null ? dir.trim() : null; if (rootDir != null) { rootDir = formatDirectory(rootDir); } } /** * Calculate the absolute path of a directory placed under the the webapp's directory structure. * @param relativePath The relative path * @return An absolute path */ public Path getAbsolutePath(String... relativePath) { return rootDir != null ? Paths.get(rootDir, relativePath) : null; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/WorkbenchServicesImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import com.thoughtworks.xstream.XStream; import org.jboss.errai.bus.server.annotations.Service; import org.kie.soup.xstream.XStreamUtils; import org.uberfire.commons.cluster.ClusterParameters; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.FileVisitResult; import org.uberfire.java.nio.file.NoSuchFileException; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.SimpleFileVisitor; import org.uberfire.java.nio.file.StandardDeleteOption; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import org.uberfire.workbench.model.PerspectiveDefinition; import org.uberfire.workbench.model.SplashScreenFilter; import org.uberfire.workbench.services.WorkbenchServices; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.uberfire.java.nio.file.Files.walkFileTree; @Service @ApplicationScoped public class WorkbenchServicesImpl implements WorkbenchServices { public static final String PERSPECTIVE_EXTENSION = ".perspective"; private final XStream xs = XStreamUtils.createTrustingXStream(); private final ClusterParameters clusterParameters = new ClusterParameters(); @Inject @Named("configIO") private IOService ioService; @Inject private UserServicesImpl userServices; @Override public void save(final String perspectiveId, final PerspectiveDefinition perspective) { final String xml = xs.toXML(perspective); final Path perspectivePath = userServices.buildPath("perspectives", perspectiveId + PERSPECTIVE_EXTENSION); try { ioService.startBatch(perspectivePath.getFileSystem()); ioService.write(perspectivePath, xml); } finally { ioService.endBatch(); } } @Override public void save(SplashScreenFilter splashFilter) { final String xml = xs.toXML(splashFilter); final Path splashFilterPath = userServices.buildPath("splash", splashFilter.getName() + ".filter"); try { ioService.startBatch(splashFilterPath.getFileSystem()); ioService.write(splashFilterPath, xml); } finally { ioService.endBatch(); } } @Override public PerspectiveDefinition loadPerspective(final String perspectiveName) { final Path perspectivePath = userServices.buildPath("perspectives", perspectiveName + PERSPECTIVE_EXTENSION); if (ioService.exists(perspectivePath)) { final String xml = ioService.readAllString(perspectivePath); return (PerspectiveDefinition) xs.fromXML(xml); } return null; } @Override public Set loadPerspectives() { final Set result = new HashSet(); final Path perspectivesPath = userServices.buildPath("perspectives"); if (ioService.exists(perspectivesPath)) { walkFileTree(perspectivesPath, new SimpleFileVisitor() { public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { try { checkNotNull("file", file); checkNotNull("attrs", attrs); String fileName = file.getFileName().toString(); if (fileName.endsWith(PERSPECTIVE_EXTENSION) && attrs.isRegularFile()) { String perspectiveName = fileName.substring(0, fileName.indexOf(PERSPECTIVE_EXTENSION)); PerspectiveDefinition def = loadPerspective(perspectiveName); if (def != null) { result.add(def); } } } catch (final Exception ex) { return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; } }); } return result; } @Override public void removePerspectiveState(final String perspectiveId) { final Path perspectivePath = userServices.buildPath("perspectives", perspectiveId + ".perspective"); if (ioService.exists(perspectivePath)) { ioService.delete(perspectivePath); } } @Override public void removePerspectiveStates() { final Path perspectivesPath = userServices.buildPath("perspectives"); if (ioService.exists(perspectivesPath)) { try { ioService.startBatch(perspectivesPath.getFileSystem()); ioService.delete(perspectivesPath, StandardDeleteOption.NON_EMPTY_DIRECTORIES); } finally { ioService.endBatch(); } } } @Override public SplashScreenFilter loadSplashScreenFilter(String filterName) { final Path splashFilterPath = userServices.buildPath("splash", filterName + ".filter"); if (ioService.exists(splashFilterPath)) { final String xml = ioService.readAllString(splashFilterPath); return (SplashScreenFilter) xs.fromXML(xml); } return null; } @Override public Map loadDefaultEditorsMap() { final Map map = new HashMap(); try { final Path path = getPathToDefaultEditors(); if (ioService.exists(path)) { for (String line : ioService.readAllLines(path)) { if (!line.trim().startsWith("#")) { String[] split = line.split("="); map.put(split[0], split[1]); } } } return map; } catch (final NoSuchFileException e) { e.printStackTrace(); return map; } } @Override public void saveDefaultEditors(final Map properties) { final StringBuilder text = new StringBuilder(); for (String key : properties.keySet()) { text.append(String.format("%s=%s", key, properties.get(key))); } final Path path = getPathToDefaultEditors(); try { ioService.startBatch(path.getFileSystem()); ioService.write(path, text.toString()); } finally { ioService.endBatch(); } } @Override public boolean isWorkbenchOnCluster() { return clusterParameters.isAppFormerClustered(); } private Path getPathToDefaultEditors() { return userServices.buildPath("defaultEditors", null); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/authz/AuthorizationPolicyDeployer.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.jboss.errai.security.shared.api.Role; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.backend.events.AuthorizationPolicyDeployedEvent; import org.uberfire.backend.server.WebAppListener; import org.uberfire.backend.server.WebAppSettings; import org.uberfire.backend.server.security.RoleRegistry; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.impl.authz.AuthorizationPolicyBuilder; /** * An Uberfire's startup bean that scans the classpath looking for an authorization policy to deploy (a file named * security-policy.properties).

        *

        *

        If located, the policy file is loaded and passed along the {@link AuthorizationPolicyStorage}. The deployment * process is only executed once, so if a policy instance has been already stored then the deployment is left out. * The {@link AuthorizationPolicyMarshaller} class is used to read and convert the entries defined at * the security-policy.properties file into an {@link AuthorizationPolicy} instance.

        *

        *

        It is also possible to split the policy into multiple files. The * security-policy.properties file is always mandatory as it serves as a marker file. Alongside that file, * several security-module-?.properties files can be created. The split mechanism allows either for the * provision of just a single full standalone policy file or multiple module files each of them containing different * entries. The way those files are defined is always up to the application developer.

        */ @Startup @ApplicationScoped public class AuthorizationPolicyDeployer { private Logger logger = LoggerFactory.getLogger(AuthorizationPolicyDeployer.class); private AuthorizationPolicyStorage authzPolicyStorage; private PermissionManager permissionManager; private Event deployedEvent; public AuthorizationPolicyDeployer() { } @Inject public AuthorizationPolicyDeployer(AuthorizationPolicyStorage authzPolicyStorage, PermissionManager permissionManager, Event deployedEvent) { this.authzPolicyStorage = authzPolicyStorage; this.permissionManager = permissionManager; this.deployedEvent = deployedEvent; } @PostConstruct public void init() { WebAppListener.registerOnStartupCommand(this::deployPolicy); } public void deployPolicy() { Path policyDir = getPolicyDir(); deployPolicy(policyDir); } public Path getPolicyDir() { String rootDir = WebAppSettings.get().getRootDir(); return Paths.get(rootDir, "WEB-INF", "classes"); } public void deployPolicy(Path policyDir) { if (policyDir != null) { AuthorizationPolicy policy = authzPolicyStorage.loadPolicy(); if (policy == null) { policy = loadPolicy(policyDir); authzPolicyStorage.savePolicy(policy); logger.info("Security policy deployed"); // Ensure any role defined is available in the role registry for (Role role : policy.getRoles()) { RoleRegistry.get().registerRole(role.getName()); } // Notify the interested parties deployedEvent.fire(new AuthorizationPolicyDeployedEvent(policy)); } else { logger.info("Security policy active"); } // Set the active policy permissionManager.setAuthorizationPolicy(policy); } else { logger.info("Security policy not defined"); } } public AuthorizationPolicy loadPolicy(Path policyDir) { AuthorizationPolicyBuilder builder = permissionManager.newAuthorizationPolicy(); AuthorizationPolicyMarshaller marshaller = new AuthorizationPolicyMarshaller(); if (policyDir != null) { try { NonEscapedProperties properties = readPolicyProperties(policyDir); marshaller.read(builder, properties); } catch (IOException e) { logger.warn("Error loading security policy files", e); } } return builder.build(); } /** * Put all the policy files together into a single properties instance. * @param policyDir The source directory where to read the policy files from. * @return An {@link NonEscapedProperties} instance containing all the properties read from the policy files found * @throws IOException When an IO error occurs reading any of the policy files */ public NonEscapedProperties readPolicyProperties(Path policyDir) throws IOException { NonEscapedProperties properties = new NonEscapedProperties(); Files.list(policyDir) .filter(this::isPolicyFile) .forEach(path -> loadPolicyFile(properties, path)); return properties; } public boolean isPolicyFile(Path p) { String fileName = p.getName(p.getNameCount() - 1).toString(); return fileName.equals("security-policy.properties") || fileName.startsWith("security-module-"); } public void loadPolicyFile(NonEscapedProperties properties, Path path) { try { properties.load(path); } catch (IOException e) { logger.error("Security policy file load error: " + path, e); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/authz/AuthorizationPolicyMarshaller.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import java.util.Map; import java.util.Properties; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.Role; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.AuthorizationResult; import org.uberfire.security.authz.Permission; import org.uberfire.security.authz.PermissionCollection; import org.uberfire.security.impl.authz.AuthorizationPolicyBuilder; import static org.uberfire.backend.server.authz.AuthorizationPolicyMarshaller.ReadMode.DEFAULT_EXCLUDED; import static org.uberfire.backend.server.authz.AuthorizationPolicyMarshaller.ReadMode.DEFAULT_ONLY; import static org.uberfire.backend.server.authz.AuthorizationPolicyMarshaller.ReadMode.EVERYTHING; /** * Class used to convert an {@link AuthorizationPolicy} instance into/from a set of key/value pairs. *

        *

        The format of the key/value pairs is:

        *

        *

        "classifier.identifier.setting.extra=value"
        * * Where: *
          *
        • classifier = role|group
        • *
        • identifier = An existing role or group identifier (depending on the classifier type)
        • *
        • setting = home|priority|permission
        • *
        • extra = Extra setting information. Mandatory for instance to define the permission's name
        • *
        • value = The setting value (depends on the setting selected). Value expected per setting type: *
            *
          • home: An existing perspective identifier to redirect after login
          • *
          • priority: An integer indicating how priority is this role|group compared to others. Used for conflict resolution.
          • *
          • permission: A name representing a specific feature or capability over a given resource.
          • *
        • *
        * *

        For example: * *

         * #Role "admin"
         * role.admin.home=Home
         * role.admin.priority=10
         * role.admin.permission.perspective.read=true
         * role.admin.permission.perspective.read.Dashboard=false
         *
         * # Role "user"
         * role.user.home=Dashboard
         * role.user.priority=0
         * role.user.permission.perspective.read=false
         * role.user.permission.perspective.read.Home=true
         * role.user.permission.perspective.read.Dashboard=true
         * 
        */ public class AuthorizationPolicyMarshaller { private static final String DEFAULT = "default"; private static final String ROLE = "role"; private static final String GROUP = "group"; private static final String PERMISSION = "permission"; private static final String PRIORITY = "priority"; private static final String HOME = "home"; private static final String DESCRIPTION = "description"; /** * It reads all the entries from the collection of property files passed as a parameter. For every entry * a call to the proper {@link AuthorizationPolicyBuilder} method is executed. *

        *

        The valid format for the entries is specified in the class description.

        * @param builder The {@link AuthorizationPolicyBuilder} used to register every processed entry. * @param input The property objects containing the authz policy entries */ public void read(AuthorizationPolicyBuilder builder, Map... input) { for (Map m : input) { // Process the global/default settings first in order to make sure the rest overwrite them and not viceversa m.forEach((x, y) -> read(builder, x.toString(), y.toString(), DEFAULT_ONLY)); } for (Map m : input) { // Process the rest of the settings m.forEach((x, y) -> read(builder, x.toString(), y.toString(), DEFAULT_EXCLUDED)); } } /** * It reads key/value pair passed as a parameter and it calls to the right * {@link AuthorizationPolicyBuilder} method . *

        *

        The valid format for an key/value pair is specified in the class description.

        * @param builder The {@link AuthorizationPolicyBuilder} used to register the entry. * @param key The key to read * @param value The value to read */ public void read(AuthorizationPolicyBuilder builder, String key, String value) { this.read(builder, key, value, EVERYTHING); } /** * It reads key/value pair passed as a parameter and it calls to the right * {@link AuthorizationPolicyBuilder} method . *

        *

        The valid format for an key/value pair is specified in the class description.

        * @param builder The {@link AuthorizationPolicyBuilder} used to register the entry. * @param key The key to read * @param value The value to read * @param readMode The {@link ReadMode} determines if the specified key shall be included or excluded */ public void read(AuthorizationPolicyBuilder builder, String key, String value, ReadMode readMode) { Key keyObj = parse(key); if (isReadable(keyObj, readMode)) { read(builder, keyObj, value); } } /** * Check if a key object can be read according the given read mode. */ private boolean isReadable(Key keyObj, ReadMode readMode) { if (keyObj.isDefault() && DEFAULT_EXCLUDED.equals(readMode)) { return false; } if (!keyObj.isDefault() && DEFAULT_ONLY.equals(readMode)) { return false; } return true; } private void read(AuthorizationPolicyBuilder builder, Key keyObj, String value) { if (!keyObj.isDefault()) { if (keyObj.isRole()) { builder.role(keyObj.getRole()); } else if (keyObj.isGroup()) { builder.group(keyObj.getGroup()); } else { throw new IllegalArgumentException("Key must start either with 'role' or 'group': " + keyObj); } } String attr = keyObj.getAttributeType(); switch (attr) { case DESCRIPTION: builder.description(value); break; case HOME: builder.home(value); break; case PRIORITY: builder.priority(Integer.parseInt(value)); break; case PERMISSION: String permission = keyObj.getAttributeId(); if (permission.length() == 0) { throw new IllegalArgumentException("Permission is incomplete: " + keyObj); } boolean granted = Boolean.parseBoolean(value); builder.permission(permission, granted); break; default: throw new IllegalArgumentException("Unknown key: " + keyObj); } } /** * Dumps the {@link AuthorizationPolicy} instance passed as a parameter into the output {@link Properties} object * specified. *

        *

        The format for an key/value pair is specified in the class description.

        * @param policy The {@link AuthorizationPolicy} to serialize * @param out The {@link Properties} instance used as output */ public void write(AuthorizationPolicy policy, Map out) { write(policy.getHomePerspective(), out); write(policy.getPermissions(), out); for (Role subject : policy.getRoles()) { write(subject, policy.getHomePerspective(subject), out); write(subject, policy.getPriority(subject), out); write(subject, policy.getPermissions(subject), out); } for (Group subject : policy.getGroups()) { write(subject, policy.getHomePerspective(subject), out); write(subject, policy.getPriority(subject), out); write(subject, policy.getPermissions(subject), out); } } public void write(String homePerspectiveId, Map out) { String key = DEFAULT + "." + HOME; out.remove(key); if (homePerspectiveId != null) { out.put(key, homePerspectiveId); } } public void write(PermissionCollection permissions, Map out) { for (Permission p : permissions.collection()) { boolean granted = p.getResult() != null && p.getResult().equals(AuthorizationResult.ACCESS_GRANTED); String key = DEFAULT + "." + PERMISSION + "." + p.getName(); out.put(key, Boolean.toString(granted)); } } public void write(Role role, String homePerspectiveId, Map out) { String key = ROLE + "." + role.getName() + "." + HOME; out.remove(key); if (homePerspectiveId != null) { out.put(key, homePerspectiveId); } } public void write(Role role, int priority, Map out) { String key = ROLE + "." + role.getName() + "." + PRIORITY; out.put(key, Integer.toString(priority)); } public void write(Role role, PermissionCollection permissions, Map out) { for (Permission p : permissions.collection()) { boolean granted = p.getResult() != null && p.getResult().equals(AuthorizationResult.ACCESS_GRANTED); String key = ROLE + "." + role.getName() + "." + PERMISSION + "." + p.getName(); out.put(key, Boolean.toString(granted)); } } public void write(Group group, String homePerspectiveId, Map out) { String key = GROUP + "." + group.getName() + "." + HOME; out.remove(key); if (homePerspectiveId != null) { out.put(key, homePerspectiveId); } } public void write(Group group, int priority, Map out) { String key = GROUP + "." + group.getName() + "." + PRIORITY; out.put(key, Integer.toString(priority)); } public void write(Group group, PermissionCollection permissions, Map out) { for (Permission p : permissions.collection()) { boolean granted = p.getResult() != null && p.getResult().equals(AuthorizationResult.ACCESS_GRANTED); String key = GROUP + "." + group.getName() + "." + PERMISSION + "." + p.getName(); out.put(key, Boolean.toString(granted)); } } public void remove(Group group, AuthorizationPolicy policy, Map out) { write(policy, out); for (Group subject : policy.getGroups()) { if (group.getName().equals(subject.getName())) { remove(subject, out); remove(subject, policy.getPermissions(subject), out); } } } private void remove(Group group, Map out) { String homePerspectiveKey = GROUP + "." + group.getName() + "." + HOME; String priorityKey = GROUP + "." + group.getName() + "." + PRIORITY; out.remove(priorityKey); out.remove(homePerspectiveKey); } private void remove(Group group, PermissionCollection permissions, Map out) { for (Permission p : permissions.collection()) { String key = GROUP + "." + group.getName() + "." + PERMISSION + "." + p.getName(); out.remove(key); } } public Key parse(String key) { int _idx = 0; String _key = key.endsWith(".*") ? key.substring(0, key.length() - 2) : key; String[] tokens = _key.split("\\."); Key result = new Key(key); // Type if (_idx < tokens.length) { result.setType(tokens[_idx++]); } // Role / Group if (_idx < tokens.length) { if (result.isRole()) { result.setRole(tokens[_idx++]); } else if (result.isGroup()) { result.setGroup(tokens[_idx++]); } } // Attribute type if (_idx < tokens.length) { result.setAttributeType(tokens[_idx++]); } // Attribute id. if (_idx < tokens.length) { StringBuilder attrIdStr = new StringBuilder(); for (int i = _idx; i < tokens.length; i++) { if (i > _idx) { attrIdStr.append("."); } attrIdStr.append(tokens[i]); } result.setAttributeId(attrIdStr.toString()); } // Validate & return result.validate(); return result; } /** * Different ways to specify what are the target entries to read when calling the * {@link #read(AuthorizationPolicyBuilder, String, String, ReadMode)} method. */ public enum ReadMode { /** * Read only those entries classified as "default" */ DEFAULT_ONLY, /** * Read everything but the entries classified as "default" */ DEFAULT_EXCLUDED, /** * Read everything */ EVERYTHING } public class Key { String key = null; String type = null; String roleGroup = null; String attributeType = null; String attributeId = null; public Key(String key) { this.key = key; } public boolean isDefault() { return type != null && DEFAULT.equals(type); } public boolean isRole() { return type != null && ROLE.equals(type); } public boolean isGroup() { return type != null && GROUP.equals(type); } public String getRole() { return isRole() ? roleGroup : null; } public void setRole(String role) { this.roleGroup = role; } public String getGroup() { return isGroup() ? roleGroup : null; } public void setGroup(String group) { this.roleGroup = group; } public String getAttributeType() { return attributeType; } public void setAttributeType(String attributeType) { this.attributeType = attributeType; } public String getAttributeId() { return attributeId; } public void setAttributeId(String attributeId) { this.attributeId = attributeId; } public void setType(String type) { this.type = type; } @Override public String toString() { return key; } public void validate() throws IllegalStateException { if (type == null || (!DEFAULT.equals(type) && !ROLE.equals(type) && !GROUP.equals(type))) { throw new IllegalArgumentException("Key must start with [default|role|group]"); } if (isRole() && (roleGroup == null || roleGroup.length() == 0)) { throw new IllegalArgumentException("Role value is empty"); } if (isGroup() && (roleGroup == null || roleGroup.length() == 0)) { throw new IllegalArgumentException("Group value is empty"); } if (attributeType == null || attributeType.length() == 0) { throw new IllegalArgumentException("Empty attribute type not allowed: " + attributeType); } } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/authz/AuthorizationPolicyVfsStorage.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import java.io.StringReader; import java.io.StringWriter; import java.util.Date; import java.util.HashMap; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.inject.Named; import org.jboss.errai.security.shared.api.Group; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.base.options.CommentedOption; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import org.uberfire.java.nio.file.FileVisitResult; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.SimpleFileVisitor; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.impl.authz.AuthorizationPolicyBuilder; import org.uberfire.spaces.SpacesAPI; import static org.kie.soup.commons.validation.PortablePreconditions.checkNotNull; import static org.uberfire.java.nio.file.Files.walkFileTree; /** * An implementation that stores the authorization policy in property files. */ @ApplicationScoped public class AuthorizationPolicyVfsStorage implements AuthorizationPolicyStorage { private Logger logger = LoggerFactory.getLogger(AuthorizationPolicyVfsStorage.class); private PermissionManager permissionManager; private SpacesAPI spaces; private IOService ioService; private FileSystem fileSystem; private Path root; public static final String POLICY_FILE = "security-policy.properties"; public AuthorizationPolicyVfsStorage() { } @Inject public AuthorizationPolicyVfsStorage(@Named("configIO") IOService ioService, PermissionManager permissionManager, SpacesAPI spaces) { this.ioService = ioService; this.permissionManager = permissionManager; this.spaces = spaces; } @PostConstruct private synchronized void init() { initFileSystem(); } @Override public synchronized AuthorizationPolicy loadPolicy() { return loadPolicyFromVfs(); } @Override public synchronized void savePolicy(AuthorizationPolicy policy) { // Dump the entire authz policy into a properties map AuthorizationPolicyMarshaller marshaller = new AuthorizationPolicyMarshaller(); NonEscapedProperties entries = new NonEscapedProperties(); marshaller.write(policy, entries); savePolicyIntoVfs(entries, "system", "Save policy"); } // VFS operations public void initFileSystem() { try { fileSystem = ioService.newFileSystem(spaces.resolveFileSystemURI(SpacesAPI.Scheme.DEFAULT, SpacesAPI.DEFAULT_SPACE, "security"), new HashMap() {{ put("init", Boolean.TRUE); put("internal", Boolean.TRUE); }}); } catch (FileSystemAlreadyExistsException e) { fileSystem = ioService.getFileSystem(spaces.resolveFileSystemURI(SpacesAPI.Scheme.DEFAULT, SpacesAPI.DEFAULT_SPACE, "security")); } this.root = fileSystem.getRootDirectories().iterator().next(); } public AuthorizationPolicy loadPolicyFromVfs() { Path authzPath = getAuthzPath(); if (!ioService.exists(authzPath)) { return null; } AuthorizationPolicyBuilder builder = permissionManager.newAuthorizationPolicy(); AuthorizationPolicyMarshaller marshaller = new AuthorizationPolicyMarshaller(); walkFileTree(authzPath, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { try { checkNotNull("file", file); checkNotNull("attrs", attrs); if (isPolicyFile(file)) { String content = ioService.readAllString(file); NonEscapedProperties props = new NonEscapedProperties(); props.load(new StringReader(content)); marshaller.read(builder, props); } } catch (final Exception e) { logger.error("Authz policy file VFS read error: " + file.getFileName(), e); return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; } }); return builder.build(); } public boolean isPolicyFile(Path p) { String fileName = p.getName(p.getNameCount() - 1).toString(); return fileName.equals(POLICY_FILE) || fileName.startsWith("security-module-"); } @Override public void deletePolicyByGroup(Group group, AuthorizationPolicy policy) { AuthorizationPolicyMarshaller marshaller = new AuthorizationPolicyMarshaller(); NonEscapedProperties entries = new NonEscapedProperties(); marshaller.remove(group, policy, entries); savePolicyIntoVfs(entries, "system", "Delete Policy"); } public void savePolicyIntoVfs(NonEscapedProperties entries, String subjectId, String message) { if (subjectId == null || message == null) { ioService.startBatch(fileSystem); } else { ioService.startBatch(fileSystem, new CommentedOption(subjectId, message)); } try (StringWriter sw = new StringWriter()) { // Store the entries into a properties file entries.store(sw, "Authorization Policy", "Last update: " + new Date().toString()); String policyContent = sw.toString(); Path policyPath = getAuthzPath().resolve(POLICY_FILE); ioService.write(policyPath, policyContent); } catch (Exception e) { logger.error("Authz policy write error.", e); } finally { ioService.endBatch(); } } public Path getAuthzPath() { checkNotNull("root", root); return root.resolve("authz"); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/authz/AuthorizationServiceImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.jboss.errai.bus.server.annotations.Service; import org.jboss.errai.security.shared.api.Group; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.backend.authz.AuthorizationService; import org.uberfire.backend.events.AuthorizationPolicySavedEvent; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.PermissionManager; @Service @ApplicationScoped public class AuthorizationServiceImpl implements AuthorizationService { private AuthorizationPolicyStorage storage; private PermissionManager permissionManager; private Event savedEvent; @Inject public AuthorizationServiceImpl(final AuthorizationPolicyStorage storage, final PermissionManager permissionManager, final Event savedEvent) { this.storage = storage; this.permissionManager = permissionManager; this.savedEvent = savedEvent; } @Override public AuthorizationPolicy loadPolicy() { return storage.loadPolicy(); } @Override public void savePolicy(AuthorizationPolicy policy) { storage.savePolicy(policy); permissionManager.setAuthorizationPolicy(policy); savedEvent.fire(new AuthorizationPolicySavedEvent(policy)); } @Override public void deletePolicyByGroup(Group group, AuthorizationPolicy policy) { storage.deletePolicyByGroup(group, policy); AuthorizationPolicy newPolicy = storage.loadPolicy(); permissionManager.setAuthorizationPolicy(newPolicy); savedEvent.fire(new AuthorizationPolicySavedEvent(newPolicy)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/authz/NonEscapedProperties.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; import java.util.Comparator; import java.util.Properties; import java.util.TreeMap; /** * A {@link TreeMap} implementation that mimics the behaviour of the JDK's {@link Properties} class * preventing the '/' or ':' chars from being escaped. */ public class NonEscapedProperties extends TreeMap { private static final long serialVersionUID = 1L; public NonEscapedProperties() { } public NonEscapedProperties(Comparator comparator) { super(comparator); } public void load(Reader reader) throws IOException { BufferedReader br = new BufferedReader(reader); String line; while ((line = br.readLine()) != null) { putLine(line); } } public void load(Path file) throws IOException { for (String line : Files.readAllLines(file)) { putLine(line); } } public void store(Writer writer, String... comments) throws IOException { StringBuilder out = new StringBuilder(); if (comments != null) { for (String comment : comments) { out.append("# ").append(comment).append("\n"); } out.append("\n"); } this.forEach((key, value) -> { out.append(key).append("=").append(value).append("\n"); }); writer.write(out.toString()); writer.flush(); } private void putLine(String line) { if (line != null) { String _line = line.trim(); if (!_line.isEmpty() && !_line.startsWith("#")) { String[] tokens = _line.split("="); if (tokens.length == 1) { super.put(tokens[0], ""); } if (tokens.length == 2) { super.put(tokens[0], tokens[1]); } } } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/fs/FileSystemServiceImpl.java ================================================ /* * Copyright 2020 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.fs; import javax.enterprise.context.ApplicationScoped; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.backend.fs.FileSystemService; import org.uberfire.java.nio.file.api.FileSystemUtils; @Service @ApplicationScoped public class FileSystemServiceImpl implements FileSystemService { @Override public Boolean isGitDefaultFileSystem() { return FileSystemUtils.isGitDefaultFileSystem(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/ConfigIOServiceProducer.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io; import java.util.concurrent.ExecutorService; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Instance; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.inject.Named; import org.jboss.errai.security.shared.service.AuthenticationService; import org.uberfire.backend.server.security.IOSecurityAuth; import org.uberfire.commons.concurrent.Unmanaged; import org.uberfire.commons.lifecycle.PriorityDisposableRegistry; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; import org.uberfire.io.IOService; import org.uberfire.io.impl.IOServiceNio2WrapperImpl; import org.uberfire.java.nio.file.FileSystem; @ApplicationScoped @Startup(StartupType.BOOTSTRAP) public class ConfigIOServiceProducer { private static ConfigIOServiceProducer instance; private ExecutorService executorService; private Instance applicationProvidedConfigIOAuthService; private IOService configIOService; private FileSystem configFileSystem; public static ConfigIOServiceProducer getInstance() { if (instance == null) { throw new IllegalStateException(ConfigIOServiceProducer.class.getName() + " not initialized on startup"); } return instance; } public ConfigIOServiceProducer() { } @Inject public ConfigIOServiceProducer(@Unmanaged ExecutorService executorService, @IOSecurityAuth Instance applicationProvidedConfigIOAuthService) { this.executorService = executorService; this.applicationProvidedConfigIOAuthService = applicationProvidedConfigIOAuthService; } @PostConstruct public void setup() { instance = this; configIOService = new IOServiceNio2WrapperImpl("config"); configFileSystem = (FileSystem) PriorityDisposableRegistry.get("systemFS"); } public void destroy() { instance = null; } @Produces @Named("configIO") public IOService configIOService() { return configIOService; } public FileSystem configFileSystem() { if (configFileSystem == null) { configFileSystem = (FileSystem) PriorityDisposableRegistry.get("systemFS"); } return configFileSystem; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/DisposableShutdownService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.ExecutorService; import javax.inject.Inject; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.uberfire.commons.concurrent.Managed; import org.uberfire.commons.concurrent.Unmanaged; import org.uberfire.commons.lifecycle.Disposable; import org.uberfire.commons.lifecycle.PriorityDisposable; import org.uberfire.commons.lifecycle.PriorityDisposableRegistry; import org.uberfire.java.nio.file.api.FileSystemProviders; import org.uberfire.java.nio.file.spi.FileSystemProvider; public class DisposableShutdownService implements ServletContextListener { private ExecutorService unmanagedExecutorService; private ExecutorService executorService; public DisposableShutdownService() { } @Inject public DisposableShutdownService(@Managed ExecutorService executorService, @Unmanaged ExecutorService unmanagedExecutorService) { this.executorService = executorService; this.unmanagedExecutorService = unmanagedExecutorService; } @Override public void contextInitialized(final ServletContextEvent sce) { } @Override public void contextDestroyed(final ServletContextEvent sce) { final List disposables = new ArrayList(PriorityDisposableRegistry.getDisposables()); sort(disposables); for (final PriorityDisposable disposable : disposables) { disposable.dispose(); } executorService.shutdown(); unmanagedExecutorService.shutdown(); for (final FileSystemProvider fileSystemProvider : FileSystemProviders.installedProviders()) { if (fileSystemProvider instanceof Disposable) { ((Disposable) fileSystemProvider).dispose(); } } PriorityDisposableRegistry.clear(); } void sort(final List disposables) { Collections.sort(disposables, new Comparator() { @Override public int compare(final PriorityDisposable o1, final PriorityDisposable o2) { return (o2.priority() < o1.priority()) ? -1 : ((o2.priority() == o1.priority()) ? 0 : 1); } }); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/object/ObjectStorage.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.object; import java.net.URI; import org.uberfire.java.nio.file.Path; /** * Object Storage definition */ public interface ObjectStorage { /** * Initialize the object storage. * @param rootURI The root URI where is going to create the file system */ void init(URI rootURI); /** * Checks if a path exists into the object storage. * @param path the path to the stored object. * @return true if exists that path into the storage else false. */ boolean exists(String path); /** * Read the content of the path given * @param path The path where the content is stored * @return The content of the file unmarshalled */ T read(String path); /** * Write an object into the object storage. That object is marshalled into JSON. Lock will be enabled before write * and disabled after it. * @param path The path where the object is going to be written * @param value The object itself */ void write(String path, T value); /** * Write an object into the object storage. That object is marshalled into JSON. You can avoid FS lock * @param path The path where the object is going to be written * @param value The object itself * @param lock If the object storage should be locked while writing */ void write(String path, T value, boolean lock); /** * Delete a path from the object storage if exists. That path contains the object stored. * @param path The path to delete */ void delete(String path); /** * Return a path based on the filesystem that is implemented for storage * @param first the path string or initial part of the path string * @param path additional strings to be joined to form the path string * @return the path object that represents the path. */ Path getPath(String first, String... path); void close(); } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/object/ObjectStorageImpl.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.object; import java.net.URI; import java.util.HashMap; import javax.inject.Inject; import javax.inject.Named; import org.jboss.errai.marshalling.server.MappingContextSingleton; import org.jboss.errai.marshalling.server.ServerMarshalling; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import org.uberfire.java.nio.file.Path; public class ObjectStorageImpl implements ObjectStorage { private IOService ioService; private FileSystem fileSystem; @Inject public ObjectStorageImpl(@Named("configIO") final IOService ioService) { this.ioService = ioService; } @Override public void init(URI rootURI) { initializeMarshaller(); initializeFileSystem(rootURI); } @Override public boolean exists(final String path) { Path fsPath = fileSystem.getPath(path); try { return ioService.exists(fsPath); } catch (final Exception e) { throw new RuntimeException(e); } } @Override public T read(final String path) { Path fsPath = fileSystem.getPath(path); try { if (ioService.exists(fsPath)) { String content = ioService.readAllString(fsPath); return (T) ServerMarshalling.fromJSON(content); } } catch (final Exception e) { throw new RuntimeException(e); } return null; } @Override public void write(final String path, final T value) { this.write(path, value, true); } @Override public void write(final String path, final T value, final boolean lock) { try { if (lock) { ioService.startBatch(fileSystem); } Path fsPath = fileSystem.getPath(path); String content = ServerMarshalling.toJSON(value); ioService.write(fsPath, content); } catch (final Exception e) { throw new RuntimeException(e); } finally { if (lock) { ioService.endBatch(); } } } @Override public void delete(final String path) { ioService.deleteIfExists(fileSystem.getPath(path)); } @Override public Path getPath(String first, String... paths) { return this.fileSystem.getPath(first, paths); } @Override public void close() { this.fileSystem.close(); this.fileSystem.dispose(); } private void initializeMarshaller() { MappingContextSingleton.get(); } private void initializeFileSystem(final URI rootURI) { try { fileSystem = ioService.newFileSystem(rootURI, new HashMap() {{ put("init", Boolean.TRUE); put("internal", Boolean.TRUE); }}); } catch (FileSystemAlreadyExistsException e) { fileSystem = ioService.getFileSystem(rootURI); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/watch/AbstractIOWatchService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.watch; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import javax.naming.InitialContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.util.Filter; import org.uberfire.commons.async.DescriptiveRunnable; import org.uberfire.commons.concurrent.Unmanaged; import org.uberfire.commons.services.cdi.ApplicationStarted; import org.uberfire.io.IOWatchService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.java.nio.file.WatchKey; import org.uberfire.java.nio.file.WatchService; import org.uberfire.workbench.events.ResourceAddedEvent; import org.uberfire.workbench.events.ResourceBatchChangesEvent; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdatedEvent; public abstract class AbstractIOWatchService implements IOWatchService, Filter> { private static final Logger LOG = LoggerFactory.getLogger(AbstractIOWatchService.class); private static final Integer AWAIT_TERMINATION_TIMEOUT = Integer.parseInt(System.getProperty("org.uberfire.watcher.quitetimeout", "3")); private final List fileSystems = new ArrayList<>(); private final List watchServices = new ArrayList<>(); protected boolean isDisposed = false; private boolean started; private final Set watchThreads = new HashSet<>(); private Event resourceBatchChanges; private Event resourceUpdatedEvent; private Event resourceRenamedEvent; private Event resourceDeletedEvent; private Event resourceAddedEvent; private ExecutorService executorService; private IOWatchServiceExecutor executor = null; private final Set> jobs = new CopyOnWriteArraySet<>(); public AbstractIOWatchService() { } @Inject public AbstractIOWatchService(Event resourceBatchChanges, Event resourceUpdatedEvent, Event resourceRenamedEvent, Event resourceDeletedEvent, Event resourceAddedEvent, @Unmanaged ExecutorService executorService) { this.resourceBatchChanges = resourceBatchChanges; this.resourceUpdatedEvent = resourceUpdatedEvent; this.resourceRenamedEvent = resourceRenamedEvent; this.resourceDeletedEvent = resourceDeletedEvent; this.resourceAddedEvent = resourceAddedEvent; this.executorService = executorService; } @PostConstruct public void initialize() { final boolean autostart = Boolean.parseBoolean(System.getProperty("org.uberfire.watcher.autostart", "true")); if (autostart) { start(); } } public synchronized void start() { if (!started) { this.started = true; for (final AsyncWatchService watchThread : watchThreads) { final IOWatchServiceExecutor watchServiceExecutor = getWatchServiceExecutor(); jobs.add(executorService.submit(new DescriptiveRunnable() { @Override public String getDescription() { return watchThread.getDescription(); } @Override public void run() { watchThread.execute(watchServiceExecutor); } })); } watchThreads.clear(); } } @PreDestroy protected void dispose() { isDisposed = true; for (final WatchService watchService : watchServices) { watchService.close(); } for (final Future job : jobs) { if (!job.isCancelled() && !job.isDone()) { job.cancel(true); } } executorService.shutdown(); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (!executorService.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS)) { executorService.shutdownNow(); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled if (!executorService.awaitTermination(AWAIT_TERMINATION_TIMEOUT, TimeUnit.SECONDS)) { LOG.error("Thread pool did not terminate"); } } } catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted executorService.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); } } @Override public boolean hasWatchService(final FileSystem fs) { return fileSystems.contains(fs.getName()); } @Override public void addWatchService(final FileSystem fs, final WatchService ws) { fileSystems.add(fs.getName()); watchServices.add(ws); final AsyncWatchService asyncWatchService = new AsyncWatchService() { @Override public void execute(final IOWatchServiceExecutor wsExecutor) { while (!isDisposed) { final WatchKey wk; try { wk = ws.take(); } catch (final Exception ex) { break; } try { wsExecutor.execute(wk, AbstractIOWatchService.this); } catch (final Exception ex) { LOG.error("Unexpected error during WatchService execution", ex); } // Reset the key -- this step is critical if you want to // receive further watch events. If the key is no longer valid, // the directory is inaccessible so exit the loop. boolean valid = wk.reset(); if (!valid) { break; } } } @Override public String getDescription() { return AbstractIOWatchService.this.getClass().getName() + "(" + ws.toString() + ")"; } }; if (started) { final IOWatchServiceExecutor watchServiceExecutor = getWatchServiceExecutor(); executorService.execute(new DescriptiveRunnable() { @Override public String getDescription() { return asyncWatchService.getDescription(); } @Override public void run() { asyncWatchService.execute(watchServiceExecutor); } }); } else { watchThreads.add(asyncWatchService); } } public void configureOnEvent(@Observes ApplicationStarted applicationStartedEvent) { start(); } protected IOWatchServiceExecutor getWatchServiceExecutor() { if (executor == null) { IOWatchServiceExecutor _executor = null; try { _executor = InitialContext.doLookup("java:module/IOWatchServiceExecutorImpl"); } catch (final Exception ignored) { } if (_executor == null) { _executor = new IOWatchServiceExecutorImpl(); ((IOWatchServiceExecutorImpl) _executor).setEvents(resourceBatchChanges, resourceUpdatedEvent, resourceRenamedEvent, resourceDeletedEvent, resourceAddedEvent); } executor = _executor; } return executor; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/watch/AsyncWatchService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.watch; public interface AsyncWatchService { void execute(final IOWatchServiceExecutor wsExecutor); String getDescription(); } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/watch/IOWatchServiceExecutor.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.watch; import org.uberfire.backend.server.util.Filter; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.java.nio.file.WatchKey; public interface IOWatchServiceExecutor { void execute(final WatchKey watchKey, final Filter> filter); } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/io/watch/IOWatchServiceExecutorImpl.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.watch; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ejb.AccessTimeout; import javax.ejb.Singleton; import javax.ejb.Startup; import javax.ejb.TransactionAttribute; import javax.enterprise.event.Event; import javax.inject.Inject; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.uberfire.backend.server.util.Filter; import org.uberfire.backend.vfs.Path; import org.uberfire.commons.data.Pair; import org.uberfire.java.nio.base.WatchContext; import org.uberfire.java.nio.file.StandardWatchEventKind; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.java.nio.file.WatchKey; import org.uberfire.rpc.SessionInfo; import org.uberfire.rpc.impl.SessionInfoImpl; import org.uberfire.workbench.events.ResourceAdded; import org.uberfire.workbench.events.ResourceAddedEvent; import org.uberfire.workbench.events.ResourceBatchChangesEvent; import org.uberfire.workbench.events.ResourceChange; import org.uberfire.workbench.events.ResourceDeleted; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceEvent; import org.uberfire.workbench.events.ResourceRenamed; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdated; import org.uberfire.workbench.events.ResourceUpdatedEvent; import static javax.ejb.TransactionAttributeType.NOT_SUPPORTED; import static org.uberfire.backend.server.util.Paths.convert; @Singleton @Startup @TransactionAttribute(NOT_SUPPORTED) @AccessTimeout(value = 30, unit = java.util.concurrent.TimeUnit.SECONDS) public class IOWatchServiceExecutorImpl implements IOWatchServiceExecutor { @Inject private Event resourceBatchChanges; @Inject private Event resourceUpdatedEvent; @Inject private Event resourceRenamedEvent; @Inject private Event resourceDeletedEvent; @Inject private Event resourceAddedEvent; public void setEvents(final Event resourceBatchChanges, final Event resourceUpdatedEvent, final Event resourceRenamedEvent, final Event resourceDeletedEvent, final Event resourceAddedEvent) { this.resourceBatchChanges = resourceBatchChanges; this.resourceUpdatedEvent = resourceUpdatedEvent; this.resourceRenamedEvent = resourceRenamedEvent; this.resourceDeletedEvent = resourceDeletedEvent; this.resourceAddedEvent = resourceAddedEvent; } @Override public void execute(final WatchKey wk, final Filter> filter) { final List> events = wk.pollEvents(); WatchContext firstContext = null; if (events.size() > 1) { final Map> changes = new HashMap<>(); for (final WatchEvent event : events) { if (!filter.doFilter(event)) { if (firstContext == null) { firstContext = (WatchContext) event.context(); } final Pair result = buildChange(event); if (result != null) { if (!changes.containsKey(result.getK1())) { changes.put(result.getK1(), new ArrayList<>()); } changes.get(result.getK1()).add(result.getK2()); } } } if (changes.size() == 1 && changes.entrySet().iterator().next().getValue().size() == 1) { final ResourceChange _event = changes.values().iterator().next().iterator().next(); if (_event instanceof ResourceUpdated) { resourceUpdatedEvent.fire((ResourceUpdatedEvent) toEvent(changes.keySet().iterator().next(), _event, firstContext)); } else if (_event instanceof ResourceAdded) { resourceAddedEvent.fire((ResourceAddedEvent) toEvent(changes.keySet().iterator().next(), _event, firstContext)); } else if (_event instanceof ResourceRenamed) { resourceRenamedEvent.fire((ResourceRenamedEvent) toEvent(changes.keySet().iterator().next(), _event, firstContext)); } else if (_event instanceof ResourceDeleted) { resourceDeletedEvent.fire((ResourceDeletedEvent) toEvent(changes.keySet().iterator().next(), _event, firstContext)); } } else if (changes.size() >= 1) { resourceBatchChanges.fire(new ResourceBatchChangesEvent(changes, message(firstContext), sessionInfo(firstContext))); } } else if (events.size() == 1) { final WatchEvent event = events.get(0); if (!filter.doFilter(event)) { if (event.kind().equals(StandardWatchEventKind.ENTRY_MODIFY)) { resourceUpdatedEvent.fire(buildEvent(ResourceUpdatedEvent.class, event).getK2()); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_CREATE)) { resourceAddedEvent.fire(buildEvent(ResourceAddedEvent.class, event).getK2()); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_RENAME)) { resourceRenamedEvent.fire(buildEvent(ResourceRenamedEvent.class, event).getK2()); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_DELETE)) { resourceDeletedEvent.fire(buildEvent(ResourceDeletedEvent.class, event).getK2()); } } } } private String message(final WatchContext context) { if (context == null) { return null; } return context.getMessage(); } private Pair buildEvent(final Class clazz, final WatchEvent event) { final WatchContext context = (WatchContext) event.context(); final Path _affectedPath; final T result; if (event.kind().equals(StandardWatchEventKind.ENTRY_MODIFY)) { _affectedPath = convert(context.getOldPath()); result = (T) new ResourceUpdatedEvent(_affectedPath, context.getMessage(), sessionInfo(context)); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_CREATE)) { _affectedPath = convert(context.getPath()); result = (T) new ResourceAddedEvent(_affectedPath, context.getMessage(), sessionInfo(context)); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_RENAME)) { _affectedPath = convert(context.getOldPath()); result = (T) new ResourceRenamedEvent(_affectedPath, convert(context.getPath()), context.getMessage(), sessionInfo(context)); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_DELETE)) { _affectedPath = convert(context.getOldPath()); result = (T) new ResourceDeletedEvent(_affectedPath, context.getMessage(), sessionInfo(context)); } else { _affectedPath = null; result = null; } if (_affectedPath == null) { return null; } return Pair.newPair(_affectedPath, result); } private Pair buildChange(final WatchEvent event) { final WatchContext context = (WatchContext) event.context(); final Path _affectedPath; final ResourceChange result; if (event.kind().equals(StandardWatchEventKind.ENTRY_MODIFY)) { _affectedPath = convert(context.getOldPath()); result = new ResourceUpdated(context.getMessage()); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_CREATE)) { _affectedPath = convert(context.getPath()); result = new ResourceAdded(context.getMessage()); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_RENAME)) { _affectedPath = convert(context.getOldPath()); result = new ResourceRenamed(convert(context.getPath()), context.getMessage()); } else if (event.kind().equals(StandardWatchEventKind.ENTRY_DELETE)) { _affectedPath = convert(context.getOldPath()); result = new ResourceDeleted(context.getMessage()); } else { _affectedPath = null; result = null; } if (_affectedPath == null) { return null; } return Pair.newPair(_affectedPath, result); } private ResourceEvent toEvent(final Path path, final ResourceChange change, final WatchContext context) { if (change instanceof ResourceUpdated) { return new ResourceUpdatedEvent(path, context.getMessage(), sessionInfo(context)); } else if (change instanceof ResourceAdded) { return new ResourceAddedEvent(path, context.getMessage(), sessionInfo(context)); } else if (change instanceof ResourceRenamed) { return new ResourceRenamedEvent(path, ((ResourceRenamed) change).getDestinationPath(), context.getMessage(), sessionInfo(context)); } else if (change instanceof ResourceDeleted) { return new ResourceDeletedEvent(path, context.getMessage(), sessionInfo(context)); } return null; } private SessionInfo sessionInfo(final WatchContext context) { final String sessionId; final String user; if (context.getSessionId() == null) { sessionId = ""; } else { sessionId = context.getSessionId(); } if (context.getUser() == null) { user = ""; } else { user = context.getUser(); } return new SessionInfoImpl(sessionId, new UserImpl(user)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/PluginService.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins; import java.io.File; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.servlet.ServletContext; import org.jboss.errai.bus.server.annotations.Service; import org.uberfire.backend.server.plugins.engine.PluginManager; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; /** * Provides an Errai RPC endpoint to serve JavaScript runtime plugins (authored * in plain JS) and Perspective Layouts (authored in plain JSON via Layout Editor * to the client where the corresponding scripts get injected into * the DOM. These plugins contain logic to programmatically register themselves * with UberFire. * It also initializes the {@link PluginManager} which * is responsible for loading plugins authored in GWT/Errai/UberFire. * These plugin scripts are injected into the host page by Errai once they are * registered with Errai's script registry or injected in runtime (when they * use Uberfire JS API). * Scripts injected via Errai's script registry do not need any programmatic * registration logic on the client as all contained managed beans (i.e. * perspectives, editors, screens) are automatically discovered and activated by * Errai IOC. */ @Service @ApplicationScoped @Startup(StartupType.BOOTSTRAP) public class PluginService { private static PluginService instance; private PluginManager pluginManager; public PluginService() { } @Inject public PluginService(PluginManager pluginManager) { this.pluginManager = pluginManager; } public static PluginService getInstance() { if (instance == null) { throw new IllegalStateException(PluginService.class.getName() + " was not initialized on startup"); } return instance; } @PostConstruct private void startUp() { instance = this; } public void init(final ServletContext servletContext) { final String contextRootDir = getContextRootDir(servletContext); final String pluginDir = getPlugins(servletContext, "plugins"); if (contextRootDir != null && pluginDir != null) { pluginManager.init(contextRootDir, pluginDir); } } String getPlugins(ServletContext servletContext, String plugins) { return PluginUtils.getRealPath(servletContext, plugins); } String getContextRootDir(ServletContext servletContext) { return getPlugins(servletContext, File.separator); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/PluginStartup.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * Initializes the {@link PluginService} when the web application starts * up. */ @WebListener public class PluginStartup implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { PluginService.getInstance().init(sce.getServletContext()); } @Override public void contextDestroyed(ServletContextEvent sce) { } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/PluginUtils.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins; import javax.servlet.ServletContext; import org.jboss.errai.bus.server.api.RpcContext; public class PluginUtils { public static String getRealPath(final String path) { return getRealPath(RpcContext.getServletRequest().getServletContext(), path); } public static String getRealPath(final ServletContext servletContext, final String path) { final String realPath = servletContext.getRealPath(path); if (realPath == null) { return null; } else { return realPath.replaceAll("\\\\", "/").replaceAll(" ", "%20"); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/RuntimePluginServiceImpl.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.jboss.errai.bus.server.annotations.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.plugin.RuntimePlugin; import org.uberfire.backend.plugin.RuntimePluginProcessor; import org.uberfire.backend.plugin.RuntimePluginService; import org.uberfire.backend.server.plugins.processors.HTMLPluginProcessor; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; import org.uberfire.java.nio.file.DirectoryStream; import org.uberfire.java.nio.file.Files; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.Paths; import org.uberfire.spaces.SpacesAPI; @Service @ApplicationScoped @Startup(StartupType.BOOTSTRAP) public class RuntimePluginServiceImpl implements RuntimePluginService { private static final Logger LOGGER = LoggerFactory.getLogger(RuntimePluginServiceImpl.class); @Inject @Any Instance runtimePluginProcessors; @Inject HTMLPluginProcessor htmlPluginProcessor; @Inject SpacesAPI spaces; @Override public Collection listFrameworksContent() { return directoryContent("frameworks", "*.js"); } @Override public Collection listPluginsContent() { return directoryContent("plugins", "*.js"); } @Override public String getTemplateContent(String url) { String pluginTemplateContent = getRuntimePluginTemplateContent(url); if (isAJarPluginTemplate(pluginTemplateContent)) { return pluginTemplateContent; } String realPath = PluginUtils.getRealPath("plugins"); if (realPath == null) { LOGGER.info("Not fetching template content for " + url + " because getRealPath() is" + " returning null. (This app is probably deployed in an unexploded .war)"); return ""; } final Path template; if (url.startsWith("/")) { template = Paths.get(URI.create("file://" + realPath + url)); } else { template = Paths.get(URI.create("file://" + realPath + "/" + url)); } if (Files.isRegularFile(template)) { return new String(Files.readAllBytes(template)); } return ""; } private boolean isAJarPluginTemplate(String pluginContent) { return pluginContent != null && !pluginContent.isEmpty(); } private Collection directoryContent(final String directory, final String glob) { String realPath = PluginUtils.getRealPath(directory); if (realPath == null) { LOGGER.info("Not listing directory content for " + directory + "/" + glob + " because getRealPath() is returning null. (This app is probably deployed in an unexploded .war)"); return Collections.emptyList(); } final Collection result = new ArrayList<>(); final Path pluginsRootPath = Paths.get(URI.create("file://" + realPath)); if (Files.isDirectory(pluginsRootPath)) { final DirectoryStream stream = Files.newDirectoryStream(pluginsRootPath, glob); for (final Path activeJS : stream) { result.add(new String(Files.readAllBytes(activeJS))); } } return result; } @Override public String getRuntimePluginTemplateContent(String pluginName) { if (htmlPluginProcessor.isRegistered(pluginName)) { Optional runtimePlugin = htmlPluginProcessor.lookupForTemplate(pluginName); return runtimePlugin. map(p -> p.getPluginContent()).orElse(""); } return ""; } @Override public List getRuntimePlugins() { List runtimePlugins = new ArrayList<>(); runtimePluginProcessors.forEach(p -> runtimePlugins.addAll(p.getAvailableRuntimePlugins())); return runtimePlugins; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/engine/PluginJarProcessor.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.engine; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.inject.Any; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.plugin.PluginProcessor; import org.uberfire.workbench.events.PluginReloadedEvent; import static org.apache.commons.lang3.StringUtils.substringAfterLast; /** * Processes and activates deployed plugin jars. The plugin jars can contain * GWT .js files, Uberfire Runtime Plugins and html templates. * The corresponding GWT .js files are registered with the {@link PluginProcessor} * and are added to the host page's <head> element by Errai, * so the plugin scripts execute before the web application's main script runs. * This is required to ensure plugins and their managed beans are discoverable by * Errai's bean manager when the main application bootstraps. * Uberfire Runtime Plugins are loaded after Errai and Uberfire bootstrap. */ @Dependent public class PluginJarProcessor { private static final Logger LOG = LoggerFactory.getLogger(PluginJarProcessor.class); private Instance pluginProcessors; private String pluginsDir; private String pluginsDeploymentUrlPath; private String pluginsDeploymentDir; private Event pluginsReloadedEvent; @Inject public PluginJarProcessor(@Any Instance pluginProcessors, final Event pluginsReloadedEvent) { this.pluginProcessors = pluginProcessors; this.pluginsReloadedEvent = pluginsReloadedEvent; } /** * Processes and loads the currently deployed plugins. * @param pluginsDir the plugin directory, must not be null. * @param pluginsDeploymentDir the directory to deploy plugin contents to, must not be null. */ public void init(final String pluginsDir, final String pluginsDeploymentDir) throws IOException { this.pluginsDeploymentUrlPath = substringAfterLast(pluginsDeploymentDir, File.separator); this.pluginsDeploymentDir = pluginsDeploymentDir; this.pluginsDir = pluginsDir; loadPlugins(); } void loadPlugins() throws IOException { removeAllPlugins(); final File pluginsRoot = new File(pluginsDir); if (pluginsRoot.exists()) { Collection deployedPlugins = FileUtils.listFiles(pluginsRoot, new String[]{"jar"}, false); deployedPlugins.forEach(p -> loadPlugins(Paths.get(p.getAbsolutePath()), false)); } } void removeAllPlugins() { pluginProcessors.forEach(p -> p.removeAll()); } /** * Clears the plugins and reloads all currently deployed plugins. * Fires a {@link PluginReloadedEvent} when done. */ public void reload() throws IOException { loadPlugins(); pluginsReloadedEvent.fire(new PluginReloadedEvent()); } /** * Unpacks the provided plugin (path pointing to a JAR file), searches for * the corresponding plugins files and process the plugin with the * corresponding {@link PluginProcessor}. * @param path path to a deployed jar file. * @param notifyClients true if clients should be notified (of added and updated * plugins) through CDI events, otherwise false. */ public void loadPlugins(Path path, boolean notifyClients) { final List pluginsFiles = extractFilesFromPluginsJar(pluginsDir + File.separator + path.toFile().getName()); if (!pluginsFiles.isEmpty()) { for (String pluginName : pluginsFiles) { for (PluginProcessor pluginRegistry : pluginProcessors) { if (pluginRegistry.shouldProcess(pluginName)) { pluginRegistry.process(pluginName, pluginsDeploymentDir, notifyClients); } } } } else { LOG.warn("Deployed plugin " + path.toFile().getName() + " does not contain any plugins!"); } } List extractFilesFromPluginsJar(String jarFileName) { List pluginsFiles = new ArrayList<>(); try (JarFile jar = new JarFile(jarFileName)) { final Enumeration enumEntries = jar.entries(); while (enumEntries.hasMoreElements()) { final JarEntry file = (JarEntry) enumEntries.nextElement(); String fileName = StringUtils.substringAfterLast(file.getName(), File.separator); if (PluginProcessor.isAValidPluginFileExtension(fileName)) { final File f = new File(pluginsDeploymentDir + File.separator + fileName); try (InputStream is = jar.getInputStream(file); FileOutputStream fos = new FileOutputStream(f)) { while (is.available() > 0) { fos.write(is.read()); } } pluginsFiles.add(fileName); } } } catch (IOException e) { throw new RuntimeException(e); } return pluginsFiles; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/engine/PluginManager.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.engine; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; import java.util.Collection; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.annotation.PreDestroy; import javax.enterprise.context.Dependent; import javax.inject.Inject; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.util.URIUtil; /** * Manages Uberfire Plugins which involves monitoring the plugins directory * (see {@link PluginWatcher}), and loading the deployed plugins (see * {@link PluginJarProcessor}). */ @Dependent public class PluginManager { private static final Logger LOG = LoggerFactory.getLogger(PluginManager.class); private PluginWatcher pluginWatcher; private PluginJarProcessor pluginJarProcessor; private ExecutorService executor; @Inject public PluginManager(final PluginWatcher pluginWatcher, final PluginJarProcessor pluginJarProcessor) { this.pluginWatcher = pluginWatcher; this.pluginJarProcessor = pluginJarProcessor; this.executor = Executors.newSingleThreadExecutor(); } @PreDestroy void shutDown() { pluginWatcher.stop(); } /** * Initializes the {@link PluginJarProcessor} and * {@link PluginWatcher} based on the provided parameters. * @param contextRootDir the web application's context root directory, must not be * null. * @param pluginDir the plugin directory, must not be null. */ public void init(final String contextRootDir, final String pluginDir) { try { pluginJarProcessor.init(pluginDir, findPluginDeploymentDir(contextRootDir)); pluginWatcher.start(pluginDir, executor, pluginJarProcessor); } catch (Exception e) { LOG.error("Failed to initialize " + PluginManager.class.getName(), e); throw new RuntimeException(e); } } /** * Finds the directory to deploy plugin contents to. * @param contextRootDir the web application's context root directory, must not be * null. * @return the directory hosting the plugin's JS files or the provided * context root directory if not found. */ String findPluginDeploymentDir(String contextRootDir) throws IOException { final Collection gwtFiles = FileUtils.listFiles(new File(encodePath(contextRootDir)), new String[]{"nocache.js"}, true); if (!gwtFiles.isEmpty()) { final File gwtFile = gwtFiles.iterator().next(); return gwtFile.getParentFile().getCanonicalPath(); } return new File(contextRootDir).getCanonicalPath(); } String encodePath(String contextRootDir) { return URIUtil.decode(contextRootDir); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/engine/PluginWatcher.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.engine; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.WatchEvent; import java.nio.file.WatchEvent.Kind; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import javax.enterprise.context.Dependent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import static java.nio.file.StandardWatchEventKinds.OVERFLOW; /** * Monitors the plugins directory for changes and loads/removes plugins using the * {@link PluginJarProcessor}. */ @Dependent public class PluginWatcher { private static final Logger LOG = LoggerFactory.getLogger(PluginWatcher.class); volatile boolean active; private ExecutorService executor; private PluginJarProcessor pluginJarProcessor; /** * Starts the plugins watcher iff the provided plugin directory exists and * the watcher hasn't already been started. * @param pluginDir the plugin directory to monitor * @param executor the executor service to submit the watch thread to * @param pluginJarProcessor the plugin loader for registering and removing plugins */ void start(final String pluginDir, final ExecutorService executor, final PluginJarProcessor pluginJarProcessor) throws IOException { final Path pluginsRootPath = Paths.get(pluginDir); if (active || !Files.exists(pluginsRootPath)) { return; } this.active = true; this.executor = executor; this.pluginJarProcessor = pluginJarProcessor; final WatchService watchService = FileSystems.getDefault().newWatchService(); pluginsRootPath.register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE); startWatchService(watchService); } private void startWatchService(final WatchService watchService) { executor.submit(() -> { while (active) { try { final WatchKey watchKey = watchService.poll(5, TimeUnit.SECONDS); if (watchKey != null && active) { final List> events = watchKey.pollEvents(); for (WatchEvent event : events) { final Kind kind = event.kind(); if (kind == OVERFLOW) { continue; } final Path file = (Path) event.context(); if (kind == ENTRY_CREATE || kind == ENTRY_MODIFY) { loadPlugins(file); } else if (kind == ENTRY_DELETE) { reloadPlugins(file); } } boolean valid = watchKey.reset(); if (!valid) { break; } } } catch (InterruptedException e) { active = false; Thread.currentThread().interrupt(); } } }); } void stop() { active = false; if (executor != null) { executor.shutdown(); } } void loadPlugins(final Path file) { if (file.getFileName().toString().endsWith(".jar")) { try { pluginJarProcessor.loadPlugins(file, true); } catch (Exception e) { logPluginsWatcherError("Failed to process new plugin " + file.getFileName().toString(), e, !active); } } } void reloadPlugins(final Path file) { try { pluginJarProcessor.reload(); } catch (Exception e) { logPluginsWatcherError("Failed to delete plugin " + file.getFileName().toString(), e, !active); } } void logPluginsWatcherError(final String message, final Exception e, final boolean debug) { if (debug) { // Debug level is sufficient in case application is stopping LOG.debug(message); } else { LOG.error(message); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/processors/AbstractRuntimePluginProcessor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.processors; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; import java.util.HashMap; import java.util.Map; import javax.enterprise.event.Event; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.plugin.RuntimePlugin; import org.uberfire.backend.plugin.RuntimePluginProcessor; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; public abstract class AbstractRuntimePluginProcessor implements RuntimePluginProcessor { private static final Logger LOG = LoggerFactory.getLogger(AbstractRuntimePluginProcessor.class); final Map availableRuntimePlugins = new HashMap<>(); private Event pluginAddedEvent; private Event pluginUpdatedEvent; public AbstractRuntimePluginProcessor() { } public AbstractRuntimePluginProcessor(Event pluginAddedEvent, Event pluginUpdatedEvent) { this.pluginAddedEvent = pluginAddedEvent; this.pluginUpdatedEvent = pluginUpdatedEvent; } @Override public Collection getAvailableRuntimePlugins() { return availableRuntimePlugins.values(); } @Override public void removeAll() { availableRuntimePlugins.clear(); } @Override public boolean isRegistered(String pluginName) { return availableRuntimePlugins.containsKey(pluginName); } @Override public boolean shouldProcess(String pluginName) { return pluginName.endsWith(getType().getExtension()); } @Override public void process(String pluginName, String pluginDeploymentDir, boolean notifyClients) { if (!isRegistered(pluginName)) { loadPlugin(pluginName, pluginDeploymentDir); if (notifyClients) { pluginAddedEvent.fire(new PluginAddedEvent(pluginName)); } } else { if (notifyClients) { pluginUpdatedEvent.fire(new PluginUpdatedEvent(pluginName)); } } } private void loadPlugin(String pluginName, String pluginDeploymentDir) { try { String pluginContent = getPluginContent(pluginName, pluginDeploymentDir); availableRuntimePlugins.put(pluginName, new RuntimePlugin(getType(), pluginName, pluginContent)); } catch (IOException e) { LOG.error("Failed to initialize " + pluginDeploymentDir, e); throw new RuntimeException(e); } } String getPluginContent(String pluginName, String pluginDeploymentDir) throws IOException { Path path = Paths.get(pluginDeploymentDir + File.separator + pluginName); return new String(Files.readAllBytes(path)); } abstract PluginProcessorType getType(); } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/processors/GWTScriptPluginProcessor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.processors; import java.io.File; import java.util.HashSet; import java.util.Set; import javax.annotation.PreDestroy; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.jboss.errai.cdi.server.scripts.ScriptRegistry; import org.uberfire.backend.plugin.PluginProcessor; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; import static org.apache.commons.lang3.StringUtils.substringAfterLast; @ApplicationScoped public class GWTScriptPluginProcessor implements PluginProcessor { static final String SCRIPT_REGISTRY_KEY = "UF"; final Set availablePlugins = new HashSet<>(); private ScriptRegistry scriptRegistry; private Event pluginAddedEvent; private Event pluginUpdatedEvent; public GWTScriptPluginProcessor() { } @Inject public GWTScriptPluginProcessor(final ScriptRegistry scriptRegistry, final Event pluginAddedEvent, final Event pluginUpdatedEvent) { this.scriptRegistry = scriptRegistry; this.pluginAddedEvent = pluginAddedEvent; this.pluginUpdatedEvent = pluginUpdatedEvent; } @PreDestroy void shutDown() { scriptRegistry.removeScripts(SCRIPT_REGISTRY_KEY); } private void add(String pluginName, String scriptUrl) { availablePlugins.add(pluginName); scriptRegistry.addScript(SCRIPT_REGISTRY_KEY, scriptUrl); } @Override public void removeAll() { availablePlugins.clear(); scriptRegistry.removeScripts(SCRIPT_REGISTRY_KEY); } @Override public boolean isRegistered(String pluginName) { return availablePlugins.contains(pluginName); } @Override public boolean shouldProcess(String pluginName) { return pluginName.endsWith(PluginProcessorType.GWT.getExtension()); } @Override public void process(String pluginName, String pluginDeploymentDir, boolean notifyClients) { final String pluginDisplayName = pluginName.replace(PluginProcessorType.GWT.getExtension(), ""); if (!isRegistered(pluginName)) { final String url = resolveScriptUrl(pluginName, pluginDeploymentDir); add(pluginName, url); if (notifyClients) { pluginAddedEvent.fire(new PluginAddedEvent(pluginDisplayName)); } } else { if (notifyClients) { pluginUpdatedEvent.fire(new PluginUpdatedEvent(pluginDisplayName)); } } } String resolveScriptUrl(String pluginName, String pluginDeploymentDir) { String pluginsDeploymentUrlPath = substringAfterLast(pluginDeploymentDir, File.separator); return pluginsDeploymentUrlPath + "/" + pluginName + "?nocache=" + System.currentTimeMillis(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/processors/HTMLPluginProcessor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.processors; import java.util.Optional; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.uberfire.backend.plugin.RuntimePlugin; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; @ApplicationScoped public class HTMLPluginProcessor extends AbstractRuntimePluginProcessor { public HTMLPluginProcessor() { } @Inject public HTMLPluginProcessor(final Event pluginAddedEvent, final Event pluginUpdatedEvent) { super(pluginAddedEvent, pluginUpdatedEvent); } @Override PluginProcessorType getType() { return PluginProcessorType.HTML_TEMPLATE; } public Optional lookupForTemplate(String templateName) { return getAvailableRuntimePlugins(). stream(). filter(p -> p.getPluginName().equalsIgnoreCase(templateName)).findAny(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/processors/PerspectiveLayoutPluginProcessor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.processors; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; @ApplicationScoped public class PerspectiveLayoutPluginProcessor extends AbstractRuntimePluginProcessor { public PerspectiveLayoutPluginProcessor() { } @Inject public PerspectiveLayoutPluginProcessor(final Event pluginAddedEvent, final Event pluginUpdatedEvent) { super(pluginAddedEvent, pluginUpdatedEvent); } @Override PluginProcessorType getType() { return PluginProcessorType.PERSPECTIVE_EDITOR; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/plugins/processors/UFJSPluginProcessor.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.processors; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Event; import javax.inject.Inject; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; @ApplicationScoped public class UFJSPluginProcessor extends AbstractRuntimePluginProcessor { public UFJSPluginProcessor() { } @Inject public UFJSPluginProcessor(final Event pluginAddedEvent, final Event pluginUpdatedEvent) { super(pluginAddedEvent, pluginUpdatedEvent); } @Override public boolean shouldProcess(String pluginName) { return pluginName.endsWith(PluginProcessorType.JS.getExtension()) && !pluginName.endsWith(PluginProcessorType.GWT.getExtension()); } @Override PluginProcessorType getType() { return PluginProcessorType.JS; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/ElytronAuthenticationService.java ================================================ /* * Copyright 2021 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Alternative; import javax.inject.Inject; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.exception.FailedAuthenticationException; import org.jboss.errai.security.shared.service.AuthenticationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.security.elytron.ElytronIdentityHelper; @ApplicationScoped @Alternative public class ElytronAuthenticationService implements AuthenticationService { private static final Logger logger = LoggerFactory.getLogger(ElytronAuthenticationService.class); private final ElytronIdentityHelper elytronIdentityHelper; private final ThreadLocal userOnThisThread = new ThreadLocal<>(); @Inject public ElytronAuthenticationService(final ElytronIdentityHelper elytronIdentityHelper) { this.elytronIdentityHelper = elytronIdentityHelper; } @Override public User login(final String username, final String password) { try { User user = elytronIdentityHelper.getIdentity(username, password); userOnThisThread.set(user); return user; } catch (Exception ex) { logger.debug("Cannot login user '{}':", username, ex); } throw new FailedAuthenticationException(); } @Override public boolean isLoggedIn() { return userOnThisThread.get() != null; } @Override public void logout() { userOnThisThread.remove(); } @Override public User getUser() { User user = userOnThisThread.get(); if (user == null) { return User.ANONYMOUS; } return user; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/FileSystemResourceAdaptor.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import org.uberfire.backend.authz.FileSystemResourceType; import org.uberfire.java.nio.file.FileSystemMetadata; import org.uberfire.security.ResourceType; import org.uberfire.security.authz.RuntimeContentResource; public class FileSystemResourceAdaptor implements RuntimeContentResource { public static final FileSystemResourceType RESOURCE_TYPE = new FileSystemResourceType(); private final String identifier; private FileSystemMetadata fileSystemMetadata; public FileSystemResourceAdaptor(final FileSystemMetadata fsFileSystemMetadata) { this.fileSystemMetadata = fsFileSystemMetadata; if (fsFileSystemMetadata.isAFileSystemID()) { identifier = fsFileSystemMetadata.getId(); } else { identifier = fsFileSystemMetadata.getUri(); } } @Override public String getIdentifier() { return identifier; } FileSystemMetadata getFileSystemMetadata() { return fileSystemMetadata; } @Override public ResourceType getResourceType() { return RESOURCE_TYPE; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/IOSecurityAuth.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface IOSecurityAuth { } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/IOSecurityAuthz.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD}) public @interface IOSecurityAuthz { } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/IOServiceSecuritySetup.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.guvnor.structure.repositories.Repository; import org.guvnor.structure.repositories.RepositoryService; import org.guvnor.structure.security.RepositoryAction; import org.jboss.errai.security.shared.service.AuthenticationService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.security.elytron.ElytronIdentityHelper; import org.uberfire.backend.server.util.Paths; import org.uberfire.backend.vfs.Path; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.java.nio.file.FileSystemMetadata; import org.uberfire.java.nio.file.api.FileSystemProviders; import org.uberfire.java.nio.file.spi.FileSystemProvider; import org.uberfire.java.nio.security.SecuredFileSystemProvider; import org.uberfire.security.WorkbenchUserManager; import org.uberfire.security.authz.AuthorizationManager; import org.uberfire.spaces.Space; import org.uberfire.spaces.SpacesAPI; import org.uberfire.ssh.service.backend.auth.SSHKeyAuthenticator; @ApplicationScoped @Startup public class IOServiceSecuritySetup { /** * The system property that specifies which authentication domain the default security service should be configured * for. Not used if the application provides its own {@code @IOSecurityAuth AuthenticationService}. */ public static final String AUTH_DOMAIN_KEY = "org.uberfire.domain"; private static final Logger LOG = LoggerFactory.getLogger(IOServiceSecuritySetup.class); @Inject @IOSecurityAuth Instance authenticationManagers; @Inject AuthenticationService httpAuthManager; @Inject AuthorizationManager authorizationManager; @Inject RepositoryService repositoryService; @Inject SpacesAPI spacesAPI; @Inject SSHKeyAuthenticator sshKeyAuthenticator; @Inject WorkbenchUserManager workbenchUserManager; @Inject ElytronIdentityHelper elytronIdentityHelper; @PostConstruct public void setup() { final AuthenticationService nonHTTPAuthenticationManager; if (authenticationManagers.isUnsatisfied()) { final String authType = System.getProperty("org.uberfire.io.auth", null); final String domain = System.getProperty(AUTH_DOMAIN_KEY, JAASAuthenticationService.DEFAULT_DOMAIN); if (authType == null) { nonHTTPAuthenticationManager = new ElytronAuthenticationService(elytronIdentityHelper); } else if (authType.toLowerCase().equals("jaas") || authType.toLowerCase().equals("container")) { nonHTTPAuthenticationManager = new JAASAuthenticationService(domain); } else { nonHTTPAuthenticationManager = loadClazz(authType, AuthenticationService.class); } } else { nonHTTPAuthenticationManager = authenticationManagers.get(); } for (final FileSystemProvider fp : FileSystemProviders.installedProviders()) { if (fp instanceof SecuredFileSystemProvider) { SecuredFileSystemProvider sfp = (SecuredFileSystemProvider) fp; sfp.setJAASAuthenticator(nonHTTPAuthenticationManager); sfp.setHTTPAuthenticator(httpAuthManager); sfp.setAuthorizer((fs, fileSystemUser) -> { Path vfsPath = Paths.convert(fs.getPath(fs.getName())); Space space = spacesAPI.resolveSpace(vfsPath.toURI()).orElseThrow(() -> new IllegalArgumentException("Cannot resolve space from given path: " + vfsPath)); Repository repository = repositoryService.getRepositoryFromSpace(space, vfsPath.getFileName()); if (repository == null) { return authorizationManager.authorize( new FileSystemResourceAdaptor(new FileSystemMetadata(fs)), fileSystemUser); } return authorizationManager.authorize( repository, repository.getContributors(), RepositoryAction.READ, fileSystemUser); } ); sfp.setSSHAuthenticator((userName, key) -> sshKeyAuthenticator.authenticate(userName, key)); } } } private T loadClazz(final String clazzName, final Class typeOf) { if (clazzName == null || clazzName.isEmpty()) { return null; } try { final Class clazz = Class.forName(clazzName); if (!typeOf.isAssignableFrom(clazz)) { // FIXME this could only be due to a deployment configuration error. why do we continue in this case? LOG.error("Class '" + clazzName + "' is not assignable to expected type " + typeOf + ". Continuing as if no class was specified."); return null; } return typeOf.cast(clazz.newInstance()); } catch (final Exception e) { // FIXME this could only be due to a deployment error. why do we continue in this case? LOG.error("Failed to load class '" + clazzName + "' as type " + typeOf + ". Continuing as if none was specified.", e); } return null; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/JAASAuthenticationService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.io.IOException; import java.lang.reflect.Method; import java.util.Collection; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Alternative; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.jboss.errai.security.shared.exception.FailedAuthenticationException; import org.jboss.errai.security.shared.service.AuthenticationService; import org.kie.soup.commons.validation.PortablePreconditions; import org.uberfire.backend.server.security.adapter.GroupAdapterAuthorizationSource; /** * Implements stateful, thread-local authentication of a user via the JAAS API ( * {@code javax.security.auth.login.LoginContext}). *

        * Do not use this module for authenticating web requests! Upon login, it associates the current thread with the * authenticated user. This association is only undone upon a call to {@link #logout()}. This is appropriate for use * with the Git SSH daemon, but would cause serious security issues if used for authenticating HTTP requests. */ @ApplicationScoped @Alternative public class JAASAuthenticationService extends GroupAdapterAuthorizationSource implements AuthenticationService { public static final String DEFAULT_DOMAIN = "ApplicationRealm"; static final String DEFAULT_ROLE_PRINCIPLE_NAME = "Roles"; private final String rolePrincipleName = DEFAULT_ROLE_PRINCIPLE_NAME; private final ThreadLocal userOnThisThread = new ThreadLocal<>(); private final String domain; public JAASAuthenticationService(String domain) { this.domain = PortablePreconditions.checkNotNull("domain", domain); } @Override public User login(final String username, final String password) { final SecurityManager jsm = System.getSecurityManager(); if (jsm != null) { final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); final ClassLoader cl = this.getClass().getClassLoader(); try { // RHBPMS-473 - TCCL used in javax.security.auth.login.LoginContext // is not the application CL if JSM is enabled. // Setting TCCL to application CL as workaround Thread.currentThread().setContextClassLoader(cl); return executeLogin(username, password); } catch (final LoginException ex) { throw new FailedAuthenticationException(); } finally { // RHBPMS-473 - Restore original TCCL if (tccl != null) { Thread.currentThread().setContextClassLoader(tccl); } } } else { try { return executeLogin(username, password); } catch (final LoginException ex) { throw new FailedAuthenticationException(); } } } private User executeLogin(final String username, final String password) throws LoginException { final LoginContext loginContext = createLoginContext(username, password); loginContext.login(); List principals = loadEntitiesFromSubjectAndAdapters(username, loginContext.getSubject(), new String[]{rolePrincipleName}); Collection roles = getRoles(principals); Collection groups = getGroups(principals, username); UserImpl user = new UserImpl(username, roles, groups); userOnThisThread.set(user); return user; } @Override public void logout() { userOnThisThread.remove(); } @Override public User getUser() { User user = userOnThisThread.get(); if (user == null) { return User.ANONYMOUS; } return user; } @Override public boolean isLoggedIn() { return userOnThisThread.get() != null; } LoginContext createLoginContext(String username, String password) throws LoginException { return new LoginContext(domain, new UsernamePasswordCallbackHandler(username, password)); } class UsernamePasswordCallbackHandler implements CallbackHandler { private final String username; private final String password; public UsernamePasswordCallbackHandler(final String username, final String password) { this.username = username; this.password = password; } @Override public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (final Callback callback : callbacks) { if (callback instanceof NameCallback) { NameCallback nameCB = (NameCallback) callback; nameCB.setName(username); } else if (callback instanceof PasswordCallback) { PasswordCallback passwordCB = (PasswordCallback) callback; passwordCB.setPassword(password.toCharArray()); } else { try { final Method method = callback.getClass().getMethod("setObject", Object.class); method.invoke(callback, password); } catch (Exception e) { } } } } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/RoleLoader.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.nio.file.Path; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import org.apache.commons.lang3.StringUtils; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.WebAppListener; import org.uberfire.backend.server.WebAppSettings; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; /** * Startup class that read the roles declared in the webapp's web.xml and register them into the {@link RoleRegistry}. */ @Startup(StartupType.BOOTSTRAP) @ApplicationScoped public class RoleLoader { Logger logger = LoggerFactory.getLogger(RoleLoader.class); @PostConstruct public void init() { WebAppListener.registerOnStartupCommand(this::registerRolesFromwWebXml); } public void registerRolesFromwWebXml() { try { Set roles = loadRolesFromwWebXml(); for (String role : roles) { RoleRegistry.get().registerRole(role); } if (!roles.isEmpty()) { logger.info("Roles registered from web.xml \"" + StringUtils.join(roles.toArray(), ",") + "\""); } } catch (Exception e) { logger.error("Error reading roles from web.xml", e); } } protected Set loadRolesFromwWebXml() throws Exception { Path webXml = WebAppSettings.get().getAbsolutePath("WEB-INF", "web.xml"); Set result = new HashSet<>(); SAXBuilder builder = new SAXBuilder(); builder.setExpandEntities(false); Document doc = builder.build(webXml.toFile()); Element root = doc.getRootElement(); // Look for declarations. List bundleNodes = root.getChildren("security-role"); if (bundleNodes.isEmpty()) { bundleNodes = root.getChildren("security-role", null); } for (Iterator iterator = bundleNodes.iterator(); iterator.hasNext(); ) { Element el_role = (Element) iterator.next(); List ch_role = el_role.getChildren(); for (int i = 0; i < ch_role.size(); i++) { Element el_child = (Element) ch_role.get(i); if (el_child.getName().equals("role-name")) { String name = el_child.getValue().trim(); if (!StringUtils.isBlank(name)) { result.add(name); } } } } return result; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/RoleRegistry.java ================================================ /* * Copyright 2016 JBoss, by Red Hat, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; /** * It holds the collection of Role instances that the platform security * services recognize as the application available roles. */ public class RoleRegistry { private static RoleRegistry instance = null; private Set roles = new HashSet(); private RoleRegistry() { } /** * Returns singleton instance of the registry to be able to register roles */ public static RoleRegistry get() { if (instance == null) { instance = new RoleRegistry(); } return instance; } /** * Registers given role into the registry */ public void registerRole(String role) { this.roles.add(new RoleImpl(role)); } /** * Gets a a role instance by its name or null if not found. */ public Role getRegisteredRole(String name) { for (Role role : roles) { if (role.getName().equals(name)) { return role; } } return null; } /** * /** * Returns unmodifiable copy of all reqistered roles */ public Set getRegisteredRoles() { return Collections.unmodifiableSet(this.roles); } /** * Clears the registry. */ public void clear() { this.roles.clear(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/adapter/GroupAdapterAuthorizationSource.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.adapter; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.ServiceLoader; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.security.auth.Subject; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; import org.uberfire.backend.server.security.RoleRegistry; import org.uberfire.security.authz.adapter.GroupsAdapter; import static java.util.Collections.emptyList; import static java.util.Collections.unmodifiableList; public class GroupAdapterAuthorizationSource { private final String roleRegexTemplate = System.getProperty("org.uberfire.regex.role_mapper", null); private HashMap regexPatterns = new HashMap<>(); private List groupsAdapters = null; public GroupAdapterAuthorizationSource() { this.groupsAdapters = loadGroupAdapters(); } private static synchronized List loadGroupAdapters() { final ServiceLoader providers = ServiceLoader.load(GroupsAdapter.class); if (providers == null) { return emptyList(); } final List result = new ArrayList<>(); for (final GroupsAdapter provider : providers) { result.add(provider); } return unmodifiableList(result); } protected List loadEntitiesFromSubjectAndAdapters(String username, Subject subject, String[] rolePrincipleNames) { List roles = new ArrayList<>(); try { List principals = collectEntitiesFromSubject(username, subject, rolePrincipleNames); roles.addAll(filterValidPrincipals(principals)); List principalsFromAdapters = collectEntitiesFromAdapters(username, subject); roles.addAll(filterValidPrincipals(principalsFromAdapters)); } catch (Exception e) { throw new RuntimeException(e); } return roles; } protected List collectEntitiesFromAdapters(String username, Subject subject) { Set userGroups = new HashSet<>(); groupsAdapters.forEach(adapter -> { final List groupRoles = adapter.getGroups(username, subject); if (groupRoles != null) { for (Group group : groupRoles) { // apply configurable regex pattern for adapters that do not return simple group names if (roleRegexTemplate == null || roleRegexTemplate.isEmpty()) { userGroups.add(group.getName()); } else { userGroups.add(getSimpleName(group.getName())); } } } }); return new LinkedList<>(userGroups); } /** * Collects the principals for a given subject. */ protected List collectEntitiesFromSubject(String username, Subject subject, String[] rolePrincipleNames) { if (null == subject) { return null; } List roles = new ArrayList<>(); try { Set principals = subject.getPrincipals(); if (principals != null) { for (java.security.Principal p : principals) { if (p instanceof java.security.acl.Group) { for (final String rolePrincipleName : rolePrincipleNames) { if (rolePrincipleName.equalsIgnoreCase(p.getName())) { Enumeration groups = ((java.security.acl.Group) p).members(); while (groups.hasMoreElements()) { final java.security.Principal groupPrincipal = groups.nextElement(); roles.add(groupPrincipal.getName()); } } } } else { roles.add(p.getName()); } } } } catch (Exception e) { throw new RuntimeException(e); } return roles; } /** * For a given collection of principal names, return the Role instances for the ones * that are considered roles, so the ones that exist on the RoleRegistry. */ protected List getRoles(List principals) { if (null != principals && !principals.isEmpty()) { Set registeredRoles = RoleRegistry.get().getRegisteredRoles(); if (null != registeredRoles && !registeredRoles.isEmpty()) { List result = new LinkedList(); for (String role : principals) { if (null != RoleRegistry.get().getRegisteredRole(role)) { result.add(new RoleImpl(role)); } } return result; } } return Collections.emptyList(); } /** * For a given collection of principal names, return the Role instances for the ones * that are considered roles, so the ones that exist on the RoleRegistry. */ protected List getGroups(List principals, String user) { if (null != principals && !principals.isEmpty()) { Set registeredRoles = RoleRegistry.get().getRegisteredRoles(); if (null != registeredRoles && !registeredRoles.isEmpty()) { List result = new LinkedList(); for (String role : principals) { if ( role != user && null == RoleRegistry.get().getRegisteredRole(role)) { result.add(new GroupImpl(role)); } } return result; } } return Collections.emptyList(); } private List filterValidPrincipals(List principals) { if (principals == null) { return new ArrayList<>(); } return principals.stream().filter(Objects::nonNull).collect(Collectors.toList()); } /* * Return simple role name if name provided by adapter matches a regex pattern * */ private String getSimpleName(String name) { for (Role role : RoleRegistry.get().getRegisteredRoles()) { if (!regexPatterns.containsKey(role.getName())) { regexPatterns.put(role.getName(), Pattern.compile(roleRegexTemplate.replaceAll("role", role.getName()))); } Matcher matcher = regexPatterns.get(role.getName()).matcher(name); while (matcher.find()) { if (matcher.group(0) != null) { return role.getName(); } } } return name; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/adapter/JettyGroupsAdapter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.adapter; 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 java.util.Properties; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.security.authz.adapter.GroupsAdapter; @ApplicationScoped public class JettyGroupsAdapter implements GroupsAdapter { private static final String GROUPS_DEFINITION_FILE = "/jetty-groups.properties"; private static final Logger logger = LoggerFactory.getLogger(JettyGroupsAdapter.class); private Map> groupsByUser = null; public JettyGroupsAdapter() { InputStream input = this.getClass().getResourceAsStream(GROUPS_DEFINITION_FILE); if (input != null) { try { Properties properties = new Properties(); properties.load(input); groupsByUser = new HashMap>(); Set userNames = properties.stringPropertyNames(); for (String userName : userNames) { String groupsStr = properties.getProperty(userName); List userGroups = new ArrayList(); if (groupsStr != null) { String[] groups = groupsStr.split(","); for (String group : groups) { userGroups.add(new GroupImpl(group)); } } groupsByUser.put(userName, userGroups); } } catch (IOException e) { logger.warn("Unable to load jetty-groups.properties file due to {}", e.getMessage()); } } } @Override public List getGroups(String principalName, final Object subject) { if (groupsByUser == null || !groupsByUser.containsKey(principalName)) { return Collections.emptyList(); } return groupsByUser.get(principalName); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/adapter/WebSphereGroupsAdapter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.adapter; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.naming.InitialContext; import javax.naming.NamingException; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.security.authz.adapter.GroupsAdapter; @ApplicationScoped public class WebSphereGroupsAdapter implements GroupsAdapter { private static final Logger logger = LoggerFactory.getLogger(WebSphereGroupsAdapter.class); private Object registry; public WebSphereGroupsAdapter() { try { this.registry = InitialContext.doLookup("UserRegistry"); } catch (NamingException e) { logger.info("Unable to look up UserRegistry in JNDI under key 'UserRegistry', disabling websphere adapter"); } } @Override public List getGroups(final String principal, final Object subject) { if (registry == null) { return Collections.emptyList(); } final List groups = new ArrayList(); try { Method method = registry.getClass().getMethod("getGroupsForUser", new Class[]{String.class}); List rolesIn = (List) method.invoke(registry, new Object[]{principal}); if (rolesIn != null) { for (Object o : rolesIn) { groups.add(new GroupImpl(o.toString())); } } } catch (Exception e) { logger.error("Unable to get groups from registry due to {}", e.getMessage(), e); } return groups; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/adapter/WeblogicGroupsAdapter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.adapter; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.enterprise.context.ApplicationScoped; import javax.security.auth.Subject; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.security.authz.adapter.GroupsAdapter; @ApplicationScoped public class WeblogicGroupsAdapter implements GroupsAdapter { private static final Logger logger = LoggerFactory.getLogger(WeblogicGroupsAdapter.class); private Class webLogicSecurity; public WeblogicGroupsAdapter() { try { this.webLogicSecurity = Class.forName("weblogic.security.Security"); } catch (Exception e) { logger.info("Unable to find weblogic.security.Security, disabling weblogic adapter"); } } @Override public List getGroups(final String principal, final Object subject) { if (webLogicSecurity == null) { return Collections.emptyList(); } final List groups = new ArrayList(); try { Subject wlsSubject = (Subject) subject; // if no subject given try to fetch it with WLS specific api if (wlsSubject == null) { Method method = webLogicSecurity.getMethod("getCurrentSubject", new Class[]{}); wlsSubject = (Subject) method.invoke(null, new Object[]{}); } if (wlsSubject != null) { for (java.security.Principal p : wlsSubject.getPrincipals()) { if (p.getClass().getName().indexOf("WLSGroup") != -1) { groups.add(new GroupImpl(p.getName())); } } } } catch (Exception e) { logger.error("Unable to get groups from subject due to {}", e.getMessage(), e); } return groups; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/elytron/DefaultElytronIdentityHelper.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.elytron; import javax.enterprise.inject.Alternative; import javax.inject.Inject; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.jboss.errai.security.shared.exception.FailedAuthenticationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.wildfly.security.auth.server.RealmUnavailableException; import org.wildfly.security.auth.server.SecurityDomain; import org.wildfly.security.evidence.Evidence; import org.wildfly.security.evidence.PasswordGuessEvidence; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * Default implementation of {@link ElytronIdentityHelper}, it relies in the platform {@link SecurityDomain} to obtain the user credentials */ @Alternative public class DefaultElytronIdentityHelper implements ElytronIdentityHelper { private static final Logger logger = LoggerFactory.getLogger(DefaultElytronIdentityHelper.class); @Inject public DefaultElytronIdentityHelper() { } @Override public User getIdentity(final String userName, final String password) { try { final Evidence evidence = new PasswordGuessEvidence(password.toCharArray()); final Iterator userRoles = login(userName, evidence); final Collection roles = new ArrayList<>(); userRoles.forEachRemaining(role -> roles.add(new RoleImpl(role))); return new UserImpl(userName, roles); } catch (Exception ex) { logger.debug("Identity provided for '{}' not valid", userName); } throw new FailedAuthenticationException(); } protected Iterator login(final String userName, final Evidence evidence) throws RealmUnavailableException { return SecurityDomain.getCurrent().authenticate(userName, evidence).getRoles().iterator(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/elytron/ElytronIdentityHelper.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.elytron; import org.jboss.errai.security.shared.api.identity.User; import org.uberfire.backend.server.security.ElytronAuthenticationService; /** * Helper for {@link ElytronAuthenticationService} to obtain the identity for a given credentials */ public interface ElytronIdentityHelper { /** * Obtains a valid (and authenticated) user for the given credentials. * @param userName The name of the user * @param password The password * @return a valid User */ User getIdentity(String userName, String password); } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/security/elytron/ElytronIdentityHelperProducer.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.elytron; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.inject.Inject; /** * Default producer for {@link ElytronIdentityHelper} */ @ApplicationScoped public class ElytronIdentityHelperProducer { @Inject public ElytronIdentityHelperProducer() { } @Produces public ElytronIdentityHelper getDefaultElytronIdentityHelper() { return new DefaultElytronIdentityHelper(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/servlet/ReleaseUserLocksServlet.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.servlet; import java.util.Set; import javax.inject.Inject; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.uberfire.backend.server.VFSLockServiceImpl; import org.uberfire.backend.vfs.VFSLockService; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.server.BaseFilteredServlet; @WebServlet(name = "ReleaseUserLocksServlet", urlPatterns = "/releaseUserLocksServlet") public class ReleaseUserLocksServlet extends BaseFilteredServlet { private static final Logger logger = LoggerFactory.getLogger(ReleaseUserLocksServlet.class); @Inject private VFSLockService vfsLockService; @Override protected void doGet(final HttpServletRequest request, final HttpServletResponse response) { final HttpSession session = request.getSession(); if (session != null && session.getAttribute(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME) != null) { final Set locks = (Set) session.getAttribute(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME); try { locks.forEach(lockInfo -> vfsLockService.releaseLock(lockInfo.getFile())); locks.clear(); } catch (Exception e) { logger.error("Error when releasing locks.", e); } } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/spaces/SpacesAPIImpl.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.spaces; import java.net.URI; import java.util.Optional; import java.util.regex.Pattern; import javax.enterprise.context.ApplicationScoped; import org.uberfire.commons.services.cdi.Startup; import org.uberfire.commons.services.cdi.StartupType; import org.uberfire.spaces.Space; import org.uberfire.spaces.SpacesAPI; @ApplicationScoped @Startup(StartupType.BOOTSTRAP) public class SpacesAPIImpl implements SpacesAPI { private static final String PATH_PATTERN = "^[A-Za-z]+://[^@]+[@]([^/]+)/.*"; private static final Pattern PATH_REGEX = Pattern.compile(PATH_PATTERN); @Override public Space getSpace(String name) { if (SpacesAPI.DEFAULT_SPACE_NAME.equals(name)) { return getDefaultSpace(); } else { return new Space(name); } } @Override public Optional resolveSpace(String uri) { return Optional .ofNullable(PATH_REGEX.matcher(uri)) .filter(matcher -> matcher.matches()) .map(matcher -> matcher.group(1)) .map(name -> trimName(name)) .map(this::getSpace); } private String trimName(final String name) { if (name.contains("@")) { return name.substring(name.indexOf("@") + 1); } else { return name; } } public URI resolveFileSystemURI(Scheme scheme, Space space, String fsName) { URI uri = URI.create(SpacesAPI.resolveFileSystemPath(scheme, space, fsName)); return uri; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/util/Filter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util; public interface Filter { boolean doFilter(final T t); } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/util/Guava14Workaround.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util; import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.Service; /** * Produces an empty {@code Set} in order to prevent deploy-time failure. * The issue is described in the Guava bug * tracker. This workaround is described in a comment on separate issue. */ @ApplicationScoped public class Guava14Workaround { @Produces Set dummyServices() { return ImmutableSet.of(); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/util/Paths.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util; import java.net.URI; import java.util.HashMap; import java.util.Map; import org.kie.soup.commons.validation.PortablePreconditions; import org.uberfire.backend.vfs.FileSystem; import org.uberfire.backend.vfs.FileSystemFactory; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.java.nio.file.Files; import static org.uberfire.backend.vfs.PathFactory.newPath; public final class Paths { private static Map cache = new HashMap<>(); public static Path convert(final org.uberfire.java.nio.file.Path path) { if (path == null) { return null; } if (path.getFileName() == null) { return newPath("/", path.toUri().toString(), new HashMap(1) {{ put(PathFactory.VERSION_PROPERTY, path.getFileSystem().supportedFileAttributeViews().contains("version")); }}); } return newPath(path.getFileName().toString(), path.toUri().toString(), new HashMap(1) {{ put(PathFactory.VERSION_PROPERTY, path.getFileSystem().supportedFileAttributeViews().contains("version")); }}); } public static org.uberfire.java.nio.file.Path convert(final Path path) { if (path == null) { return null; } return org.uberfire.java.nio.file.Paths.get(URI.create(path.toURI())); } public static FileSystem convert(final org.uberfire.java.nio.file.FileSystem fs) { if (!cache.containsKey(fs)) { final Map roots = new HashMap<>(); for (final org.uberfire.java.nio.file.Path root : fs.getRootDirectories()) { roots.put(root.toUri().toString(), root.getFileName() == null ? "/" : root.getFileName().toString()); } cache.put(fs, FileSystemFactory.newFS(roots, fs.supportedFileAttributeViews())); } return cache.get(fs); } public static String readLockedBy(final Path path) { org.uberfire.java.nio.file.Path lock = convert(PathFactory.newLock(path)); if (!Files.exists(lock)) { return null; } else { return new String(Files.readAllBytes(lock)); } } public static boolean isLock(final Path path) { return path.toURI().endsWith(PathFactory.LOCK_FILE_EXTENSION); } /** * Substring the second path from the first. This can be used to for example to substring the repository prefix from a Path. * @param wholePath What we want to substring from the first Path * @param prefixToRemove The Path we want to substring * @return The result. For example the File URI from the Repository root or from a submodule root. * @throws IllegalStateException When the the prefix is longer than the URI where it is removed from. */ public static String removePrefix(final Path wholePath, final Path prefixToRemove) { PortablePreconditions.checkNotNull("prefixToRemove", prefixToRemove); PortablePreconditions.checkNotNull("wholePath", wholePath); if (prefixToRemove.toURI().length() > wholePath.toURI().length()) { throw new IllegalArgumentException("Prefix is longer than the URI where it is being removed from."); } final org.uberfire.java.nio.file.Path nioWholePath = convert(wholePath); final org.uberfire.java.nio.file.Path nioPrefixToRemove = convert(prefixToRemove); if (!nioWholePath.startsWith(nioPrefixToRemove)) { throw new IllegalArgumentException("The beginning of the whole Path " + nioWholePath + " does not match the prefix path " + nioPrefixToRemove + "."); } return nioPrefixToRemove.relativize(nioWholePath).toString(); } /** * git:// and default:// can point to the same location. This normalizes the Paths for easier use with length and removePrefix functions. * @param path * @return */ public static org.uberfire.java.nio.file.Path normalizePath(final org.uberfire.java.nio.file.Path path) { return Paths.convert(Paths.convert(path)); } /** * git:// and default:// can point to the same location. This normalizes the Paths for easier use with length and removePrefix functions. * @param path * @return */ public static Path normalizePath(final Path path) { return Paths.convert(Paths.convert(path)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/util/TextUtil.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util; import java.text.Normalizer; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TextUtil { private static final String EMPTY_STRING = ""; // Any character except unicode letters and digits 0-9 private static final Pattern nonASCIIp1 = Pattern.compile("[^\\p{L}\\p{Nd}]"); private static final Matcher nonASCIIm1 = nonASCIIp1.matcher(EMPTY_STRING); // Any ASCII character except those between code point 0 (NULL) and 127 (DEL) private static final Pattern nonASCIIp2 = Pattern.compile("[^\\x00-\\x7f]"); private static final Matcher nonASCIIm2 = nonASCIIp2.matcher(EMPTY_STRING); // Any character except unicode letters and digits 0-9, allowing '.' and '-' private static final Pattern repoP1 = Pattern.compile("[^\\p{L}\\p{Nd}\\x2D\\x2E]"); // Any ASCII character except those between code point 0 (NULL) and 127 (DEL), allowing '.' and '-' private static final Pattern repoP2 = Pattern.compile("[^\\x00-\\x7f\\x2D\\x2E]"); // Match repetitions of '.', '-' or combinations thereof private static final Pattern repoP3 = Pattern.compile("[\\x2D\\x2E][\\x2D\\x2E]{1,}+"); public static String normalizeRepositoryName(String input) { // Remove leading and/or trailing '.' and '-' if (input.startsWith(".") || input.startsWith("-")) { input = normalizeRepositoryName(input.substring(1)); } if (input.endsWith(".") || input.endsWith("-")) { input = normalizeRepositoryName(input.substring(0, input.length() - 1)); } // Repository operations are not too frequent so instantiate corresponding matchers on demand return repoP3.matcher( repoP2.matcher( repoP1.matcher(Normalizer.normalize(input, Normalizer.Form.NFD)).replaceAll(EMPTY_STRING) ).replaceAll(EMPTY_STRING) ).replaceAll(EMPTY_STRING); } public static String normalizeUserName(String input) { nonASCIIm1.reset(Normalizer.normalize(input, Normalizer.Form.NFD)); return nonASCIIm2.reset(nonASCIIm1.replaceAll(EMPTY_STRING)).replaceAll(EMPTY_STRING); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/util/gzip/GzipFilter.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util.gzip; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import static javax.ws.rs.core.HttpHeaders.ACCEPT_ENCODING; public class GzipFilter implements Filter { static final String GZIP = "gzip"; static final String ORG_UBERFIRE_GZIP_ENABLE = "org.uberfire.gzip.enable"; public void init(final FilterConfig filterConfig) { // Empty on purpose } public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException { switch (getAction(req)) { case HALT: break; case DO_NOT_ACCEPT_GZIP: case DO_NOT_COMPRESS: chain.doFilter(req, res); break; case COMPRESS: compressAndContinue(req, (HttpServletResponse) res, chain); break; } } void compressAndContinue(final ServletRequest req, final HttpServletResponse res, final FilterChain chain) throws IOException, ServletException { final GzipHttpServletResponseWrapper wResponse = new GzipHttpServletResponseWrapper(res); chain.doFilter(req, wResponse); wResponse.close(); } Action getAction(final ServletRequest req) { final String enabled = System.getProperty(ORG_UBERFIRE_GZIP_ENABLE); if (enabled != null && !enabled.equals("true")) { return Action.DO_NOT_COMPRESS; } if (!(req instanceof HttpServletRequest)) { return Action.HALT; } final String acceptEncodingHeader = ((HttpServletRequest) req).getHeader(ACCEPT_ENCODING); if (acceptEncodingHeader == null || !acceptEncodingHeader.contains(GZIP)) { return Action.DO_NOT_ACCEPT_GZIP; } return Action.COMPRESS; } public void destroy() { // Empty on purpose } enum Action { HALT, DO_NOT_COMPRESS, DO_NOT_ACCEPT_GZIP, COMPRESS; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/util/gzip/GzipHttpServletResponseWrapper.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util.gzip; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; class GzipHttpServletResponseWrapper extends HttpServletResponseWrapper { private HttpServletResponse response; private ServletOutputStream stream; private PrintWriter writer; GzipHttpServletResponseWrapper(final HttpServletResponse response) { super(response); this.response = response; this.stream = null; this.writer = null; } @Override public void flushBuffer() throws IOException { stream.flush(); } @Override public ServletOutputStream getOutputStream() throws IOException { if (writer != null) { throw new IllegalStateException("getOutputStream() was already called"); } if (stream == null) { stream = createOutputStream(); } return stream; } @Override public PrintWriter getWriter() throws IOException { if (writer != null) { return writer; } if (stream != null) { throw new IllegalStateException("getWriter() was already called"); } stream = createOutputStream(); writer = new PrintWriter(new OutputStreamWriter(stream, StandardCharsets.UTF_8)); return writer; } @Override public void setContentLength(final int length) { // Empty on purpose } private ServletOutputStream createOutputStream() throws IOException { return new GzipResponseServletOutputStream(response); } void close() { try { if (writer != null) { writer.close(); } else if (stream != null) { stream.close(); } } catch (final IOException e) { // Error on closing writer or stream. } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/java/org/uberfire/backend/server/util/gzip/GzipResponseServletOutputStream.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util.gzip; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; class GzipResponseServletOutputStream extends ServletOutputStream { private static final String CONTENT_LENGTH_HEADER = "Content-Length"; private static final String CONTENT_ENCODING_HEADER = "Content-Encoding"; private ByteArrayOutputStream baos; private GZIPOutputStream gzipStream; private HttpServletResponse response; private ServletOutputStream outputStream; private boolean closed; GzipResponseServletOutputStream(final HttpServletResponse response) throws IOException { super(); this.closed = false; this.response = response; this.outputStream = response.getOutputStream(); this.baos = new ByteArrayOutputStream(); this.gzipStream = new GZIPOutputStream(baos); } @Override public void close() throws IOException { if (closed) { return; } gzipStream.finish(); final byte[] bytes = baos.toByteArray(); response.addHeader(CONTENT_LENGTH_HEADER, Integer.toString(bytes.length)); response.addHeader(CONTENT_ENCODING_HEADER, GzipFilter.GZIP); outputStream.write(bytes); outputStream.flush(); outputStream.close(); closed = true; } @Override public void flush() throws IOException { if (closed) { return; } gzipStream.flush(); } @Override public void write(final int b) throws IOException { if (closed) { throw new IOException("Output stream already closed."); } gzipStream.write((byte) b); } @Override public void write(final byte[] data) throws IOException { write(data, 0, data.length); } @Override public void write(final byte[] data, final int offset, final int length) throws IOException { if (closed) { throw new IOException("Output stream already closed."); } gzipStream.write(data, offset, length); } @Override public boolean isReady() { return true; } @Override public void setWriteListener(final WriteListener writeListener) { // Empty on purpose } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: uberfire-backend/uberfire-backend-server/src/main/resources/META-INF/services/org.uberfire.security.authz.adapter.GroupsAdapter ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # org.uberfire.backend.server.security.adapter.JettyGroupsAdapter org.uberfire.backend.server.security.adapter.WeblogicGroupsAdapter org.uberfire.backend.server.security.adapter.WebSphereGroupsAdapter ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/IOWatchServiceNonDotImplTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.java.nio.file.Path; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class IOWatchServiceNonDotImplTest { @Test public void shouldFilterTest() { Path path = mock(Path.class); IOWatchServiceNonDotImpl io = new IOWatchServiceNonDotImpl(); assertFalse(io.shouldFilter(null)); when(path.getFileName()).thenReturn(null); assertFalse(io.shouldFilter(path)); Path filename = mock(Path.class); when(filename.toString()).thenReturn("dont_start_with_."); when(path.getFileName()).thenReturn(filename); assertFalse(io.shouldFilter(path)); when(filename.toString()).thenReturn(".dora"); assertTrue(io.shouldFilter(path)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/LockCleanupSessionListenerTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.Collections; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.io.ConfigIOServiceProducer; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.Path; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class LockCleanupSessionListenerTest { @Mock private HttpSessionEvent evt; @Mock private HttpSession session; @Mock private IOService ioService; @Test public void throwExceptionWhenIOProducerNotInitialized() { final LockCleanupSessionListener listener = new LockCleanupSessionListener(); assertThatThrownBy(() -> listener.sessionDestroyed(evt)) .isInstanceOf(IllegalStateException.class) .hasMessage("org.uberfire.backend.server.io.ConfigIOServiceProducer not initialized on startup"); } @Test public void initWithoutInjection() { final ConfigIOServiceProducer producer = spy(new ConfigIOServiceProducer()); final LockCleanupSessionListener listener = new LockCleanupSessionListener(); try { when(evt.getSession()).thenReturn(session); when(session.getAttribute(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME)).thenReturn(Collections.emptySet()); when(producer.configIOService()).thenReturn(ioService); producer.setup(); listener.sessionDestroyed(evt); // Needs to programmatically request FS and IOService from producer instead of using @Inject (see UF-237) verify(producer).configIOService(); verify(producer).configFileSystem(); } finally { producer.destroy(); } } @Test public void releaseLockAssociatedWithSession() { final ConfigIOServiceProducer producer = spy(new ConfigIOServiceProducer()); final LockCleanupSessionListener listener = spy(new LockCleanupSessionListener()); try { final String lockedBy = "christian"; final LockInfo lock = new LockInfo(true, lockedBy, PathFactory.newPath("file", "default://file")); when(evt.getSession()).thenReturn(session); when(session.getAttribute(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME)).thenReturn(Collections.singleton(lock)); when(producer.configIOService()).thenReturn(ioService); when(ioService.readAllString(any(Path.class))).thenReturn(lockedBy); producer.setup(); listener.sessionDestroyed(evt); verify(ioService, times(1)).delete(any(Path.class)); } finally { producer.destroy(); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/VFSLockServiceTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.util.Set; import javax.servlet.http.HttpSession; import org.jboss.errai.bus.client.api.QueueSession; import org.jboss.errai.bus.client.api.base.MessageBuilder; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.bus.server.api.RpcContext; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.backend.vfs.impl.LockInfo; import org.uberfire.backend.vfs.impl.LockResult; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.NoSuchFileException; import org.uberfire.rpc.SessionInfo; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class VFSLockServiceTest { @InjectMocks private VFSLockServiceImpl lockService; @Mock private IOService ioService; @Mock private FileSystem fileSystem; @Mock private SessionInfo sessionInfo; @Mock private QueueSession queueSession; @Mock private HttpSession httpSession; private Path path = PathFactory.newPath("file-to-lock.txt", "default://file-to-lock.txt"); @Before public void setup() { setupRpcContext(); User testUser = new UserImpl("testUser"); when(sessionInfo.getIdentity()).thenReturn(testUser); when(queueSession.getAttribute(HttpSession.class, HttpSession.class.getName())).thenReturn(httpSession); } @Test public void acquireLockSucceedsIfFileUnlocked() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(false); final LockResult result = lockService.acquireLock(path); assertTrue(result.isSuccess()); assertEquals(path, result.getLockInfo().getFile()); assertEquals("testUser", result.getLockInfo().lockedBy()); assertTrue(result.getLockInfo().isLocked()); } @Test public void acquireLockSucceedsIfLockOwned() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("testUser"); final LockResult result = lockService.acquireLock(path); assertTrue(result.isSuccess()); assertEquals(path, result.getLockInfo().getFile()); assertEquals("testUser", result.getLockInfo().lockedBy()); assertTrue(result.getLockInfo().isLocked()); } @Test public void acquireLockFailsIfFileLocked() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("some-other-user"); final LockResult result = lockService.acquireLock(path); assertFalse(result.isSuccess()); assertEquals(path, result.getLockInfo().getFile()); assertEquals("some-other-user", result.getLockInfo().lockedBy()); assertTrue(result.getLockInfo().isLocked()); } @Test public void acquireLockUpdatesSession() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(false); lockService.acquireLock(path); verify(httpSession).setAttribute(eq(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME), any(Set.class)); } @Test // Unfortunately, batching is required for ensuring writes are properly // replicated in the cluster. This needs to addressed in a future version // of UF: https://issues.jboss.org/browse/UF-242 public void acquireLockUsesBatch() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(false); lockService.acquireLock(path); final InOrder inOrder = inOrder(ioService); inOrder.verify(ioService).startBatch(fileSystem); inOrder.verify(ioService).exists(any(org.uberfire.java.nio.file.Path.class)); inOrder.verify(ioService).write(any(org.uberfire.java.nio.file.Path.class), any(String.class)); inOrder.verify(ioService).endBatch(); } @Test public void releaseLockSucceedsIfLockOwned() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("testUser"); final LockResult result = lockService.releaseLock(path); assertTrue(result.isSuccess()); assertEquals(path, result.getLockInfo().getFile()); assertEquals(null, result.getLockInfo().lockedBy()); assertFalse(result.getLockInfo().isLocked()); } @Test public void releaseLockFailsIfLockNotOwned() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("some-other-user"); try { lockService.releaseLock(path); fail("Expected exception on attempt to release lock not owned by user"); } catch (Exception ioe) { // expected } } @Test public void forceReleaseLockSucceedsIfLockNotOwned() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("some-other-user"); final LockResult result = lockService.forceReleaseLock(path); assertTrue(result.isSuccess()); assertEquals(path, result.getLockInfo().getFile()); assertEquals(null, result.getLockInfo().lockedBy()); assertFalse(result.getLockInfo().isLocked()); } @Test public void releaseLockFailsIfFileUnlocked() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(false); final LockResult result = lockService.releaseLock(path); assertFalse(result.isSuccess()); assertEquals(path, result.getLockInfo().getFile()); assertEquals(null, result.getLockInfo().lockedBy()); assertFalse(result.getLockInfo().isLocked()); } @Test public void releaseLockUpdatesSession() { lockService.acquireLock(path); when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("testUser"); lockService.releaseLock(path); verify(httpSession).setAttribute(eq(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME), any(Set.class)); } @Test // Unfortunately, batching is required for ensuring writes are properly // replicated in the cluster. This needs to addressed in a future version // of UF: https://issues.jboss.org/browse/UF-242 public void releaseLockUsesBatch() { lockService.acquireLock(path); when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("testUser"); lockService.releaseLock(path); final InOrder inOrder = inOrder(ioService); inOrder.verify(ioService).startBatch(fileSystem); inOrder.verify(ioService).exists(any(org.uberfire.java.nio.file.Path.class)); inOrder.verify(ioService).readAllString(any(org.uberfire.java.nio.file.Path.class)); inOrder.verify(ioService).delete(any(org.uberfire.java.nio.file.Path.class)); inOrder.verify(ioService).endBatch(); } @Test public void retrieveLockInfoForLockedFile() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenReturn("some-user"); final LockInfo info = lockService.retrieveLockInfo(path); assertTrue(info.isLocked()); assertEquals("some-user", info.lockedBy()); } @Test public void retrieveLockInfoForUnlockedFile() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(false); final LockInfo info = lockService.retrieveLockInfo(path); assertFalse(info.isLocked()); assertNull(info.lockedBy()); } @Test public void retrieveLockInfoNoSuchFileException() { when(ioService.exists(any(org.uberfire.java.nio.file.Path.class))).thenReturn(true); when(ioService.readAllString(any(org.uberfire.java.nio.file.Path.class))).thenThrow(new NoSuchFileException()); final LockInfo info = lockService.retrieveLockInfo(path); assertFalse(info.isLocked()); assertNull(info.lockedBy()); } private void setupRpcContext() { final Message message = MessageBuilder.createMessage("for testing").signalling().done().getMessage(); message.setResource("Session", queueSession); RpcContext.set(message); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/VFSServicesServerImplTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.net.URI; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.uberfire.backend.vfs.DirectoryStream; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.PathFactory; import org.uberfire.io.IOService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.FileSystem; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class VFSServicesServerImplTest { private static final Path ROOT_PATH = PathFactory.newPath("root", "file://root"); private static final String ROOT_URI = ROOT_PATH.toURI(); private static Set FS_ATTRIBUTES = new HashSet() {{ add("version"); }}; @Mock private IOService ioService; @Mock private FileSystem fileSystem; @Mock private org.uberfire.java.nio.file.Path rootPath; private VFSServicesServerImpl tested; private URI rootUri; @Before public void setup() throws Exception { rootUri = new URI(ROOT_URI); when(fileSystem.supportedFileAttributeViews()).thenReturn(FS_ATTRIBUTES); when(rootPath.toUri()).thenReturn(rootUri); when(rootPath.getFileSystem()).thenReturn(fileSystem); doAnswer((Answer) invocationOnMock -> { final URI arg = (URI) invocationOnMock.getArguments()[0]; return arg.toURL().toString().equals(ROOT_URI) ? rootPath : null; }).when(ioService).get(any(URI.class)); tested = new VFSServicesServerImpl(ioService); } @Test public void testGet() { final Path path = tested.get(ROOT_URI); assertEquals(ROOT_URI, path.toURI()); } @Test public void testNewDirectoryStream() { doAnswer((Answer>) invocationOnMock -> rootDirectoryStream) .when(ioService) .newDirectoryStream(any(org.uberfire.java.nio.file.Path.class)); final DirectoryStream paths = tested.newDirectoryStream(ROOT_PATH); final Path path = paths.iterator().next(); assertEquals(ROOT_PATH, path); } @Test @SuppressWarnings("unchecked") public void testNewDirectoryStreamFiltered() { final DirectoryStream.Filter filter = mock(DirectoryStream.Filter.class); doAnswer((Answer>) invocationOnMock -> { org.uberfire.java.nio.file.DirectoryStream.Filter argFilter = (org.uberfire.java.nio.file.DirectoryStream.Filter) invocationOnMock.getArguments()[1]; argFilter.accept(rootPath); return rootDirectoryStream; }) .when(ioService) .newDirectoryStream(any(org.uberfire.java.nio.file.Path.class), any(org.uberfire.java.nio.file.DirectoryStream.Filter.class)); final DirectoryStream paths = tested.newDirectoryStream(ROOT_PATH, filter); verify(filter, times(1)).accept(eq(ROOT_PATH)); final Path path = paths.iterator().next(); assertEquals(ROOT_PATH, path); } @Test public void testCreateDirectory() { tested.createDirectory(ROOT_PATH); verify(ioService, times(1)).createDirectory(any(org.uberfire.java.nio.file.Path.class)); } @Test @SuppressWarnings("unchecked") public void testCreateDirectoryWithAttributes() { final Map attributes = mock(Map.class); tested.createDirectory(ROOT_PATH, attributes); verify(ioService, times(1)) .createDirectory(any(org.uberfire.java.nio.file.Path.class), eq(attributes)); } @Test public void testCreateDirectories() { tested.createDirectories(ROOT_PATH); verify(ioService, times(1)).createDirectories(any(org.uberfire.java.nio.file.Path.class)); } @Test @SuppressWarnings("unchecked") public void testCreateDirectoriesWithAttributes() { final Map attributes = mock(Map.class); tested.createDirectories(ROOT_PATH, attributes); verify(ioService, times(1)) .createDirectories(any(org.uberfire.java.nio.file.Path.class), eq(attributes)); } @Test @SuppressWarnings("unchecked") public void testSetAttributes() { final Map attributes = mock(Map.class); tested.setAttributes(ROOT_PATH, attributes); verify(ioService, times(1)) .setAttributes(any(org.uberfire.java.nio.file.Path.class), eq(attributes)); } @Test public void testDelete() { tested.delete(ROOT_PATH); verify(ioService, times(1)).delete(any(org.uberfire.java.nio.file.Path.class)); } @Test public void testDeleteIfExists() { tested.deleteIfExists(ROOT_PATH); verify(ioService, times(1)).deleteIfExists(any(org.uberfire.java.nio.file.Path.class)); } @Test public void testCopy() { tested.copy(ROOT_PATH, ROOT_PATH); verify(ioService, times(1)) .copy(any(org.uberfire.java.nio.file.Path.class), any(org.uberfire.java.nio.file.Path.class)); } @Test public void testMove() { tested.move(ROOT_PATH, ROOT_PATH); verify(ioService, times(1)) .move(any(org.uberfire.java.nio.file.Path.class), any(org.uberfire.java.nio.file.Path.class)); } @Test public void testReadAllString() { tested.readAllString(ROOT_PATH); verify(ioService, times(1)).readAllString(any(org.uberfire.java.nio.file.Path.class)); } @Test public void testWrite() { final String content = "some-content-goes-here"; tested.write(ROOT_PATH, content); verify(ioService, times(1)) .write(any(org.uberfire.java.nio.file.Path.class), eq(content)); } @Test @SuppressWarnings("unchecked") public void testWriteWithAttributes() { final Map attributes = mock(Map.class); final String content = "some-content-goes-here"; tested.write(ROOT_PATH, content, attributes); verify(ioService, times(1)) .write(any(org.uberfire.java.nio.file.Path.class), eq(content), eq(attributes)); } private final org.uberfire.java.nio.file.DirectoryStream rootDirectoryStream = new org.uberfire.java.nio.file.DirectoryStream() { @Override public void close() throws IOException { } @Override public Iterator iterator() { return Collections.singletonList(rootPath).iterator(); } }; } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/WebAppSettingsTest.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. *

        * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

        * http://www.apache.org/licenses/LICENSE-2.0 *

        * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Paths; import org.junit.Test; import static org.junit.Assert.*; public class WebAppSettingsTest { String slash = FileSystems.getDefault().getSeparator(); @Test public void testLastSlashIgnored() { WebAppSettings.get().setRootDir("/test/"); String homeDir = WebAppSettings.get().getRootDir(); assertEquals(homeDir, slash + "test"); WebAppSettings.get().setRootDir("c:\\test\\"); homeDir = WebAppSettings.get().getRootDir(); assertEquals(homeDir, "c:" + slash + "test"); } @Test public void testRelativeDir() { WebAppSettings.get().setRootDir("test"); Path myFile = WebAppSettings.get().getAbsolutePath("mydir", "myfile"); assertEquals(myFile, Paths.get("test", "mydir", "myfile")); } @Test public void testEmptyDir() { WebAppSettings.get().setRootDir(null); Path myDir = WebAppSettings.get().getAbsolutePath("mydir"); assertNull(myDir); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/authz/AuthorizationServiceTest.java ================================================ /** * Copyright 2020 Red Hat, Inc. and/or its affiliates. *

        * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

        * http://www.apache.org/licenses/LICENSE-2.0 *

        * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import javax.enterprise.event.Event; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.backend.events.AuthorizationPolicyDeployedEvent; import org.uberfire.backend.events.AuthorizationPolicySavedEvent; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.authz.PermissionTypeRegistry; import org.uberfire.security.impl.authz.DefaultPermissionManager; import org.uberfire.security.impl.authz.DefaultPermissionTypeRegistry; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class AuthorizationServiceTest { AuthorizationServiceImpl authorizationService; AuthorizationPolicyDeployer deployer; @Mock AuthorizationPolicyStorage storage; @Mock Event event; @Mock Event policySavedEvent; PermissionManager permissionManager; private static final String path = "WEB-INF/classes/security-policy.properties"; @Before public void setUp(){ PermissionTypeRegistry permissionTypeRegistry = new DefaultPermissionTypeRegistry(); permissionManager = spy(new DefaultPermissionManager(permissionTypeRegistry)); deployer = new AuthorizationPolicyDeployer(storage, permissionManager, event); authorizationService = new AuthorizationServiceImpl(storage, permissionManager, policySavedEvent); } @Test public void testPolicyLoad() throws Exception { getPolicyFromPath(path); } @Test public void testPolicySave() throws Exception { Path policyDir = getPolicyFromPath(path); deployer.deployPolicy(policyDir); ArgumentCaptor policyCaptor = ArgumentCaptor.forClass(AuthorizationPolicy.class); verify(storage).loadPolicy(); verify(storage).savePolicy(policyCaptor.capture()); AuthorizationPolicy ap = policyCaptor.getValue(); authorizationService.savePolicy(ap); verify(permissionManager, times(2)).setAuthorizationPolicy(ap); verify(policySavedEvent).fire(any()); } @Test public void testPolicyDelete() throws Exception { Path policyDir = getPolicyFromPath(path); deployer.deployPolicy(policyDir); ArgumentCaptor policyCaptor = ArgumentCaptor.forClass(AuthorizationPolicy.class); verify(storage).loadPolicy(); verify(storage).savePolicy(policyCaptor.capture()); AuthorizationPolicy ap = policyCaptor.getValue(); Group group = new GroupImpl("group1"); authorizationService.deletePolicyByGroup(group, ap); verify(storage).deletePolicyByGroup(group, ap); verify(permissionManager, times(2)).setAuthorizationPolicy(any()); verify(policySavedEvent, times(1)).fire(any()); } private Path getPolicyFromPath(String path) throws Exception { URL fileURL = Thread.currentThread().getContextClassLoader().getResource(path); Path policyDir = Paths.get(fileURL.toURI()).getParent(); assertNotNull(policyDir); return policyDir; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/authz/AuthzPolicyDeployerTest.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. *

        * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

        * http://www.apache.org/licenses/LICENSE-2.0 *

        * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import java.io.IOException; import java.net.URI; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Set; import javax.enterprise.event.Event; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.authz.AuthorizationPolicyStorage; import org.uberfire.backend.events.AuthorizationPolicyDeployedEvent; import org.uberfire.backend.server.WebAppSettings; import org.uberfire.backend.server.security.RoleRegistry; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.mocks.FileSystemTestingUtils; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.AuthorizationResult; import org.uberfire.security.authz.Permission; import org.uberfire.security.authz.PermissionCollection; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.authz.PermissionTypeRegistry; import org.uberfire.security.impl.authz.DefaultPermissionManager; import org.uberfire.security.impl.authz.DefaultPermissionTypeRegistry; import org.uberfire.spaces.SpacesAPI; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class AuthzPolicyDeployerTest { @Mock protected SpacesAPI spaces; @Mock AuthorizationPolicyStorage storage; AuthorizationPolicyVfsStorage vfsstorage; private FileSystem fileSystem; @Mock Event event; private static FileSystemTestingUtils fileSystemTestingUtils = new FileSystemTestingUtils(); AuthorizationPolicyDeployer deployer; PermissionManager permissionManager; IOService ioService; @Before public void setUp() throws IOException { fileSystemTestingUtils.setup(); fileSystem = fileSystemTestingUtils.getFileSystem(); ioService = spy(fileSystemTestingUtils.getIoService()); doNothing().when(ioService).endBatch(); doReturn(fileSystem).when(ioService).newFileSystem(any(), anyMap()); PermissionTypeRegistry permissionTypeRegistry = new DefaultPermissionTypeRegistry(); permissionManager = spy(new DefaultPermissionManager(permissionTypeRegistry)); vfsstorage = new AuthorizationPolicyVfsStorage(ioService, permissionManager, spaces); deployer = new AuthorizationPolicyDeployer(storage, permissionManager, event); vfsstorage.initFileSystem(); RoleRegistry.get().clear(); } @Test public void testPolicyDir() { WebAppSettings.get().setRootDir("/test"); Path path = deployer.getPolicyDir(); Path expected = Paths.get(URI.create("file:///test/WEB-INF/classes")); assertEquals(path, expected); } @Test public void testInvalidPolicy() { assertThatThrownBy(() -> testPolicyLoad("WEB-INF/classes/invalid/security-policy.properties")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Key must start with [default|role|group]"); } @Test public void testPolicyLoad() throws Exception { testPolicyLoad("WEB-INF/classes/security-policy.properties"); } @Test public void testPolicyLoad2() throws Exception { testPolicyLoad("WEB-INF/classes/split/security-policy.properties"); } @Test public void testPolicyDelete() throws Exception { testPolicyDelete("WEB-INF/classes/security-policy.properties"); } public void testPolicyDelete(String path) throws Exception { URL fileURL = Thread.currentThread().getContextClassLoader().getResource(path); Path policyDir = Paths.get(fileURL.toURI()).getParent(); assertTrue(RoleRegistry.get().getRegisteredRoles().isEmpty()); deployer.deployPolicy(policyDir); ArgumentCaptor policyCaptor = ArgumentCaptor.forClass(AuthorizationPolicy.class); verify(storage).loadPolicy(); verify(storage).savePolicy(policyCaptor.capture()); vfsstorage.savePolicy(policyCaptor.getValue()); AuthorizationPolicy policy = vfsstorage.loadPolicyFromVfs(); Set groups = policy.getGroups(); assertEquals(1, groups.size()); Group group = new GroupImpl("group1"); PermissionCollection permissions = policy.getPermissions(group); Permission permission = permissions.get("perspective.read"); assertNotNull(permission); assertEquals(AuthorizationResult.ACCESS_GRANTED, permission.getResult()); vfsstorage.deletePolicyByGroup(group, policyCaptor.getValue()); verify(event).fire(any()); policy = vfsstorage.loadPolicyFromVfs(); groups = policy.getGroups(); assertEquals(0, groups.size()); } public void testPolicyLoad(String path) throws Exception { URL fileURL = Thread.currentThread().getContextClassLoader().getResource(path); Path policyDir = Paths.get(fileURL.toURI()).getParent(); assertTrue(RoleRegistry.get().getRegisteredRoles().isEmpty()); deployer.deployPolicy(policyDir); ArgumentCaptor policyCaptor = ArgumentCaptor.forClass(AuthorizationPolicy.class); verify(storage).loadPolicy(); verify(storage).savePolicy(policyCaptor.capture()); verify(event).fire(any()); AuthorizationPolicy policy = policyCaptor.getValue(); verify(permissionManager).setAuthorizationPolicy(policy); assertEquals(RoleRegistry.get().getRegisteredRoles().size(), 3); Set roles = policy.getRoles(); assertEquals(roles.size(), 3); Role adminRole = new RoleImpl("admin"); PermissionCollection permissions = policy.getPermissions(adminRole); assertTrue(roles.contains(adminRole)); assertEquals(policy.getRoleDescription(adminRole), "Administrator"); assertEquals(policy.getPriority(adminRole), 1); assertEquals(permissions.collection().size(), 3); Permission permission = permissions.get("perspective.read"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); permission = permissions.get("perspective.read.SimplePerspective"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_DENIED); Role userRole = new RoleImpl("user"); permissions = policy.getPermissions(userRole); assertTrue(roles.contains(userRole)); assertEquals(policy.getRoleDescription(userRole), "End user"); assertEquals(policy.getPriority(userRole), 2); assertEquals(permissions.collection().size(), 4); permission = permissions.get("perspective.read"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_DENIED); permission = permissions.get("perspective.read.HomePerspective"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); permission = permissions.get("perspective.read.SimplePerspective"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); Role managerRole = new RoleImpl("manager"); permissions = policy.getPermissions(managerRole); assertTrue(roles.contains(managerRole)); assertEquals(policy.getRoleDescription(managerRole), "Manager"); assertEquals(policy.getPriority(managerRole), 3); assertEquals(permissions.collection().size(), 3); permission = permissions.get("perspective.read"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); permission = permissions.get("repository.read.git://repo1"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); } @Test public void testNothingToDeploy() { deployer.deployPolicy(null); verify(storage, never()).loadPolicy(); verify(storage, never()).savePolicy(any()); } @Test public void testAlreadyDeployed() { when(storage.loadPolicy()).thenReturn(mock(AuthorizationPolicy.class)); deployer.deployPolicy(Paths.get("")); verify(storage).loadPolicy(); verify(storage, never()).savePolicy(any()); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/authz/AuthzPolicyMarshallerTest.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. *

        * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

        * http://www.apache.org/licenses/LICENSE-2.0 *

        * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.authz; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.stream.Collectors; import java.util.stream.Stream; import org.jboss.errai.security.shared.api.Group; import org.jboss.errai.security.shared.api.GroupImpl; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; import org.jboss.errai.security.shared.api.identity.User; import org.junit.Before; import org.junit.Test; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.AuthorizationResult; import org.uberfire.security.authz.Permission; import org.uberfire.security.authz.PermissionCollection; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.authz.VotingStrategy; import org.uberfire.security.impl.authz.AuthorizationPolicyBuilder; import org.uberfire.security.impl.authz.DefaultPermissionManager; import org.uberfire.security.impl.authz.DefaultPermissionTypeRegistry; import static org.assertj.core.api.Assertions.assertThatThrownBy; 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.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class AuthzPolicyMarshallerTest { AuthorizationPolicyBuilder builder; AuthorizationPolicyMarshaller marshaller; PermissionManager permissionManager; @Before public void setUp() { permissionManager = new DefaultPermissionManager(new DefaultPermissionTypeRegistry()); builder = permissionManager.newAuthorizationPolicy(); marshaller = new AuthorizationPolicyMarshaller(); } protected User createUserMock(String... roles) { User user = mock(User.class); Set roleSet = Stream.of(roles).map(RoleImpl::new).collect(Collectors.toSet()); when(user.getRoles()).thenReturn(roleSet); when(user.getGroups()).thenReturn(null); return user; } @Test public void testDefaultHomeEntry() { AuthorizationPolicyMarshaller.Key key = marshaller.parse("default.home"); assertTrue(key.isDefault()); assertEquals(key.getAttributeType(), "home"); } @Test public void testDefaultPermissionEntry() { AuthorizationPolicyMarshaller.Key key = marshaller.parse("default.permission.perspective.read"); assertTrue(key.isDefault()); assertEquals(key.getAttributeType(), "permission"); assertEquals(key.getAttributeId(), "perspective.read"); } @Test public void testOverwriteDefault() { Map input = new HashMap<>(); input.put("default.permission.perspective.read", "false"); input.put("default.permission.perspective.read.HomePerspective", "true"); input.put("role.user.permission.perspective.read", "false"); input.put("role.user.permission.perspective.read.HomePerspective", "true"); input.put("role.user.permission.perspective.read.Sales dashboard", "true"); marshaller.read(builder, input); permissionManager.setAuthorizationPolicy(builder.build()); User user = createUserMock("user", "manager"); PermissionCollection pc = permissionManager.resolvePermissions(user, VotingStrategy.PRIORITY); assertEquals(pc.collection().size(), 3); assertEquals(pc.get("perspective.read").getResult(), AuthorizationResult.ACCESS_DENIED); assertEquals(pc.get("perspective.read.HomePerspective").getResult(), AuthorizationResult.ACCESS_GRANTED); assertEquals(pc.get("perspective.read.Sales dashboard").getResult(), AuthorizationResult.ACCESS_GRANTED); } @Test public void testDefaultPermissionsNotOverwrite() { Map input = new HashMap<>(); input.put("default.permission.perspective.read.p1", "false"); input.put("default.permission.perspective.read.p2", "false"); input.put("role.user.permission.perspective.read", "true"); input.put("role.user.permission.perspective.read.p2", "false"); marshaller.read(builder, input); permissionManager.setAuthorizationPolicy(builder.build()); User user = createUserMock("user"); PermissionCollection pc = permissionManager.resolvePermissions(user, VotingStrategy.PRIORITY); assertEquals(pc.collection().size(), 2); assertEquals(pc.get("perspective.read").getResult(), AuthorizationResult.ACCESS_GRANTED); assertNull(pc.get("perspective.read.p1")); assertEquals(pc.get("perspective.read.p2").getResult(), AuthorizationResult.ACCESS_DENIED); } @Test public void testHomeEntry() { AuthorizationPolicyMarshaller.Key key = marshaller.parse("role.admin.home"); assertTrue(key.isRole()); assertEquals(key.getRole(), "admin"); assertEquals(key.getAttributeType(), "home"); assertNull(key.getAttributeId()); } @Test public void testGroupEntry() { AuthorizationPolicyMarshaller.Key key = marshaller.parse("group.IT.home"); assertFalse(key.isRole()); assertTrue(key.isGroup()); assertEquals(key.getGroup(), "IT"); assertEquals(key.getAttributeType(), "home"); assertNull(key.getAttributeId()); } @Test public void testPriorityEntry() { AuthorizationPolicyMarshaller.Key key = marshaller.parse("role.admin.priority"); assertTrue(key.isRole()); assertEquals(key.getRole(), "admin"); assertEquals(key.getAttributeType(), "priority"); assertNull(key.getAttributeId()); } @Test public void testPermissionEntry() { AuthorizationPolicyMarshaller.Key key = marshaller.parse("role.admin.permission.perspective.read"); assertTrue(key.isRole()); assertEquals(key.getRole(), "admin"); assertEquals(key.getAttributeType(), "permission"); assertEquals(key.getAttributeId(), "perspective.read"); } @Test public void testSpecialCharsAllowed() { AuthorizationPolicyMarshaller.Key key = marshaller.parse("role.manager.permission.repository.update.git://repo1"); assertTrue(key.isRole()); assertEquals(key.getRole(), "manager"); assertEquals(key.getAttributeType(), "permission"); assertEquals(key.getAttributeId(), "repository.update.git://repo1"); } @Test public void testRoleMissing() { assertThatThrownBy(() -> marshaller.parse("role..priority")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Role value is empty"); } @Test public void testTypeMissing() { assertThatThrownBy(() -> marshaller.parse(".admin.priority")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Key must start with [default|role|group]"); } @Test public void testIncompleteEntry() { assertThatThrownBy(() -> marshaller.parse("role")) .isInstanceOf(IllegalArgumentException.class) .hasMessage("Role value is empty"); } @Test public void testReadDefaultEntries() { AuthorizationPolicy policy = builder.bydefault().home("B") .permission("p1", false) .permission("p2", true) .role("admin") .permission("p1", true) .build(); String home = policy.getHomePerspective(); PermissionCollection pc = policy.getPermissions(); assertEquals(home, "B"); assertEquals(pc.collection().size(), 2); assertNotNull(pc.get("p1")); assertNotNull(pc.get("p2")); assertEquals(pc.get("p1").getResult(), AuthorizationResult.ACCESS_DENIED); assertEquals(pc.get("p2").getResult(), AuthorizationResult.ACCESS_GRANTED); Role admin = new RoleImpl("admin"); home = policy.getHomePerspective(admin); pc = policy.getPermissions(admin); assertEquals(home, "B"); assertEquals(pc.collection().size(), 2); assertNotNull(pc.get("p1")); assertNotNull(pc.get("p2")); assertEquals(pc.get("p1").getResult(), AuthorizationResult.ACCESS_GRANTED); assertEquals(pc.get("p2").getResult(), AuthorizationResult.ACCESS_GRANTED); } @Test public void testPolicyRead() throws Exception { URL fileURL = Thread.currentThread().getContextClassLoader().getResource("WEB-INF/classes/security-policy.properties"); Path policyPath = Paths.get(fileURL.toURI()); NonEscapedProperties input = new NonEscapedProperties(); input.load(Files.newBufferedReader(policyPath)); marshaller.read(builder, input); AuthorizationPolicy policy = builder.build(); Set roles = policy.getRoles(); assertEquals(roles.size(), 3); Role adminRole = new RoleImpl("admin"); PermissionCollection permissions = policy.getPermissions(adminRole); assertTrue(roles.contains(adminRole)); assertEquals(policy.getRoleDescription(adminRole), "Administrator"); assertEquals(policy.getPriority(adminRole), 1); assertEquals(permissions.collection().size(), 3); Permission permission = permissions.get("perspective.read"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); permission = permissions.get("perspective.read.SimplePerspective"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_DENIED); Role userRole = new RoleImpl("user"); permissions = policy.getPermissions(userRole); assertTrue(roles.contains(userRole)); assertEquals(policy.getRoleDescription(userRole), "End user"); assertEquals(policy.getPriority(userRole), 2); assertEquals(permissions.collection().size(), 4); permission = permissions.get("perspective.read"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_DENIED); permission = permissions.get("perspective.read.HomePerspective"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); permission = permissions.get("perspective.read.SimplePerspective"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); Role managerRole = new RoleImpl("manager"); permissions = policy.getPermissions(managerRole); assertTrue(roles.contains(managerRole)); assertEquals(policy.getRoleDescription(managerRole), "Manager"); assertEquals(policy.getPriority(managerRole), 3); assertEquals(permissions.collection().size(), 3); permission = permissions.get("perspective.read"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); permission = permissions.get("repository.read.git://repo1"); assertNotNull(permission); assertEquals(permission.getResult(), AuthorizationResult.ACCESS_GRANTED); } @Test public void testPolicyWrite() { builder.role("admin").priority(5).home("A") .permission("p1", true) .permission("p2", false) .group("group1").priority(3).home("B") .permission("p1", false) .permission("p2", true) .bydefault().home("B") .permission("p1", false) .permission("p2", true); AuthorizationPolicy policy = builder.build(); TreeMap output = new TreeMap<>(); marshaller.write(policy, output); assertEquals(output.size(), 11); assertEquals(output.get("role.admin.home"), "A"); assertEquals(output.get("role.admin.home"), "A"); assertEquals(output.get("role.admin.priority"), "5"); assertEquals(output.get("role.admin.permission.p1"), "true"); assertEquals(output.get("role.admin.permission.p2"), "false"); assertEquals(output.get("group.group1.home"), "B"); assertEquals(output.get("group.group1.priority"), "3"); assertEquals(output.get("group.group1.permission.p1"), "false"); assertEquals(output.get("group.group1.permission.p2"), "true"); assertEquals(output.get("default.home"), "B"); assertEquals(output.get("default.permission.p1"), "false"); assertEquals(output.get("default.permission.p2"), "true"); } @Test public void testPolicyRemove() { builder.group("group2").priority(3).home("B") .permission("p1", false) .permission("p2", true); AuthorizationPolicy policy = builder.build(); TreeMap output = new TreeMap<>(); marshaller.write(policy, output); Group g = new GroupImpl("group2"); assertEquals("B", output.get("group.group2.home")); assertEquals("3", output.get("group.group2.priority")); assertEquals("false", output.get("group.group2.permission.p1")); assertEquals("true", output.get("group.group2.permission.p2")); marshaller.remove(g, policy, output); assertEquals(null, output.get("group.group2.home")); assertEquals(null, output.get("group.group2.priority")); assertEquals(null, output.get("group.group2.permission.p1")); assertEquals(null, output.get("group.group2.permission.p2")); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/io/JGitFileSystemLazyCacheTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io; import java.io.File; import java.io.IOException; import java.net.URI; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.fs.jgit.JGitFileSystemProxy; import org.uberfire.mocks.FileSystemTestingUtils; import static org.junit.Assert.*; public class JGitFileSystemLazyCacheTest { private static FileSystemTestingUtils fsUtils = new FileSystemTestingUtils(); static { System.out.println("Working Dir: " + new File("").getAbsoluteFile().getAbsolutePath()); } @Before public void setup() throws IOException { System.setProperty("org.uberfire.nio.jgit.cache.instances", "2"); fsUtils.setup(false); } @After public void cleanupFileSystem() { fsUtils.cleanup(); System.clearProperty("org.uberfire.nio.jgit.cache.instances"); } @Test public void basicCache() throws IOException { String repoName = "amend-repo-test"; Path firstWrite = fsUtils.getIoService().get(URI.create("git://" + repoName + "/init1.file")); String content = "dora!"; Path secondWrite = fsUtils.getIoService().get(URI.create("git://" + repoName + "/init2.file")); fsUtils.getIoService().write(firstWrite, content); String jgitcontent = fsUtils.getIoService().readAllString(firstWrite); assertEquals(content, jgitcontent); fsUtils.getIoService().write(secondWrite, content); JGitFileSystemProxy fileSystem = (JGitFileSystemProxy) firstWrite.getFileSystem(); JGitFileSystemProxy fileSystem1 = (JGitFileSystemProxy) secondWrite.getFileSystem(); assertEquals(fileSystem, fileSystem1); } @Test public void regenerateFSCache() throws IOException { String defaultRepo = "git://amend-repo-test"; Path firstWriteFS1 = fsUtils.getIoService().get(URI.create(defaultRepo + "/init1.file")); FileSystem fileSystem1Instance1 = firstWriteFS1.getFileSystem(); String dora1 = "dora1"; String dora2 = "dora2"; fsUtils.getIoService().write(firstWriteFS1, dora1); fsUtils.setupJGitRepository(defaultRepo + "2", false); Path writeFS2 = fsUtils.getIoService().get(URI.create(defaultRepo + "2" + "/init1.file")); fsUtils.getIoService().write(writeFS2, dora1); fsUtils.setupJGitRepository(defaultRepo + "3", false); Path writeFS3 = fsUtils.getIoService().get(URI.create(defaultRepo + "3" + "/init1.file")); fsUtils.getIoService().write(writeFS3, dora1); //memoized cache size == 2 , so fsUtils.setupJGitRepository(defaultRepo, false); Path secondWriteFS1 = fsUtils.getIoService().get(URI.create(defaultRepo + "/init2.file")); fsUtils.getIoService().write(secondWriteFS1, dora2); FileSystem fileSystem1Instance2 = secondWriteFS1.getFileSystem(); //not equals because we have to regenerate, but still represent the same FS assertTrue(System.identityHashCode(fileSystem1Instance1) != System.identityHashCode(fileSystem1Instance2)); assertTrue(fileSystem1Instance1.hashCode() == fileSystem1Instance2.hashCode()); assertEquals(fileSystem1Instance1, fileSystem1Instance2); //let's remove fs1 again from cache fsUtils.setupJGitRepository(defaultRepo + "5", false); fsUtils.setupJGitRepository(defaultRepo + "6", false); //read to see if all the writes are fine on fs1 String actual1 = fsUtils.getIoService().readAllString(fsUtils.getIoService().get(URI.create(defaultRepo + "/init1.file"))); String actual2 = fsUtils.getIoService().readAllString(fsUtils.getIoService().get(URI.create(defaultRepo + "/init2.file"))); assertEquals(dora1, actual1); assertEquals(dora2, actual2); } @Test public void branchingTest() throws IOException { FileSystem fileSystem = fsUtils.setupJGitRepository("git://dora-repo", true); fsUtils.getProvider().forceAsDefault(); Path branchPath = fileSystem.getPath("branch", "dir"); Path pathOnBranch = branchPath.resolve("test.file"); String expected = "dora"; fsUtils.getIoService().write(pathOnBranch, expected); String actual = fsUtils.getIoService().readAllString(branchPath.resolve("test.file")); assertEquals(expected, actual); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/io/object/ObjectStorageTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.object; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.uberfire.io.IOService; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.mocks.FileSystemTestingUtils; import org.uberfire.mocks.SessionInfoMock; import org.uberfire.rpc.SessionInfo; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Mockito.*; public class ObjectStorageTest { private static FileSystemTestingUtils fileSystemTestingUtils = new FileSystemTestingUtils(); static { System.setProperty("errai.devel.nocache", "true"); System.out.println("Working Dir: " + new File("").getAbsoluteFile().getAbsolutePath()); } private IOService ioService; private FileSystem fileSystem; private SessionInfo sessionInfo; private ObjectStorageImpl objectStorage; @Before public void setup() throws IOException { fileSystemTestingUtils.setup(); sessionInfo = mockSessionInfo(); fileSystem = mockFileSystem(); ioService = mockIoService(fileSystem); objectStorage = new ObjectStorageImpl(ioService); objectStorage.init(URI.create("default://object/store")); } @After public void cleanupFileSystem() { fileSystemTestingUtils.cleanup(); } @Test public void testForAFileDoesNotExist() { final String file = "my.object.file"; final boolean objectExists = objectStorage.exists("/forks/" + file); assertFalse(objectExists); } @Test public void testWriteFileAndCheckThatExists() { objectStorage.write("/forks/uberfire.txt", "content"); boolean exists = objectStorage.exists("/forks/uberfire.txt"); assertTrue(exists); } @Test public void testWriteAndRead() { final String fileContent = "content"; objectStorage.write("/forks/uberfire", fileContent); String content = objectStorage.read("/forks/uberfire"); assertEquals(fileContent, content); } @Test public void testWriteAndReadList() { final ArrayList fileContent = new ArrayList(); fileContent.add("uberfire"); objectStorage.write("/forks/uberfire", fileContent); List content = objectStorage.read("/forks/uberfire"); assertEquals(fileContent.size(), content.size()); assertEquals(fileContent.get(0), content.get(0)); } @Test public void testWithDoubleSlashPath() { final String fileContent = "content"; objectStorage.write("/forks/uberfire", fileContent); String content = objectStorage.read("/forks/uberfire"); assertEquals(fileContent, content); } @Test public void testWriteTwoTimes() { objectStorage.write("/forks/uberfire", "content a"); objectStorage.write("/forks/uberfire", "content b"); String content = objectStorage.read("/forks/uberfire"); assertEquals("content b", content); } @Test public void testWriteAndDelete() { objectStorage.write("/forks/uberfire", "content b"); assertTrue(objectStorage.exists("/forks/uberfire")); objectStorage.delete("/forks/uberfire"); assertFalse(objectStorage.exists("/forks/uberfire")); } private SessionInfo mockSessionInfo() { return new SessionInfoMock(); } private FileSystem mockFileSystem() { return fileSystemTestingUtils.getFileSystem(); } private IOService mockIoService(final FileSystem fileSystem) { final IOService ioService = spy(fileSystemTestingUtils.getIoService()); doNothing().when(ioService).startBatch(any(FileSystem.class)); doNothing().when(ioService).endBatch(); doReturn(fileSystem).when(ioService).newFileSystem(any(URI.class), anyMap()); return ioService; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/io/watch/AbstractIOWatchServiceTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.watch; import java.lang.reflect.Field; import java.util.List; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.util.Filter; import org.uberfire.commons.async.DescriptiveThreadFactory; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.file.ClosedWatchServiceException; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.InterruptedException; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.java.nio.file.WatchKey; import org.uberfire.java.nio.file.WatchService; import org.uberfire.java.nio.file.Watchable; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; @RunWith(MockitoJUnitRunner.class) public class AbstractIOWatchServiceTest { @Test public void testAddWatchServiceException() { // BZ1323572 try { System.setProperty("org.uberfire.watcher.autostart", "false"); AbstractIOWatchService service = new AbstractIOWatchService(null, null, null, null, null, Executors.newCachedThreadPool(new DescriptiveThreadFactory())) { @Override public boolean doFilter(WatchEvent t) { return false; } }; WatchService ws = new WatchService() { @Override public void close() throws IOException { } @Override public WatchKey poll() throws ClosedWatchServiceException { return null; } @Override public WatchKey poll(long timeout, TimeUnit unit) throws ClosedWatchServiceException, InterruptedException { return null; } @Override public WatchKey take() throws ClosedWatchServiceException, InterruptedException { return new WatchKey() { @Override public boolean isValid() { return false; } @Override public List> pollEvents() { return null; } @Override public boolean reset() { return false; // exit the loop in asyncWatchService.execute() } @Override public void cancel() { } @Override public Watchable watchable() { return null; } }; } @Override public boolean isClose() { return false; } }; service.addWatchService(mock(FileSystem.class), ws); Set watchThreads = null; try { Field field = AbstractIOWatchService.class.getDeclaredField("watchThreads"); field.setAccessible(true); watchThreads = (Set) field.get(service); } catch (Exception e) { fail(e.getMessage()); } AsyncWatchService asyncWatchService = watchThreads.iterator().next(); IOWatchServiceExecutor wsExecutor = (watchKey, filter) -> { throw new RuntimeException("dummy"); }; try { asyncWatchService.execute(wsExecutor); assertTrue(true); } catch (Exception e) { fail("Exception is thrown from asyncWatchService.execute()"); } } finally { System.clearProperty("org.uberfire.watcher.autostart"); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/io/watch/IOWatchServiceExecutorImplTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.io.watch; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.util.Filter; import org.uberfire.java.nio.base.WatchContext; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.StandardWatchEventKind; import org.uberfire.java.nio.file.WatchEvent; import org.uberfire.java.nio.file.WatchKey; import org.uberfire.mocks.EventSourceMock; import org.uberfire.workbench.events.ResourceAddedEvent; import org.uberfire.workbench.events.ResourceBatchChangesEvent; import org.uberfire.workbench.events.ResourceChange; import org.uberfire.workbench.events.ResourceChangeType; import org.uberfire.workbench.events.ResourceDeletedEvent; import org.uberfire.workbench.events.ResourceRenamedEvent; import org.uberfire.workbench.events.ResourceUpdatedEvent; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class IOWatchServiceExecutorImplTest { private static final String COMMIT_MESSAGE = "COMMIT_MESSAGE"; private static final String SESSION_ID = "SESSION_ID"; private static final String USER = "USER"; private static final String ORIGINAL_FILE1_URI = "file:///originalPath/OriginalFile1.java"; private static final String NEW_FILE1_URI = "file:///newFilePath/NewFile1.java"; private static final String ORIGINAL_FILE2_URI = "file:///originalPath/OriginalFile2.java"; private static final String NEW_FILE2_URI = "file:///newFilePath/NewFile2.java"; private static final String ORIGINAL_FILE3_URI = "file:///originalPath/OriginalFile3.java"; private static final String NEW_FILE3_URI = "file:///newFilePath/NewFile3.java"; private static final String ORIGINAL_FILE4_URI = "file:///originalPath/OriginalFile4.java"; private static final String NEW_FILE4_URI = "file:///newFilePath/NewFile4.java"; @Mock private EventSourceMock resourceBatchChanges; @Mock private EventSourceMock resourceUpdatedEvent; @Mock private EventSourceMock resourceRenamedEvent; @Mock private EventSourceMock resourceDeletedEvent; @Mock private EventSourceMock resourceAddedEvent; @Captor private ArgumentCaptor resourceUpdatedEventCaptor; @Captor private ArgumentCaptor resourceDeletedEventCaptor; @Captor private ArgumentCaptor resourceAddedEventCaptor; @Captor private ArgumentCaptor resourceRenamedEventCaptor; @Captor private ArgumentCaptor resourceBatchChangesEventCaptor; private IOWatchServiceExecutorImpl watchServiceExecutor; @Before public void setUp() { watchServiceExecutor = new IOWatchServiceExecutorImpl(); watchServiceExecutor.setEvents(resourceBatchChanges, resourceUpdatedEvent, resourceRenamedEvent, resourceDeletedEvent, resourceAddedEvent); } @Test public void testSingleEventModify() throws Exception { testSingleEvent(StandardWatchEventKind.ENTRY_MODIFY, ORIGINAL_FILE1_URI, NEW_FILE1_URI, SESSION_ID, USER, COMMIT_MESSAGE); } @Test public void testSingleEventDelete() throws Exception { testSingleEvent(StandardWatchEventKind.ENTRY_DELETE, ORIGINAL_FILE1_URI, NEW_FILE1_URI, SESSION_ID, USER, COMMIT_MESSAGE); } @Test public void testSingleEventCreate() throws Exception { testSingleEvent(StandardWatchEventKind.ENTRY_CREATE, ORIGINAL_FILE1_URI, NEW_FILE1_URI, SESSION_ID, USER, COMMIT_MESSAGE); } @Test public void testSingleEventRename() throws Exception { testSingleEvent(StandardWatchEventKind.ENTRY_RENAME, ORIGINAL_FILE1_URI, NEW_FILE1_URI, SESSION_ID, USER, COMMIT_MESSAGE); } @SuppressWarnings("unchecked") @Test public void testMultipleEvents() throws Exception { List> events = new ArrayList<>(); //file1 modified events.add(mockWatchEvent(StandardWatchEventKind.ENTRY_MODIFY, ORIGINAL_FILE1_URI, NEW_FILE1_URI, SESSION_ID, USER, COMMIT_MESSAGE)); //file1 renamed events.add(mockWatchEvent(StandardWatchEventKind.ENTRY_RENAME, ORIGINAL_FILE1_URI, NEW_FILE1_URI, SESSION_ID, USER, COMMIT_MESSAGE)); //file 2 added events.add(mockWatchEvent(StandardWatchEventKind.ENTRY_CREATE, ORIGINAL_FILE2_URI, NEW_FILE2_URI, SESSION_ID, USER, COMMIT_MESSAGE)); //file 3 removed events.add(mockWatchEvent(StandardWatchEventKind.ENTRY_DELETE, ORIGINAL_FILE3_URI, NEW_FILE3_URI, SESSION_ID, USER, COMMIT_MESSAGE)); //file 4 added events.add(mockWatchEvent(StandardWatchEventKind.ENTRY_CREATE, ORIGINAL_FILE4_URI, NEW_FILE4_URI, SESSION_ID, USER, COMMIT_MESSAGE)); //file 4 modified events.add(mockWatchEvent(StandardWatchEventKind.ENTRY_MODIFY, ORIGINAL_FILE4_URI, NEW_FILE4_URI, SESSION_ID, USER, COMMIT_MESSAGE)); //file 4 deleted events.add(mockWatchEvent(StandardWatchEventKind.ENTRY_DELETE, ORIGINAL_FILE4_URI, NEW_FILE4_URI, SESSION_ID, USER, COMMIT_MESSAGE)); WatchKey watchKey = mock(WatchKey.class); Filter> filter = mock(Filter.class); when(watchKey.pollEvents()).thenReturn(events); when(filter.doFilter(any(WatchEvent.class))).thenReturn(false); watchServiceExecutor.execute(watchKey, filter); verify(resourceBatchChanges).fire(resourceBatchChangesEventCaptor.capture()); //verify file1 was modified verifyResourceChange(resourceBatchChangesEventCaptor.getValue(), ORIGINAL_FILE1_URI, COMMIT_MESSAGE, ResourceChangeType.UPDATE); //verify file1 was renamed verifyResourceChange(resourceBatchChangesEventCaptor.getValue(), ORIGINAL_FILE1_URI, COMMIT_MESSAGE, ResourceChangeType.RENAME); //verify file2 was added verifyResourceChange(resourceBatchChangesEventCaptor.getValue(), NEW_FILE2_URI, COMMIT_MESSAGE, ResourceChangeType.ADD); //verify file3 was removed verifyResourceChange(resourceBatchChangesEventCaptor.getValue(), ORIGINAL_FILE3_URI, COMMIT_MESSAGE, ResourceChangeType.DELETE); //verify file4 was added verifyResourceChange(resourceBatchChangesEventCaptor.getValue(), NEW_FILE4_URI, COMMIT_MESSAGE, ResourceChangeType.ADD); //verify file4 was modified verifyResourceChange(resourceBatchChangesEventCaptor.getValue(), ORIGINAL_FILE4_URI, COMMIT_MESSAGE, ResourceChangeType.UPDATE); //verify file4 was deleted verifyResourceChange(resourceBatchChangesEventCaptor.getValue(), ORIGINAL_FILE4_URI, COMMIT_MESSAGE, ResourceChangeType.DELETE); } private void verifyResourceChange(ResourceBatchChangesEvent resourceBatchChanges, String originalFile1Uri, String commitMessage, ResourceChangeType changeType) { Optional> expectedResourceChanges = resourceBatchChanges.getBatch().entrySet() .stream() .filter(entry -> originalFile1Uri.equals(entry.getKey().toURI())) .map(Map.Entry::getValue) .findFirst() .filter(resourceChanges -> resourceChanges.stream() .filter(resourceChange -> resourceChange.getType().equals(changeType) && resourceChange.getMessage().equals(commitMessage)) .findFirst().isPresent()); assertTrue("Change " + changeType.name() + " was not found for resource: " + originalFile1Uri, expectedResourceChanges.isPresent()); } @SuppressWarnings("unchecked") public void testSingleEvent(WatchEvent.Kind kind, String originalPathURI, String newPathURI, String sessionId, String userId, String commitMessage) throws Exception { WatchKey watchKey = mock(WatchKey.class); Filter> filter = mock(Filter.class); List> events = new ArrayList<>(); events.add(mockWatchEvent(kind, originalPathURI, newPathURI, sessionId, userId, commitMessage)); when(watchKey.pollEvents()).thenReturn(events); when(filter.doFilter(any(WatchEvent.class))).thenReturn(false); watchServiceExecutor.execute(watchKey, filter); if (kind == StandardWatchEventKind.ENTRY_MODIFY) { verifyResourceUpdatedEvent(originalPathURI, sessionId, userId, commitMessage); } else if (kind == StandardWatchEventKind.ENTRY_DELETE) { verifyResourceDeletedEvent(originalPathURI, sessionId, userId, commitMessage); } else if (kind == StandardWatchEventKind.ENTRY_CREATE) { verifyResourceAddedEvent(newPathURI, sessionId, userId, commitMessage); } else { verifyResourceRenamedEvent(originalPathURI, newPathURI, sessionId, userId, commitMessage); } } @SuppressWarnings("unchecked") private WatchEvent mockWatchEvent(WatchEvent.Kind kind, String originalPathURI, String newPathURI, String sessionId, String userId, String commitMessage) throws URISyntaxException { WatchEvent event = mock(WatchEvent.class); when(event.kind()).thenReturn(kind); FileSystem fileSystem = mock(FileSystem.class); Set supportedViews = new HashSet<>(); when(fileSystem.supportedFileAttributeViews()).thenReturn(supportedViews); WatchContext context = mock(WatchContext.class); when(context.getSessionId()).thenReturn(sessionId); when(context.getUser()).thenReturn(userId); when(context.getMessage()).thenReturn(commitMessage); Path oldPath = mock(Path.class); URI oldPathUri = new URI(originalPathURI); when(oldPath.toUri()).thenReturn(oldPathUri); when(oldPath.getFileSystem()).thenReturn(fileSystem); Path path = mock(Path.class); URI pathUri = new URI(newPathURI); when(path.toUri()).thenReturn(pathUri); when(path.getFileSystem()).thenReturn(fileSystem); when(context.getOldPath()).thenReturn(oldPath); when(context.getPath()).thenReturn(path); when(event.context()).thenReturn(context); return event; } private void verifyResourceUpdatedEvent(String file, String sessionId, String userId, String commitMessage) { verify(resourceUpdatedEvent, times(1)).fire(resourceUpdatedEventCaptor.capture()); assertEquals(file, resourceUpdatedEventCaptor.getValue().getPath().toURI()); assertEquals(sessionId, resourceUpdatedEventCaptor.getValue().getSessionInfo().getId()); assertEquals(userId, resourceUpdatedEventCaptor.getValue().getSessionInfo().getIdentity().getIdentifier()); assertEquals(commitMessage, resourceUpdatedEventCaptor.getValue().getMessage()); } private void verifyResourceDeletedEvent(String file, String sessionId, String userId, String commitMessage) { verify(resourceDeletedEvent, times(1)).fire(resourceDeletedEventCaptor.capture()); assertEquals(file, resourceDeletedEventCaptor.getValue().getPath().toURI()); assertEquals(sessionId, resourceDeletedEventCaptor.getValue().getSessionInfo().getId()); assertEquals(userId, resourceDeletedEventCaptor.getValue().getSessionInfo().getIdentity().getIdentifier()); assertEquals(commitMessage, resourceDeletedEventCaptor.getValue().getMessage()); } private void verifyResourceAddedEvent(String file, String sessionId, String userId, String commitMessage) { verify(resourceAddedEvent, times(1)).fire(resourceAddedEventCaptor.capture()); assertEquals(file, resourceAddedEventCaptor.getValue().getPath().toURI()); assertEquals(sessionId, resourceAddedEventCaptor.getValue().getSessionInfo().getId()); assertEquals(userId, resourceAddedEventCaptor.getValue().getSessionInfo().getIdentity().getIdentifier()); assertEquals(commitMessage, resourceAddedEventCaptor.getValue().getMessage()); } private void verifyResourceRenamedEvent(String file, String destinationFile, String sessionId, String userId, String commitMessage) { verify(resourceRenamedEvent, times(1)).fire(resourceRenamedEventCaptor.capture()); assertEquals(file, resourceRenamedEventCaptor.getValue().getPath().toURI()); assertEquals(destinationFile, resourceRenamedEventCaptor.getValue().getDestinationPath().toURI()); assertEquals(sessionId, resourceRenamedEventCaptor.getValue().getSessionInfo().getId()); assertEquals(userId, resourceRenamedEventCaptor.getValue().getSessionInfo().getIdentity().getIdentifier()); assertEquals(commitMessage, resourceRenamedEventCaptor.getValue().getMessage()); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/PluginServiceTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins; import javax.servlet.ServletContext; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.plugins.engine.PluginManager; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class PluginServiceTest { @Mock PluginManager pluginManager; PluginService pluginService; @Test public void initTest() { String path = "/home/dorinha/"; pluginService = createPluginsService(path); pluginService.init(mock(ServletContext.class)); verify(pluginManager).init(path, path); } @Test public void initTestNullDirs() { String path = null; pluginService = createPluginsService(path); pluginService.init(mock(ServletContext.class)); verify(pluginManager, never()).init(anyString(), anyString()); } private PluginService createPluginsService(final String validPath) { return new PluginService(pluginManager) { @Override String getPlugins(ServletContext servletContext, String plugins) { return validPath; } @Override String getContextRootDir(ServletContext servletContext) { return validPath; } }; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/engine/AbstractPluginsTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.engine; import java.io.File; import org.junit.Before; import static org.junit.Assert.*; public abstract class AbstractPluginsTest { protected String contextRootDir; protected String pluginDir; protected String pluginDeploymentDir; @Before public void setup() { try { contextRootDir = new File(getClass().getClassLoader().getResource("test-app").getFile()).getParentFile().getAbsolutePath(); pluginDir = new File(getClass().getClassLoader().getResource("plugins").getFile()).getAbsolutePath(); pluginDeploymentDir = new File(getClass().getClassLoader().getResource("test-app/test-app.nocache.js").getFile()).getParentFile().getAbsolutePath(); } catch (Exception e) { e.printStackTrace(); fail("Test files not found. Make sure the required files are on the classpath."); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/engine/PluginJarProcessorTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.engine; import java.io.File; import java.nio.file.Path; import java.util.Arrays; import java.util.List; import javax.enterprise.event.Event; import javax.enterprise.inject.Instance; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.plugin.PluginProcessor; import org.uberfire.backend.server.plugins.processors.GWTScriptPluginProcessor; import org.uberfire.backend.server.plugins.processors.HTMLPluginProcessor; import org.uberfire.backend.server.plugins.processors.UFJSPluginProcessor; import org.uberfire.workbench.events.PluginReloadedEvent; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class PluginJarProcessorTest extends AbstractPluginsTest { @Mock Instance pluginProcessors; PluginJarProcessor pluginJarProcessor; @Mock private Event pluginsReloadedEvent; @Mock private GWTScriptPluginProcessor gwtScriptPluginProcessor; @Mock private HTMLPluginProcessor htmlPluginProcessor; @Mock private UFJSPluginProcessor ufjsPluginProcessor; @Before public void setup() { super.setup(); List pluginProcessorsList = Arrays.asList(gwtScriptPluginProcessor, htmlPluginProcessor, ufjsPluginProcessor); when(this.pluginProcessors.iterator()).thenReturn(pluginProcessorsList.iterator()); pluginJarProcessor = spy(new PluginJarProcessor(pluginProcessors, pluginsReloadedEvent) { @Override List extractFilesFromPluginsJar(String jarFileName) { return Arrays.asList("dora.html", "dora.txt"); } }); } @Test public void initLoadsDeployedPlugins() throws Exception { pluginJarProcessor.init(pluginDir, pluginDeploymentDir); verify(pluginJarProcessor).loadPlugins(); } @Test public void reloadClearsPluginRegistry() throws Exception { pluginJarProcessor.init(pluginDir, pluginDeploymentDir); pluginJarProcessor.reload(); verify(pluginJarProcessor, times(2)).removeAllPlugins(); } @Test public void reloadFiresPluginsReloadedEvent() throws Exception { pluginJarProcessor.init(pluginDir, pluginDeploymentDir); pluginJarProcessor.reload(); verify(pluginsReloadedEvent).fire(any(PluginReloadedEvent.class)); } @Test public void loadPlugins() throws Exception { Path path = mock(Path.class); when(path.toFile()).thenReturn(mock(File.class)); when(htmlPluginProcessor.shouldProcess("dora.html")).thenReturn(true); pluginJarProcessor.loadPlugins(path, true); verify(htmlPluginProcessor, times(1)).process(eq("dora.html"), any(), eq(true)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/engine/PluginManagerTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.engine; import java.util.concurrent.ExecutorService; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class PluginManagerTest extends AbstractPluginsTest { @Mock private PluginWatcher pluginWatcher; @Mock private PluginJarProcessor pluginJarProcessor; @InjectMocks private PluginManager manager; @Test public void initPluginLoader() throws Exception { manager.init(contextRootDir, pluginDir); verify(pluginJarProcessor, times(1)).init(eq(pluginDir), eq(pluginDeploymentDir)); } @Test public void initStartsWatcher() throws Exception { manager.init(contextRootDir, pluginDir); verify(pluginWatcher, times(1)).start(eq(pluginDir), any(ExecutorService.class), eq(pluginJarProcessor)); } @Test public void shutdownStopsWatcher() throws Exception { manager.shutDown(); verify(pluginWatcher, times(1)).stop(); } @Test public void findPluginDeploymentDir() throws Exception { PluginManager managerSpy = spy(manager); final String pluginDeploymentDir = managerSpy.findPluginDeploymentDir(contextRootDir); verify(managerSpy).encodePath(contextRootDir); assertEquals(this.pluginDeploymentDir, pluginDeploymentDir); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/engine/PluginWatcherTest.java ================================================ /* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.plugins.engine; import java.nio.file.Path; import java.util.concurrent.ExecutorService; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class PluginWatcherTest extends AbstractPluginsTest { @Spy private PluginWatcher pluginWatcher; @Mock private PluginJarProcessor pluginJarProcessor; @Mock private ExecutorService executor; @Mock private Path plugin; @Mock private Path fileName; @After public void tearDown() { pluginWatcher.stop(); } @Test public void startSubmitsWatcherThread() throws Exception { pluginWatcher.start(pluginDir, executor, pluginJarProcessor); verify(executor, times(1)).submit(any(Runnable.class)); } @Test public void startDoesNotSubmitWatcherThreadIfPluginDirDoesNotExist() throws Exception { pluginWatcher.start(pluginDir + "invalid", executor, pluginJarProcessor); verify(executor, never()).submit(any(Runnable.class)); } @Test public void startOnlyOnce() throws Exception { pluginWatcher.start(pluginDir, executor, pluginJarProcessor); pluginWatcher.start(pluginDir, executor, pluginJarProcessor); verify(executor, times(1)).submit(any(Runnable.class)); } @Test public void stopEndsWatcherThread() throws Exception { pluginWatcher.start(pluginDir, executor, pluginJarProcessor); assertTrue(pluginWatcher.active); pluginWatcher.stop(); assertFalse(pluginWatcher.active); verify(executor, times(1)).shutdown(); } @Test public void loadPluginLogsError() throws Exception { pluginWatcher.start(pluginDir, executor, pluginJarProcessor); when(fileName.toString()).thenReturn("fileName.jar"); when(plugin.getFileName()).thenReturn(fileName); Exception e = new RuntimeException(); doThrow(e).when(pluginJarProcessor).loadPlugins(any(Path.class), any(Boolean.class)); pluginWatcher.loadPlugins(plugin); verify(pluginWatcher, times(1)).logPluginsWatcherError("Failed to process new plugin fileName.jar", e, false); pluginWatcher.stop(); pluginWatcher.loadPlugins(plugin); verify(pluginWatcher, times(1)).logPluginsWatcherError("Failed to process new plugin fileName.jar", e, true); } @Test public void reloadPluginsLogsError() throws Exception { pluginWatcher.start(pluginDir, executor, pluginJarProcessor); when(fileName.toString()).thenReturn("fileName.js"); when(plugin.getFileName()).thenReturn(fileName); Exception e = new RuntimeException(); doThrow(e).when(pluginJarProcessor).reload(); pluginWatcher.reloadPlugins(plugin); verify(pluginWatcher, times(1)).logPluginsWatcherError("Failed to delete plugin fileName.js", e, false); pluginWatcher.stop(); pluginWatcher.reloadPlugins(plugin); verify(pluginWatcher, times(1)).logPluginsWatcherError("Failed to delete plugin fileName.js", e, true); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/processors/GWTScriptPluginProcessorTest.java ================================================ package org.uberfire.backend.server.plugins.processors; import javax.enterprise.event.Event; import org.jboss.errai.cdi.server.scripts.ScriptRegistry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.plugins.engine.AbstractPluginsTest; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class GWTScriptPluginProcessorTest extends AbstractPluginsTest { GWTScriptPluginProcessor processor; @Mock private ScriptRegistry scriptRegistry; @Mock private Event pluginAddedEvent; @Mock private Event pluginUpdatedEvent; @Before public void setup() { super.setup(); processor = new GWTScriptPluginProcessor(scriptRegistry, pluginAddedEvent, pluginUpdatedEvent); } @Test public void processTest() { assertFalse(processor.isRegistered("test-app.nocache.js")); processor.process("test-app.nocache.js", pluginDeploymentDir, true); assertTrue(processor.isRegistered("test-app.nocache.js")); verify(scriptRegistry, times(1)).addScript(eq("UF"), anyString()); verify(pluginAddedEvent, times(1)).fire(any()); processor.process("test-app.nocache.js", pluginDeploymentDir, true); verify(pluginUpdatedEvent, times(1)).fire(any()); } @Test public void shutDownShouldRemoveScripts() throws Exception { processor.shutDown(); verify(scriptRegistry, times(1)).removeScripts("UF"); } @Test public void removeAllShouldClearPluginsAndScriptRegistry() throws Exception { processor.availablePlugins.add("test"); assertFalse(processor.availablePlugins.isEmpty()); processor.removeAll(); verify(scriptRegistry, times(1)).removeScripts("UF"); assertTrue(processor.availablePlugins.isEmpty()); } @Test public void shouldProcessTest() throws Exception { assertFalse(processor.shouldProcess("pluginname.html")); assertTrue(processor.shouldProcess("pluginname.nocache.js")); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/processors/HTMLPluginProcessorTest.java ================================================ package org.uberfire.backend.server.plugins.processors; import java.io.IOException; import javax.enterprise.event.Event; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.plugins.engine.AbstractPluginsTest; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class HTMLPluginProcessorTest extends AbstractPluginsTest { @Mock private Event pluginAddedEvent; @Mock private Event pluginUpdatedEvent; private HTMLPluginProcessor processor; public void setup() { processor = new HTMLPluginProcessor(pluginAddedEvent, pluginUpdatedEvent) { @Override String getPluginContent(String pluginName, String pluginDeploymentDir) throws IOException { return "mock"; } }; } @Test public void processTest() { assertFalse(processor.isRegistered("dora.html")); processor.process("dora.html", pluginDeploymentDir, true); assertTrue(processor.isRegistered("dora.html")); verify(pluginAddedEvent, times(1)).fire(any()); processor.process("dora.html", pluginDeploymentDir, true); verify(pluginUpdatedEvent, times(1)).fire(any()); assertTrue(processor.lookupForTemplate("dora.html").isPresent()); } @Test public void shouldProcessTest() throws Exception { assertFalse(processor.shouldProcess("pluginname.nocache.js")); assertTrue(processor.shouldProcess("pluginname.html")); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/plugins/processors/UFJSPluginProcessorTest.java ================================================ package org.uberfire.backend.server.plugins.processors; import java.io.IOException; import javax.enterprise.event.Event; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.plugins.engine.AbstractPluginsTest; import org.uberfire.workbench.events.PluginAddedEvent; import org.uberfire.workbench.events.PluginUpdatedEvent; import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.class) public class UFJSPluginProcessorTest extends AbstractPluginsTest { @Mock private Event pluginAddedEvent; @Mock private Event pluginUpdatedEvent; private UFJSPluginProcessor processor; public void setup() { processor = new UFJSPluginProcessor(pluginAddedEvent, pluginUpdatedEvent) { @Override String getPluginContent(String pluginName, String pluginDeploymentDir) throws IOException { return "mock"; } }; } @Test public void shouldProcessTest() throws Exception { assertTrue(processor.shouldProcess("pluginname.js")); assertFalse(processor.shouldProcess("pluginname.nocache.js")); assertFalse(processor.shouldProcess("pluginname.html")); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/ElytronAuthenticationServiceTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.exception.FailedAuthenticationException; import org.junit.Before; import org.junit.Test; import org.uberfire.backend.server.security.elytron.ElytronIdentityHelper; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; public class ElytronAuthenticationServiceTest { private ElytronAuthenticationService tested; private ElytronIdentityHelper elytronIdentityHelper; @Before public void setup() { elytronIdentityHelper = mock(ElytronIdentityHelper.class); tested = new ElytronAuthenticationService(elytronIdentityHelper); } @Test public void testNoLogin() throws Exception { assertEquals(User.ANONYMOUS, tested.getUser()); } @Test public void testGetAnonymous() throws Exception { assertFalse(tested.isLoggedIn()); } @Test public void testLogin() throws Exception { final String username = "user1"; final String password = "password1"; assertFalse(tested.isLoggedIn()); final User mock = mock(User.class); doReturn(mock).when(elytronIdentityHelper).getIdentity(username, password); assertEquals(mock, tested.login(username, password)); assertEquals(mock, tested.getUser()); assertTrue(tested.isLoggedIn()); tested.logout(); assertFalse(tested.isLoggedIn()); } @Test(expected = FailedAuthenticationException.class) public void testLoginFailure() throws Exception { tested = new ElytronAuthenticationService(elytronIdentityHelper); final String username = "user1"; final String password = "wrong pass"; doThrow(new FailedAuthenticationException()).when(elytronIdentityHelper).getIdentity(username, password); tested.login(username, password); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/FileSystemResourceAdaptorTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.net.URI; import java.util.Arrays; import org.junit.Test; import org.uberfire.java.nio.base.FileSystemId; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemMetadata; import org.uberfire.java.nio.file.Path; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class FileSystemResourceAdaptorTest { @Test public void testFileSystemToCheckProxyIssuesWithExtraInterfaces() { final FileSystem mockedFS = mock(FileSystem.class); final FileSystem mockedFSId = mock(FileSystem.class, withSettings().extraInterfaces(FileSystemId.class)); final Path rootPath = mock(Path.class); when(mockedFS.getRootDirectories()).thenReturn(Arrays.asList(rootPath)); when(mockedFSId.getRootDirectories()).thenReturn(Arrays.asList(rootPath)); when(rootPath.getFileSystem()).thenReturn(mockedFSId); when(rootPath.toUri()).thenReturn(URI.create("jgit://myrepo")); when(((FileSystemId) mockedFSId).id()).thenReturn("my-fsid"); { FileSystemMetadata fileSystemInfo = new FileSystemMetadata(mockedFSId); final FileSystemResourceAdaptor fileSystemResourceAdaptor = new FileSystemResourceAdaptor(fileSystemInfo); assertEquals(fileSystemInfo, fileSystemResourceAdaptor.getFileSystemMetadata()); assertEquals("my-fsid", fileSystemResourceAdaptor.getIdentifier()); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/IOServiceSecuritySetupTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import org.guvnor.structure.repositories.Repository; import org.guvnor.structure.repositories.RepositoryService; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.service.AuthenticationService; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.java.nio.base.FileSystemId; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.security.FileSystemAuthorizer; import org.uberfire.security.ResourceAction; import org.uberfire.security.authz.AuthorizationManager; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.impl.authz.DefaultAuthorizationManager; import org.uberfire.security.impl.authz.DefaultPermissionManager; import org.uberfire.security.impl.authz.DefaultPermissionTypeRegistry; import org.uberfire.spaces.Space; import org.uberfire.spaces.SpacesAPI; import javax.enterprise.inject.Instance; import java.net.URI; import java.util.Optional; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class IOServiceSecuritySetupTest { @Mock Instance authenticationManagers; AuthorizationManager authorizationManager; RepositoryService repositoryService; SpacesAPI spacesAPI; IOServiceSecuritySetup setupBean; @Before public void setup() { // this is the fallback configuration when no @IOSecurityAuth bean is found System.setProperty("org.uberfire.io.auth", MockAuthenticationService.class.getName()); PermissionManager permissionManager = new DefaultPermissionManager(new DefaultPermissionTypeRegistry()); authorizationManager = spy(new DefaultAuthorizationManager(permissionManager)); repositoryService = mock(RepositoryService.class); spacesAPI = mock(SpacesAPI.class); setupBean = new IOServiceSecuritySetup(); setupBean.authenticationManagers = authenticationManagers; setupBean.authorizationManager = authorizationManager; setupBean.repositoryService = repositoryService; setupBean.spacesAPI = spacesAPI; } @After public void teardown() { System.clearProperty("org.uberfire.io.auth"); } @Test public void testSystemPropertyAuthConfig() throws Exception { when(authenticationManagers.isUnsatisfied()).thenReturn(true); setupBean.setup(); // setup should have initialized the authenticator and authorizer to their defaults MockSecuredFilesystemProvider mockFsp = MockSecuredFilesystemProvider.LATEST_INSTANCE; assertNotNull(mockFsp.authenticator); assertNotNull(mockFsp.authorizer); // and they should work :) User user = mockFsp.authenticator.login("fake", "fake"); assertEquals(MockAuthenticationService.FAKE_USER.getIdentifier(), user.getIdentifier()); final FileSystem mockfs = mock(FileSystem.class); final FileSystem mockedFSId = mock(FileSystem.class, withSettings().extraInterfaces(FileSystemId.class)); final Path rootPath = mock(Path.class); when(rootPath.toUri()).thenReturn(URI.create("/")); when(rootPath.getFileSystem()).thenReturn(mockedFSId); when(mockfs.getPath(mockfs.getName())).thenReturn(rootPath); Space space = mock(Space.class); when(spacesAPI.resolveSpace(any())).thenReturn(Optional.of(space)); assertTrue(mockFsp.authorizer.authorize(mockfs, user)); } @Test public void testCustomAuthenticatorBean() throws Exception { // this simulates the existence of a @IOServiceAuth AuthenticationService bean when(authenticationManagers.isUnsatisfied()).thenReturn(false); AuthenticationService mockAuthenticationService = mock(AuthenticationService.class); when(authenticationManagers.get()).thenReturn(mockAuthenticationService); setupBean.setup(); AuthenticationService authenticator = MockSecuredFilesystemProvider.LATEST_INSTANCE.authenticator; authenticator.login("fake", "fake"); // make sure the call went to the one we provided verify(mockAuthenticationService).login("fake", "fake"); } @Test public void testCustomAuthorizerBean() throws Exception { when(authenticationManagers.isUnsatisfied()).thenReturn(true); setupBean.setup(); FileSystemAuthorizer installedAuthorizer = MockSecuredFilesystemProvider.LATEST_INSTANCE.authorizer; AuthenticationService installedAuthenticator = MockSecuredFilesystemProvider.LATEST_INSTANCE.authenticator; FileSystem mockfs = mock(FileSystem.class); final FileSystem mockedFSId = mock(FileSystem.class, withSettings().extraInterfaces(FileSystemId.class)); final Path rootPath = mock(Path.class); final Repository repository = mock(Repository.class); when(rootPath.toUri()).thenReturn(URI.create("/")); when(rootPath.getFileSystem()).thenReturn(mockedFSId); User fileSystemUser = installedAuthenticator.login("fake", "fake"); when(mockfs.getPath(mockfs.getName())).thenReturn(rootPath); Space space = mock(Space.class); when(spacesAPI.resolveSpace(any())).thenReturn(Optional.of(space)); when(repositoryService.getRepositoryFromSpace(any(), any())).thenReturn(repository); installedAuthorizer.authorize(mockfs, fileSystemUser); // make sure the call went to the one we provided verify(authorizationManager).authorize(repository, repository.getContributors(), ResourceAction.READ, fileSystemUser); } @Test public void testNonRepositoryAuthorization() throws Exception { when(authenticationManagers.isUnsatisfied()).thenReturn(true); setupBean.setup(); FileSystemAuthorizer installedAuthorizer = MockSecuredFilesystemProvider.LATEST_INSTANCE.authorizer; AuthenticationService installedAuthenticator = MockSecuredFilesystemProvider.LATEST_INSTANCE.authenticator; FileSystem mockfs = mock(FileSystem.class); final FileSystem mockedFSId = mock(FileSystem.class, withSettings().extraInterfaces(FileSystemId.class)); final Path rootPath = mock(Path.class); final Repository repository = mock(Repository.class); when(rootPath.toUri()).thenReturn(URI.create("/")); when(rootPath.getFileSystem()).thenReturn(mockedFSId); User fileSystemUser = installedAuthenticator.login("fake", "fake"); when(mockfs.getPath(mockfs.getName())).thenReturn(rootPath); Space space = mock(Space.class); when(spacesAPI.resolveSpace(any())).thenReturn(Optional.of(space)); when(repositoryService.getRepositoryFromSpace(any(), any())).thenReturn(null); installedAuthorizer.authorize(mockfs, fileSystemUser); // make sure the call went to the one we provided verify(authorizationManager).authorize(any(FileSystemResourceAdaptor.class), any(User.class)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/JAASAuthenticationServiceTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.security.Principal; import java.security.acl.Group; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import org.jboss.errai.security.shared.api.GroupImpl; import org.jboss.errai.security.shared.api.RoleImpl; import org.jboss.errai.security.shared.api.identity.User; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import org.uberfire.backend.server.security.adapter.WebSphereGroupsAdapter; import org.uberfire.security.authz.adapter.GroupsAdapter; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; import static org.powermock.api.mockito.PowerMockito.mockStatic; @RunWith(PowerMockRunner.class) @PrepareForTest({JAASAuthenticationService.class}) @PowerMockIgnore({"javax.security.*", "javax.naming.*"}) public class JAASAuthenticationServiceTest { private JAASAuthenticationService tested; @Before public void setup() { RoleRegistry.get().clear(); RoleRegistry.get().registerRole( "admin" ); RoleRegistry.get().registerRole( "role1" ); tested = spy( new JAASAuthenticationService( JAASAuthenticationService.DEFAULT_DOMAIN ) ); } @Test public void testNoLogin() throws Exception { assertEquals( User.ANONYMOUS, tested.getUser() ); } @Test public void testGetAnnonymous() throws Exception { assertFalse( tested.isLoggedIn() ); } @Test public void testLogin() throws Exception { String username = "user1"; String password = "password1"; Set principals = mockPrincipals( "admin", "role1", "group1" ); Subject subject = new Subject(); subject.getPrincipals().addAll( principals ); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.getSubject() ).thenReturn( subject ); doReturn( loginContext ).when( tested ).createLoginContext( anyString(), anyString() ); User user = tested.login( username, password ); assertNotNull( user ); assertEquals( username, user.getIdentifier() ); assertEquals( 2, user.getRoles().size() ); assertTrue( user.getRoles().contains( new RoleImpl( "admin" ) ) ); assertTrue( user.getRoles().contains( new RoleImpl( "role1" ) ) ); assertEquals( 1, user.getGroups().size() ); assertTrue( user.getGroups().contains( new GroupImpl( "group1" ) ) ); } @Test public void testLoginSwitchesClassloaderForJsm() throws Exception { mockStatic( JAASAuthenticationService.class ); mockStatic( Thread.class ); mockStatic( System.class ); final ClassLoader tccl = mock( ClassLoader.class ); final Thread thread = mock( Thread.class ); when( Thread.currentThread() ).thenReturn( thread ); when( System.getSecurityManager() ).thenReturn( mock( SecurityManager.class ) ); when( thread.getContextClassLoader() ).thenReturn( tccl ); String username = "user1"; String password = "password1"; Set principals = mockPrincipals( "admin", "role1", "group1" ); Subject subject = new Subject(); subject.getPrincipals().addAll( principals ); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.getSubject() ).thenReturn( subject ); doReturn( loginContext ).when( tested ).createLoginContext( anyString(), anyString() ); tested.login( username, password ); InOrder inOrder = inOrder( thread ); inOrder.verify( thread ).setContextClassLoader( tested.getClass().getClassLoader() ); inOrder.verify( thread ).setContextClassLoader( same( tccl ) ); } @Test public void testLoginNoPrincipal() throws Exception { String username = "user1"; String password = "password1"; Subject subject = new Subject(); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.getSubject() ).thenReturn( subject ); doReturn( loginContext ).when( tested ).createLoginContext( anyString(), anyString() ); User user = tested.login( username, password ); assertNotNull( user ); assertEquals( username, user.getIdentifier() ); assertEquals( 0, user.getRoles().size() ); assertEquals( 0, user.getGroups().size() ); } @Test public void testLoginSubjectGroups() throws Exception { String username = "user1"; String password = "password1"; Set principals = mockPrincipals( "admin", "role1", "group1" ); Group aclGroup = mock( Group.class ); doReturn( JAASAuthenticationService.DEFAULT_ROLE_PRINCIPLE_NAME ).when( aclGroup ).getName(); Set aclGroups = mockPrincipals( "g1", "g2" ); Enumeration aclGroupsEnum = Collections.enumeration( aclGroups ); doReturn( aclGroupsEnum ).when( aclGroup ).members(); Subject subject = new Subject(); subject.getPrincipals().addAll( principals ); subject.getPrincipals().add( aclGroup ); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.getSubject() ).thenReturn( subject ); doReturn( loginContext ).when( tested ).createLoginContext( anyString(), anyString() ); User user = tested.login( username, password ); assertNotNull( user ); assertEquals( username, user.getIdentifier() ); assertEquals( 2, user.getRoles().size() ); assertTrue( user.getRoles().contains( new RoleImpl( "admin" ) ) ); assertTrue( user.getRoles().contains( new RoleImpl( "role1" ) ) ); assertEquals( 3, user.getGroups().size() ); assertTrue( user.getGroups().contains( new GroupImpl( "group1" ) ) ); assertTrue( user.getGroups().contains( new GroupImpl( "g1" ) ) ); assertTrue( user.getGroups().contains( new GroupImpl( "g2" ) ) ); } /* * RHBPMS-4609: When LDAP provides the authorized groups on Websphere the groups returned are not filtered to simple name (i.e, group = admin) when accessed from non-web clients such as ssh. * This test checks that the regex pattern configured as a System property will recognize these unfiltered groups as authorized roles. */ @Test public void testLoginSubjectGroupsWithRegexRoleMapper() throws Exception { RoleRegistry.get().clear(); RoleRegistry.get().registerRole( "admin" ); RoleRegistry.get().registerRole( "user" ); RoleRegistry.get().registerRole( "role1" ); System.setProperty( "org.uberfire.regex.role_mapper", "cn[\\ ]*=[\\ ]*role" ); JAASAuthenticationService sshClient = spy( new JAASAuthenticationService( JAASAuthenticationService.DEFAULT_DOMAIN ) ); String username = "user1"; String password = "password1"; Set principals = mockPrincipals( "ldap", "role1" ); Group aclGroup = mock( Group.class ); doReturn( JAASAuthenticationService.DEFAULT_ROLE_PRINCIPLE_NAME ).when( aclGroup ).getName(); Set aclGroups = mockPrincipals( "g1", "g2" ); Enumeration aclGroupsEnum = Collections.enumeration( aclGroups ); doReturn( aclGroupsEnum ).when( aclGroup ).members(); Subject subject = new Subject(); subject.getPrincipals().addAll( principals ); subject.getPrincipals().add( aclGroup ); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.getSubject() ).thenReturn( subject ); doReturn( loginContext ).when( sshClient ).createLoginContext( anyString(), anyString() ); WebSphereGroupsAdapter wsga = mock( WebSphereGroupsAdapter.class ); List groups = mockGroups( "cn=admin,ou=groups,dc=com,dc=example", "cn=user" ); doReturn( groups ).when( wsga ).getGroups( anyString(), anyObject() ); List list = new ArrayList(); list.add( wsga ); Whitebox.setInternalState( sshClient, "groupsAdapters", list ); User user = sshClient.login( username, password ); assertNotNull( user ); assertEquals( username, user.getIdentifier() ); assertEquals( 3, user.getRoles().size() ); assertTrue( user.getRoles().contains( new RoleImpl( "admin" ) ) ); assertTrue( user.getRoles().contains( new RoleImpl( "user" ) ) ); assertTrue( user.getRoles().contains( new RoleImpl( "role1" ) ) ); assertEquals( 3, user.getGroups().size() ); assertTrue( user.getGroups().contains( new GroupImpl( "g1" ) ) ); assertTrue( user.getGroups().contains( new GroupImpl( "g2" ) ) ); assertTrue( user.getGroups().contains( new GroupImpl( "ldap" ) ) ); } @Test public void testLoggedIn() throws Exception { String username = "user1"; String password = "password1"; Set principals = mockPrincipals( "admin" ); Subject subject = new Subject(); subject.getPrincipals().addAll( principals ); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.getSubject() ).thenReturn( subject ); doReturn( loginContext ).when( tested ).createLoginContext( anyString(), anyString() ); tested.login( username, password ); assertTrue( tested.isLoggedIn() ); } @Test public void testGetUser() throws Exception { String username = "user1"; String password = "password1"; RoleRegistry.get().registerRole( "admin" ); Set principals = mockPrincipals( "admin" ); Subject subject = new Subject(); subject.getPrincipals().addAll( principals ); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.getSubject() ).thenReturn( subject ); doReturn( loginContext ).when( tested ).createLoginContext( anyString(), anyString() ); User user = tested.login( username, password ); User user1 = tested.getUser(); assertEquals( user, user1 ); } private Set mockPrincipals( String... names ) { Set principals = new HashSet(); for ( String name : names ) { Principal p1 = mock( Principal.class ); when( p1.getName() ).thenReturn( name ); principals.add( p1 ); } return principals; } private List mockGroups( String... names ) { ArrayList groups = new ArrayList(); for ( String name : names ) { org.jboss.errai.security.shared.api.Group g = mock( org.jboss.errai.security.shared.api.Group.class ); when( g.getName() ).thenReturn( name ); groups.add( g ); } return groups; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/MockAuthenticationService.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.api.identity.UserImpl; import org.jboss.errai.security.shared.service.AuthenticationService; public class MockAuthenticationService implements AuthenticationService { public static final User FAKE_USER = new UserImpl("fake"); @Override public User login(String username, String password) { return FAKE_USER; } @Override public boolean isLoggedIn() { return true; } @Override public void logout() { } @Override public User getUser() { return FAKE_USER; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/MockSecuredFilesystemProvider.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.nio.channels.FileChannel; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import org.jboss.errai.security.shared.service.AuthenticationService; import org.uberfire.java.nio.IOException; import org.uberfire.java.nio.base.AbstractPath; import org.uberfire.java.nio.channels.AsynchronousFileChannel; import org.uberfire.java.nio.channels.SeekableByteChannel; import org.uberfire.java.nio.file.AccessDeniedException; import org.uberfire.java.nio.file.AccessMode; import org.uberfire.java.nio.file.AtomicMoveNotSupportedException; import org.uberfire.java.nio.file.ClosedWatchServiceException; import org.uberfire.java.nio.file.CopyOption; import org.uberfire.java.nio.file.DeleteOption; import org.uberfire.java.nio.file.DirectoryNotEmptyException; import org.uberfire.java.nio.file.DirectoryStream; import org.uberfire.java.nio.file.DirectoryStream.Filter; import org.uberfire.java.nio.file.FileAlreadyExistsException; import org.uberfire.java.nio.file.FileStore; import org.uberfire.java.nio.file.FileSystem; import org.uberfire.java.nio.file.FileSystemAlreadyExistsException; import org.uberfire.java.nio.file.FileSystemNotFoundException; import org.uberfire.java.nio.file.InvalidPathException; import org.uberfire.java.nio.file.LinkOption; import org.uberfire.java.nio.file.NoSuchFileException; import org.uberfire.java.nio.file.NotDirectoryException; import org.uberfire.java.nio.file.NotLinkException; import org.uberfire.java.nio.file.OpenOption; import org.uberfire.java.nio.file.Path; import org.uberfire.java.nio.file.PathMatcher; import org.uberfire.java.nio.file.PatternSyntaxException; import org.uberfire.java.nio.file.WatchEvent.Kind; import org.uberfire.java.nio.file.WatchEvent.Modifier; import org.uberfire.java.nio.file.WatchKey; import org.uberfire.java.nio.file.WatchService; import org.uberfire.java.nio.file.attribute.BasicFileAttributes; import org.uberfire.java.nio.file.attribute.FileAttribute; import org.uberfire.java.nio.file.attribute.FileAttributeView; import org.uberfire.java.nio.file.attribute.UserPrincipalLookupService; import org.uberfire.java.nio.file.spi.FileSystemProvider; import org.uberfire.java.nio.security.FileSystemAuthorizer; import org.uberfire.java.nio.security.SSHAuthenticator; import org.uberfire.java.nio.security.SecuredFileSystemProvider; /** * A fake filesystem provider that's registered under * src/test/resources/META-INF/services. */ public class MockSecuredFilesystemProvider implements SecuredFileSystemProvider { public static MockSecuredFilesystemProvider LATEST_INSTANCE; public boolean isForcedDefault; public AuthenticationService authenticator; public FileSystemAuthorizer authorizer; public SSHAuthenticator sshAuthenticator; public MockSecuredFilesystemProvider() { LATEST_INSTANCE = this; } @Override public void forceAsDefault() { isForcedDefault = true; } @Override public boolean isDefault() { return false; } @Override public String getScheme() { return "mocksecure"; } @Override public FileSystem newFileSystem(URI uri, Map env) throws IllegalArgumentException, IOException, SecurityException, FileSystemAlreadyExistsException { throw new UnsupportedOperationException(); } @Override public FileSystem getFileSystem(URI uri) throws IllegalArgumentException, FileSystemNotFoundException, SecurityException { throw new UnsupportedOperationException(); } @Override public Path getPath(URI uri) throws IllegalArgumentException, FileSystemNotFoundException, SecurityException { return new MockPath(); } @Override public FileSystem newFileSystem(Path path, Map env) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public InputStream newInputStream(Path path, OpenOption... options) throws IllegalArgumentException, UnsupportedOperationException, NoSuchFileException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public OutputStream newOutputStream(Path path, OpenOption... options) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public FileChannel newFileChannel(Path path, Set options, FileAttribute... attrs) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public AsynchronousFileChannel newAsynchronousFileChannel(Path path, Set options, ExecutorService executor, FileAttribute... attrs) throws IllegalArgumentException, UnsupportedOperationException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public SeekableByteChannel newByteChannel(Path path, Set options, FileAttribute... attrs) throws IllegalArgumentException, UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public DirectoryStream newDirectoryStream(Path dir, Filter filter) throws NotDirectoryException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void createDirectory(Path dir, FileAttribute... attrs) throws UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void createSymbolicLink(Path link, Path target, FileAttribute... attrs) throws UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void createLink(Path link, Path existing) throws UnsupportedOperationException, FileAlreadyExistsException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void delete(Path path, DeleteOption... options) throws DirectoryNotEmptyException, NoSuchFileException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public boolean deleteIfExists(Path path, DeleteOption... options) throws DirectoryNotEmptyException, IOException, SecurityException { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } @Override public Path readSymbolicLink(Path link) throws UnsupportedOperationException, NotLinkException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void copy(Path source, Path target, CopyOption... options) throws UnsupportedOperationException, FileAlreadyExistsException, DirectoryNotEmptyException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void move(Path source, Path target, CopyOption... options) throws DirectoryNotEmptyException, AtomicMoveNotSupportedException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public boolean isSameFile(Path path, Path path2) throws IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public boolean isHidden(Path path) throws IllegalArgumentException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public FileStore getFileStore(Path path) throws IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void checkAccess(Path path, AccessMode... modes) throws UnsupportedOperationException, NoSuchFileException, AccessDeniedException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public V getFileAttributeView(Path path, Class type, LinkOption... options) throws NoSuchFileException { throw new UnsupportedOperationException(); } @Override public A readAttributes(Path path, Class type, LinkOption... options) throws NoSuchFileException, UnsupportedOperationException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public Map readAttributes(Path path, String attributes, LinkOption... options) throws UnsupportedOperationException, IllegalArgumentException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void setAttribute(Path path, String attribute, Object value, LinkOption... options) throws UnsupportedOperationException, IllegalArgumentException, ClassCastException, IOException, SecurityException { throw new UnsupportedOperationException(); } @Override public void setJAASAuthenticator(AuthenticationService authenticator) { this.authenticator = authenticator; } @Override public void setHTTPAuthenticator(AuthenticationService authenticator) { } @Override public void setAuthorizer(FileSystemAuthorizer authorizer) { this.authorizer = authorizer; } @Override public void setSSHAuthenticator(SSHAuthenticator authenticator) { this.sshAuthenticator = authenticator; } private class MockPath extends AbstractPath { public MockPath() { super(new MockFileSystem(), new File("mock")); } @Override public File toFile() throws UnsupportedOperationException { return null; } @Override public WatchKey register(WatchService watcher, Kind[] events, Modifier... modifiers) throws UnsupportedOperationException, IllegalArgumentException, ClosedWatchServiceException, IOException, SecurityException { return null; } @Override public WatchKey register(WatchService watcher, Kind... events) throws UnsupportedOperationException, IllegalArgumentException, ClosedWatchServiceException, IOException, SecurityException { return null; } @Override protected Path newPath(FileSystem fs, String substring, String host, boolean realPath, boolean isNormalized) { return null; } @Override protected Path newRoot(FileSystem fs, String substring, String host, boolean realPath) { return null; } @Override protected RootInfo setupRoot(FileSystem fs, String path, String host, boolean isRoot) { return new RootInfo(0, true, true, new byte[0]); } @Override protected String defaultDirectory() { return null; } } private class MockFileSystem implements FileSystem { @Override public void close() throws IOException { } @Override public void dispose() { } @Override public FileSystemProvider provider() { return null; } @Override public boolean isOpen() { return false; } @Override public boolean isReadOnly() { return false; } @Override public String getSeparator() { return null; } @Override public Iterable getRootDirectories() { return null; } @Override public Iterable getFileStores() { return null; } @Override public Set supportedFileAttributeViews() { return null; } @Override public Path getPath(String first, String... more) throws InvalidPathException { return null; } @Override public PathMatcher getPathMatcher(String syntaxAndPattern) throws IllegalArgumentException, PatternSyntaxException, UnsupportedOperationException { return null; } @Override public UserPrincipalLookupService getUserPrincipalLookupService() throws UnsupportedOperationException { return null; } @Override public WatchService newWatchService() throws UnsupportedOperationException, IOException { return null; } @Override public String getName() { return "name"; } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/RoleLoaderTest.java ================================================ /** * Copyright 2016 Red Hat, Inc. and/or its affiliates. *

        * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

        * http://www.apache.org/licenses/LICENSE-2.0 *

        * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security; import java.io.File; import java.net.URL; import java.util.Set; import org.jboss.errai.security.shared.api.Role; import org.junit.Before; import org.junit.Test; import org.uberfire.backend.server.WebAppSettings; import static org.junit.Assert.*; public class RoleLoaderTest { @Before public void setUp() { URL fileURL = Thread.currentThread().getContextClassLoader().getResource("WEB-INF/classes/security-policy.properties"); String homeDir = new File(fileURL.getPath()).getParentFile().getParentFile().getParent(); WebAppSettings.get().setRootDir(homeDir); RoleRegistry.get().clear(); RoleLoader roleLoader = new RoleLoader(); roleLoader.registerRolesFromwWebXml(); } @Test public void testLoad() { Set roles = RoleRegistry.get().getRegisteredRoles(); assertEquals(roles.size(), 2); assertNotNull(RoleRegistry.get().getRegisteredRole("role1")); assertNotNull(RoleRegistry.get().getRegisteredRole("role2")); assertNull(RoleRegistry.get().getRegisteredRole("empty")); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/adapter/GroupAdapterAuthorizationSourceTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.adapter; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.junit.Test; import static org.junit.Assert.assertTrue; public class GroupAdapterAuthorizationSourceTest { GroupAdapterAuthorizationSource adapter = new GroupAdapterAuthorizationSource(); @Test public void testConcurrency() throws Exception { final ExecutorService service = Executors.newFixedThreadPool(4); final CountDownLatch latch = new CountDownLatch(12); for (int i = 0; i < 12; i++) { service.submit(() -> { try { adapter.collectEntitiesFromAdapters(null, null); latch.countDown(); } catch (Exception ex){ ex.printStackTrace(); } }); } service.shutdown(); assertTrue(latch.await(3, TimeUnit.SECONDS)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/elytron/DefaultElytronIdentityHelperTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.elytron; import org.jboss.errai.security.shared.api.RoleImpl; import org.jboss.errai.security.shared.api.identity.User; import org.jboss.errai.security.shared.exception.FailedAuthenticationException; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.wildfly.security.auth.server.RealmUnavailableException; import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.authz.Roles; import org.wildfly.security.evidence.Evidence; import java.util.ArrayList; import java.util.Iterator; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class DefaultElytronIdentityHelperTest { private static final String USERNAME = "user"; private static final String PASSWORD = "password"; private DefaultElytronIdentityHelper helper; private ArrayList roles = new ArrayList<>(); @Before public void init() { helper = spy(new DefaultElytronIdentityHelper() { @Override protected Iterator login(String userName, Evidence evidence) { return roles.iterator(); } }); } @After public void after() { roles.clear(); } @Test public void testSuccessfulLogin() throws RealmUnavailableException { roles.add("admin"); roles.add("rest-all"); final User identity = helper.getIdentity(USERNAME, PASSWORD); assertEquals(USERNAME, identity.getIdentifier()); assertTrue(identity.getRoles().contains(new RoleImpl("admin"))); assertTrue(identity.getRoles().contains(new RoleImpl("rest-all"))); assertEquals(2, identity.getRoles().size()); } @Test public void testSuccessfulLoginNoRoles() throws RealmUnavailableException { final User identity = helper.getIdentity(USERNAME, PASSWORD); assertTrue(identity.getRoles().isEmpty()); } @Test(expected = FailedAuthenticationException.class) public void testUnSuccessfulLogin() throws RealmUnavailableException { doThrow(new RuntimeException("whatever error")).when(helper).login(any(), any()); helper.getIdentity(USERNAME, PASSWORD); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/security/elytron/ElytronIdentityHelperProducerTest.java ================================================ /* * Copyright 2021 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.security.elytron; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.security.WorkbenchUserManager; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @RunWith(MockitoJUnitRunner.class) public class ElytronIdentityHelperProducerTest { private static final String USERNAME = "user"; private static final String PASSWORD = "password"; private ElytronIdentityHelperProducer producer; @Before public void init() { producer = new ElytronIdentityHelperProducer(); } @Test public void testProduce() { ElytronIdentityHelper helper = producer.getDefaultElytronIdentityHelper(); assertNotNull(helper); assertTrue(helper instanceof DefaultElytronIdentityHelper); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/servlet/ReleaseUserLocksServletTest.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.servlet; import java.util.HashSet; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.uberfire.backend.server.VFSLockServiceImpl; import org.uberfire.backend.vfs.Path; import org.uberfire.backend.vfs.VFSLockService; import org.uberfire.backend.vfs.impl.LockInfo; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class ReleaseUserLocksServletTest { @Mock private VFSLockService vfsLockService; @InjectMocks private ReleaseUserLocksServlet releaseUserLocksServlet; @Test public void releaseUserLocksWhenInvalidSessionTest() { HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse response = mock(HttpServletResponse.class); doReturn(null).when(request).getSession(); releaseUserLocksServlet.doGet(request, response); verify(vfsLockService, never()).releaseLock(any(Path.class)); } @Test public void releaseUserLocksWhenNoLockAttributeTest() { HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse response = mock(HttpServletResponse.class); HttpSession session = mock(HttpSession.class); doReturn(session).when(request).getSession(); doReturn(null).when(session).getAttribute(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME); releaseUserLocksServlet.doGet(request, response); verify(vfsLockService, never()).releaseLock(any(Path.class)); } @Test public void releaseUserLocksSuccessTest() { HttpServletRequest request = mock(HttpServletRequest.class); HttpServletResponse response = mock(HttpServletResponse.class); HttpSession session = mock(HttpSession.class); Set locks = new HashSet<>(); locks.add(mock(LockInfo.class)); doReturn(session).when(request).getSession(); doReturn(locks).when(session).getAttribute(VFSLockServiceImpl.LOCK_SESSION_ATTRIBUTE_NAME); releaseUserLocksServlet.doGet(request, response); verify(vfsLockService).releaseLock(any()); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/spaces/SpacesAPIImplTest.java ================================================ /* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.spaces; import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.uberfire.spaces.Space; import org.uberfire.spaces.SpacesAPI; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class SpacesAPIImplTest { SpacesAPIImpl spaces; @Before public void setup() { spaces = new SpacesAPIImpl(); } @Test public void resolveFileSystemURITest() { assertEquals("default://system/system", spaces.resolveFileSystemURI(SpacesAPI.Scheme.DEFAULT, SpacesAPI.DEFAULT_SPACE, "system").toString()); } @Test public void resolveSpaceNameTest() throws Exception { Optional space = spaces.resolveSpace("default://main@myteam/mortgages/"); assertTrue(space.isPresent()); assertEquals("myteam", space.get().getName()); } @Test public void resolveSpaceNameWhenBranchNameHasSlashesTest() throws Exception { Optional space = spaces.resolveSpace("default://my/main/branch@myteam/mortgages/"); assertTrue(space.isPresent()); assertEquals("myteam", space.get().getName()); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/util/PathsTest.java ================================================ /* * Copyright 2018 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util; import org.junit.Test; import org.uberfire.backend.vfs.Path; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class PathsTest { @Test public void getFilePathFromProjectRoot() throws Exception { final Path repositoryRoot = getPath("file:///spaceName/repositoryName", "/"); final Path pathToFile = getPath("file:///spaceName/repositoryName/org/test/file.txt", "file.txt"); assertEquals("org/test/file.txt", Paths.removePrefix(pathToFile, repositoryRoot)); } @Test public void getFilePath() throws Exception { final Path repositoryRoot = getPath("file:///spaceName/repositoryName/org/test", "test"); final Path pathToFile = getPath("file:///spaceName/repositoryName/org/test/file.txt", "file.txt"); assertEquals("file.txt", Paths.removePrefix(pathToFile, repositoryRoot)); } @Test public void pathsAreEqual() throws Exception { final Path repositoryRoot = getPath("file:///spaceName/repositoryName/org/test", "test"); assertEquals("", Paths.removePrefix(repositoryRoot, repositoryRoot)); } @Test(expected = IllegalArgumentException.class) public void pathIsShorterThanPrefix() throws Exception { final Path repositoryRoot = getPath("file:///spaceName/repositoryName/org/test", "test"); final Path pathToFile = getPath("file:///spaceName/repositoryName/org/test/file.txt", "file.txt"); Paths.removePrefix(repositoryRoot, pathToFile); } @Test(expected = IllegalArgumentException.class) public void prefixDoesNotMatch() throws Exception { final Path repositoryRoot = getPath("file:///spaceName/repositoryName/org/test", "test"); final Path pathToFile = getPath("file:///otherSpace/repositoryName/org/test/file.txt", "file.txt"); Paths.removePrefix(pathToFile, repositoryRoot); } private Path getPath(final String uri, final String fileName) { final Path path = mock(Path.class); when(path.toURI()).thenReturn(uri); when(path.getFileName()).thenReturn(fileName); return path; } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/util/TestPaths.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.backend.server.util; import org.junit.Test; import static org.junit.Assert.*; public class TestPaths { @Test public void test() { { final String FILENAME = "file name.txt"; final org.uberfire.java.nio.file.Path path = org.uberfire.java.nio.file.Paths.get("file://reponame/path/to/").resolve(FILENAME); assertEquals(FILENAME, path.getFileName().toString()); assertEquals(FILENAME, Paths.convert(path).getFileName()); assertEquals(FILENAME, Paths.convert(Paths.convert(path)).getFileName().toString()); System.out.println(path.toUri().toString()); System.out.println(Paths.convert(path).toURI()); System.out.println(Paths.normalizePath(path).toUri().toString()); } { final String FILENAME = "file_name.txt"; final org.uberfire.java.nio.file.Path path = org.uberfire.java.nio.file.Paths.get("file://reponame/path/to/").resolve(FILENAME); assertEquals(FILENAME, path.getFileName().toString()); assertEquals(FILENAME, Paths.convert(path).getFileName()); assertEquals(FILENAME, Paths.convert(Paths.convert(path)).getFileName().toString()); System.out.println(path.toUri().toString()); System.out.println(Paths.convert(path).toURI()); System.out.println(Paths.normalizePath(path).toUri().toString()); } { final String FILENAME = "file+name.txt"; final org.uberfire.java.nio.file.Path path = org.uberfire.java.nio.file.Paths.get("file://reponame/path/to/").resolve(FILENAME); assertEquals(FILENAME, path.getFileName().toString()); assertEquals(FILENAME, Paths.convert(path).getFileName()); assertEquals(FILENAME, Paths.convert(Paths.convert(path)).getFileName().toString()); System.out.println(path.toUri().toString()); System.out.println(Paths.convert(path).toURI()); System.out.println(Paths.normalizePath(path).toUri().toString()); } } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/backend/server/util/gzip/GzipFilterTest.java ================================================ package org.uberfire.backend.server.util.gzip; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.junit.Before; import org.junit.Test; import static javax.ws.rs.core.HttpHeaders.ACCEPT_ENCODING; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.uberfire.backend.server.util.gzip.GzipFilter.Action.COMPRESS; import static org.uberfire.backend.server.util.gzip.GzipFilter.Action.DO_NOT_ACCEPT_GZIP; import static org.uberfire.backend.server.util.gzip.GzipFilter.Action.DO_NOT_COMPRESS; import static org.uberfire.backend.server.util.gzip.GzipFilter.Action.HALT; import static org.uberfire.backend.server.util.gzip.GzipFilter.GZIP; import static org.uberfire.backend.server.util.gzip.GzipFilter.ORG_UBERFIRE_GZIP_ENABLE; public class GzipFilterTest { @Before public void before() { System.clearProperty(ORG_UBERFIRE_GZIP_ENABLE); } @Test public void doFilter_compress() throws IOException, ServletException { final GzipFilter gzipFilter = spy(new GzipFilter()); when(gzipFilter.getAction(any())).thenReturn(COMPRESS); final FilterChain chain = mock(FilterChain.class); gzipFilter.doFilter(mock(HttpServletRequest.class), mock(HttpServletResponse.class), chain); verify(gzipFilter, times(1)).compressAndContinue(any(), any(), any()); verify(chain, times(1)).doFilter(any(), any()); } @Test public void doFilter_doNotCompress() throws IOException, ServletException { final GzipFilter gzipFilter = spy(new GzipFilter()); when(gzipFilter.getAction(any())).thenReturn(DO_NOT_COMPRESS); final FilterChain chain = mock(FilterChain.class); gzipFilter.doFilter(mock(HttpServletRequest.class), mock(HttpServletResponse.class), chain); verify(gzipFilter, never()).compressAndContinue(any(), any(), any()); verify(chain, times(1)).doFilter(any(), any()); } @Test public void doFilter_doNotAcceptGzip() throws IOException, ServletException { final GzipFilter gzipFilter = spy(new GzipFilter()); when(gzipFilter.getAction(any())).thenReturn(DO_NOT_ACCEPT_GZIP); final FilterChain chain = mock(FilterChain.class); gzipFilter.doFilter(mock(HttpServletRequest.class), mock(HttpServletResponse.class), chain); verify(gzipFilter, never()).compressAndContinue(any(), any(), any()); verify(chain, times(1)).doFilter(any(), any()); } @Test public void doFilter_halt() throws IOException, ServletException { final GzipFilter gzipFilter = spy(new GzipFilter()); when(gzipFilter.getAction(any())).thenReturn(HALT); final FilterChain chain = mock(FilterChain.class); gzipFilter.doFilter(mock(HttpServletRequest.class), mock(HttpServletResponse.class), chain); verify(gzipFilter, never()).compressAndContinue(any(), any(), any()); verify(chain, never()).doFilter(any(), any()); } @Test public void getAction_notHttpServletRequest() { final GzipFilter gzipFilter = new GzipFilter(); assertEquals(HALT, gzipFilter.getAction(mock(ServletRequest.class))); } @Test public void getAction_disableGzipCompressionViaSystemProperty() { final GzipFilter gzipFilter = new GzipFilter(); System.setProperty(ORG_UBERFIRE_GZIP_ENABLE, "false"); assertEquals(DO_NOT_COMPRESS, gzipFilter.getAction(mock(HttpServletRequest.class))); System.setProperty(ORG_UBERFIRE_GZIP_ENABLE, "falsy"); assertEquals(DO_NOT_COMPRESS, gzipFilter.getAction(mock(HttpServletRequest.class))); } @Test public void getAction_doNotAcceptEncodingGzip() { final GzipFilter gzipFilter = new GzipFilter(); final HttpServletRequest mock = mock(HttpServletRequest.class); assertEquals(DO_NOT_ACCEPT_GZIP, gzipFilter.getAction(mock)); when(mock.getHeader(eq(ACCEPT_ENCODING))).thenReturn("foo"); assertEquals(DO_NOT_ACCEPT_GZIP, gzipFilter.getAction(mock)); } @Test public void getAction_acceptEncodingGzip() { final GzipFilter gzipFilter = new GzipFilter(); final HttpServletRequest mock = mock(HttpServletRequest.class); when(mock.getHeader(eq(ACCEPT_ENCODING))).thenReturn(GZIP); assertEquals(COMPRESS, gzipFilter.getAction(mock)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/java/org/uberfire/util/TextUtilTest.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.util; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import junit.framework.TestCase; import org.uberfire.backend.server.util.TextUtil; public class TextUtilTest extends TestCase { private static final String BASE = "dUMmY"; String userNameIllegalChars = "ªº\\!|\"@·#$%&¬/()=?'¿¡€^`[*+]¨´{}<>,;:_~ .-"; String repoNameIllegalChars = "ªº\\!|\"@·#$%&¬/()=?'¿¡€^`[*+]¨´{}<>,;:_~ "; // key: illegal char, value: expected char after normalization Map additionalIllegal = new HashMap(); private StringBuilder sb = new StringBuilder(BASE); @Override protected void setUp() throws Exception { additionalIllegal.put('ñ', 'n'); additionalIllegal.put('Ñ', 'N'); additionalIllegal.put('ç', 'c'); additionalIllegal.put('Ç', 'C'); additionalIllegal.put('á', 'a'); additionalIllegal.put('à', 'a'); additionalIllegal.put('ä', 'a'); additionalIllegal.put('Á', 'A'); additionalIllegal.put('À', 'A'); additionalIllegal.put('Ä', 'A'); } public void testNormalizeUserName() { for (int i = 0; i < userNameIllegalChars.length(); i++) { int index = 0; assertEquals(BASE, TextUtil.normalizeUserName(sb.insert(index, userNameIllegalChars.charAt(i)).toString())); sb.deleteCharAt(index); index = BASE.length() - 3; assertEquals(BASE, TextUtil.normalizeUserName(sb.insert(index, userNameIllegalChars.charAt(i)).toString())); sb.deleteCharAt(index); index = BASE.length() - 1; assertEquals(BASE, TextUtil.normalizeUserName(sb.insert(index, userNameIllegalChars.charAt(i)).toString())); sb.deleteCharAt(index); } StringBuilder expected = new StringBuilder(BASE); for (Iterator> it = additionalIllegal.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = it.next(); int index = 0; assertEquals(expected.insert(index, entry.getValue()).toString(), TextUtil.normalizeUserName(sb.insert(index, entry.getKey()).toString())); sb.deleteCharAt(index); expected.deleteCharAt(index); index = BASE.length() - 3; assertEquals(expected.insert(index, entry.getValue()).toString(), TextUtil.normalizeUserName(sb.insert(index, entry.getKey()).toString())); sb.deleteCharAt(index); expected.deleteCharAt(index); index = BASE.length() - 1; assertEquals(expected.insert(index, entry.getValue()).toString(), TextUtil.normalizeUserName(sb.insert(index, entry.getKey()).toString())); sb.deleteCharAt(index); expected.deleteCharAt(index); } } public void testNormalizeRepositoryName() { for (int i = 0; i < repoNameIllegalChars.length(); i++) { int index = 0; assertEquals(BASE, TextUtil.normalizeRepositoryName(sb.insert(index, repoNameIllegalChars.charAt(i)).toString())); sb.deleteCharAt(index); index = BASE.length() - 3; assertEquals(BASE, TextUtil.normalizeRepositoryName(sb.insert(index, repoNameIllegalChars.charAt(i)).toString())); sb.deleteCharAt(index); index = BASE.length() - 1; assertEquals(BASE, TextUtil.normalizeRepositoryName(sb.insert(index, repoNameIllegalChars.charAt(i)).toString())); sb.deleteCharAt(index); } StringBuilder expected = new StringBuilder(BASE); for (Iterator> it = additionalIllegal.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = it.next(); int index = 0; assertEquals(expected.insert(index, entry.getValue()).toString(), TextUtil.normalizeRepositoryName(sb.insert(index, entry.getKey()).toString())); sb.deleteCharAt(index); expected.deleteCharAt(index); index = BASE.length() - 3; assertEquals(expected.insert(index, entry.getValue()).toString(), TextUtil.normalizeRepositoryName(sb.insert(index, entry.getKey()).toString())); sb.deleteCharAt(index); expected.deleteCharAt(index); index = BASE.length() - 1; assertEquals(expected.insert(index, entry.getValue()).toString(), TextUtil.normalizeRepositoryName(sb.insert(index, entry.getKey()).toString())); sb.deleteCharAt(index); expected.deleteCharAt(index); } String strInput = ""; String strExpected = ""; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "_{`"; strExpected = ""; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "."; strExpected = ""; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "-"; strExpected = ""; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "..."; strExpected = ""; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "---"; strExpected = ""; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "..d."; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = ".d.."; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "--d-"; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "-d--"; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "..d.."; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = ".-d.."; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = ".d-.."; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "--d--."; strExpected = "d"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d---f"; strExpected = "df"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d...f"; strExpected = "df"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d----f"; strExpected = "df"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d-f"; strExpected = "d-f"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d.f"; strExpected = "d.f"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d.-f"; strExpected = "df"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d.-.f"; strExpected = "df"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d-.-f"; strExpected = "df"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d-.f"; strExpected = "df"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "d..-.-B'.--..+-_--ç-..f"; strExpected = "dBcf"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "m\"y-t@ës#t'.re{p'o-n:a;m,e"; strExpected = "my-test.repo-name"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = "-m\"y-t@ës#t'.re{p'o-n:a;m,e-"; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); strInput = ".m\"y-t@ës#t'.re{p'o-n:a;m,e."; assertEquals(strExpected, TextUtil.normalizeRepositoryName(strInput)); } } ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/META-INF/services/org.uberfire.java.nio.file.spi.FileSystemProvider ================================================ # # Copyright 2015 Red Hat, Inc. and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # org.uberfire.backend.server.security.MockSecuredFilesystemProvider org.uberfire.java.nio.fs.file.SimpleFileSystemProvider org.uberfire.java.nio.fs.jgit.JGitFileSystemProvider ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/invalid/security-policy.properties ================================================ # Invalid entries role role.= role..home= .home= ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/security-policy.properties ================================================ # A self contained security policy # # Default default.home=Home default.permission.perspective.read=false # Role "admin" role.admin.description=Administrator role.admin.home=Home role.admin.priority=1 role.admin.permission.perspective.read=true role.admin.permission.perspective.read.SimplePerspective=false role.admin.permission.filesystem.system.master.*=true # Role "user" role.user.description=End user role.user.home=Home role.user.priority=2 role.user.permission.perspective.read=false role.user.permission.perspective.read.HomePerspective=true role.user.permission.perspective.read.SimplePerspective=true role.user.permission.filesystem.system.master.*=false # Role "manager" role.manager.description=Manager role.manager.home=Home role.manager.priority=3 role.manager.permission.perspective.read.*=true role.manager.permission.filesystem.system.master.*=false role.manager.permission.repository.read.git://repo1=true # Group "group1" group.group1.description=group1desc group.group1.home=Home group.group1.priority=3 group.group1.permission.perspective.read.*=true ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/split/security-module-filesystem.properties ================================================ role.admin.permission.filesystem.system.master.*=true role.manager.permission.filesystem.system.master.*=false role.user.permission.filesystem.system.master.*=false ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/split/security-module-homes.properties ================================================ role.admin.home=Home role.user.home=Home role.manager.home=Home ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/split/security-module-perspective.properties ================================================ role.admin.permission.perspective.read=true role.admin.permission.perspective.read.SimplePerspective=false role.user.permission.perspective.read=false role.user.permission.perspective.read.HomePerspective=true role.user.permission.perspective.read.SimplePerspective=true role.manager.permission.perspective.read.*=true role.manager.permission.repository.read.git://repo1=true ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/split/security-module-priorities.properties ================================================ role.admin.priority=1 role.user.priority=2 role.manager.priority=3 ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/split/security-module-roles.properties ================================================ role.admin.description=Administrator role.user.description=End user role.manager.description=Manager ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/classes/split/security-policy.properties ================================================ # Security policy marker file. # # All the files starting with the "security-module" prefix will be loaded and # included as part of the global authorization policy. # default.home=Home default.permission.perspective.read=false ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/WEB-INF/web.xml ================================================ Role 1 role1 Role 2 role2 Empty ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/plugins/plugin.txt ================================================ //do not delete. needed for testing. ================================================ FILE: uberfire-backend/uberfire-backend-server/src/test/resources/test-app/test-app.nocache.js ================================================ // do not delete. needed for testing. ================================================ FILE: uberfire-client-api/.gitignore ================================================ /target /local # Eclipse, Netbeans and IntelliJ files /.* /**/.* !.gitignore /nbproject /*.ipr /*.iws /*.iml # Repository wide ignore mac DS_Store files .DS_Store ================================================ FILE: uberfire-client-api/pom.xml ================================================ 4.0.0 org.uberfire uberfire-parent 7.75.0-SNAPSHOT ../pom.xml uberfire-client-api jar UberFire Client API UberFire Client API org.uberfire uberfire-api jakarta.inject jakarta.inject-api provided org.jboss.errai errai-common org.jboss.errai errai-bus org.jboss.errai errai-ioc org.kie.soup kie-soup-commons com.google.elemental2 elemental2-dom com.google.elemental2 elemental2-promise com.google.jsinterop jsinterop-annotations com.google.gwt gwt-user provided org.apache.maven.plugins maven-dependency-plugin unpack-bluebird process-resources unpack org.webjars.bower bluebird ${version.org.webjars.bower.bluebird} jar true ${project.build.directory}/bluebird false true org.apache.maven.plugins maven-resources-plugin copy-bluebird-resources process-resources copy-resources ${project.build.outputDirectory}/org/uberfire/client/views/static/bluebird ${project.build.directory}/bluebird/META-INF/resources/webjars/bluebird/${version.org.webjars.bower.bluebird}/js/browser bluebird.min.js ================================================ FILE: uberfire-client-api/src/main/java/org/uberfire/client/annotations/DefaultPosition.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.client.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Default position for WorkbenchParts added to the Workbench. Methods marked with this annotation should take zero * arguments and return a {@code Position} indicating the WorkbenchPart's default position. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface DefaultPosition { } ================================================ FILE: uberfire-client-api/src/main/java/org/uberfire/client/annotations/Intercept.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.client.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Intercept { } ================================================ FILE: uberfire-client-api/src/main/java/org/uberfire/client/annotations/Perspective.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.client.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Methods annotated with this provide a PerspectiveDefinition. The method should have zero arguments and return a * {@code org.uberfire.client.workbench.model.PerspectiveDefinition}. *

        * This annotation should only be used in classes annotated with {@link WorkbenchPerspective}, and it cannot be used in * a class that has fields annotated with {@link WorkbenchPanel}. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Perspective { } ================================================ FILE: uberfire-client-api/src/main/java/org/uberfire/client/annotations/SplashBodyHeight.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.client.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface SplashBodyHeight { } ================================================ FILE: uberfire-client-api/src/main/java/org/uberfire/client/annotations/SplashFilter.java ================================================ /* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.client.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Methods annotated with this provide a PerspectiveDefinition. The method * should have zero arguments and return a * {@code org.uberfire.client.workbench.model.PerspectiveDefinition}. */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface SplashFilter { } ================================================ FILE: uberfire-client-api/src/main/java/org/uberfire/client/annotations/WorkbenchClientEditor.java ================================================ /* * Copyright 2019 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.client.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * This annotation works like {@code @WorkbenchEditor}, and should be used for client side only editors. * * Classes annotated with this are considered WorkbenchParts that perform some * "editor" function for the specified file-type. *

        * At its simplest form the Class should implement * {@code com.google.gwt.user.client.ui.IsWidget} (e.g. extend * {@code com.google.gwt.user.client.ui.Composite}) and provide a method * annotated with {@code @WorkbenchPartTitle}. *

        *

        * Developers wishing to separate view from logic (perhaps by implementing the * MVP pattern) can further provide a zero-argument method annotated with * {@code @WorkbenchPartView} with return type * {@code com.google.gwt.user.client.ui.IsWidget}. *

        *

        * In this latter case the {@code @WorkbenchEditor} need not implement * {@code com.google.gwt.user.client.ui.IsWidget}. *

        *

        * WorkbechEditors can receive the following life-cycle calls: *